/opt/canhelp/apps/web/.next/cache/webpack/server-production
Edit: /opt/canhelp/apps/web/.next/cache/webpack/server-production/21.pack (6011538B)
wpc [ webpack/lib/cache/PackFileCacheStrategyPackContentItems`& Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!/opt/canhelp/apps/web/src/app/tasks/page.tsx|rsc Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!/opt/canhelp/apps/web/src/app/robots.ts|rsc Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!/opt/canhelp/apps/web/src/app/sitemap.ts|rsc Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!/opt/canhelp/apps/web/src/lib/api.ts|rsc$ Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/chat/page.tsx|ssr' Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/profile/page.tsx|ssr( Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/schedule/page.tsx|ssr0 Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/specialist-setup/page.tsx|ssr) Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/tasks/new/page.tsx|ssr% Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/context/locale.tsx|ssr Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/lib/api.ts|ssr/ Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/tasks/TaskListClient.tsx|ssr( Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/components/Footer.tsx|ssr Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/lib/auth.ts|ssr+ Compilation/modules|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/components/Turnstile.tsx|ssr4 Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!/opt/canhelp/apps/web/src/app/tasks/page.tsx|rsc|webpack-runtime, Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!/opt/canhelp/apps/web/src/lib/api.ts|rsc|webpack-runtime; Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/chat/page.tsx|ssr|webpack-runtime> Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/profile/page.tsx|ssr|webpack-runtime? Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/schedule/page.tsx|ssr|webpack-runtimeG Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/specialist-setup/page.tsx|ssr|webpack-runtime@ Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/tasks/new/page.tsx|ssr|webpack-runtime< Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/context/locale.tsx|ssr|webpack-runtime4 Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/lib/api.ts|ssr|webpack-runtimeF Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/app/tasks/TaskListClient.tsx|ssr|webpack-runtime5 Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/lib/auth.ts|ssr|webpack-runtime Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-app-loader/index.js?page=%2Frobots.txt%2Froute&name=app%2Frobots.txt%2Froute&pagePath=private-next-app-dir%2Frobots.ts&appDir=%2Fopt%2Fcanhelp%2Fapps%2Fweb%2Fsrc%2Fapp&appPaths=%2Frobots&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D&isGlobalNotFoundEnabled=!|rsc|7a7f45020dcf5f1c|webpack-runtime Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-app-loader/index.js?page=%2Fsitemap.xml%2Froute&name=app%2Fsitemap.xml%2Froute&pagePath=private-next-app-dir%2Fsitemap.ts&appDir=%2Fopt%2Fcanhelp%2Fapps%2Fweb%2Fsrc%2Fapp&appPaths=%2Fsitemap&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D&isGlobalNotFoundEnabled=!|rsc|049d8527ae16ef50|webpack-runtimeP Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/components/Footer.tsx|ssr|f8575f579785db27|webpack-runtimeS Compilation/codeGeneration|javascript/auto|/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[16].oneOf[7].use[1]!/opt/canhelp/apps/web/src/components/Turnstile.tsx|ssr|49d9f9ab1791da38|webpack-runtimeCompilation/assets|chunk784Compilation/assets|chunk475Compilation/assets|chunk892Compilation/assets|chunk902MinifierWebpackPlugin|../app/robots.txt/route.jsMinifierWebpackPlugin|../app/sitemap.xml/route.jsMinifierWebpackPlugin|892.jsMinifierWebpackPlugin|902.jswebpack/lib/NormalModulewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSource" import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import Link from 'next/link';
import { cookies } from 'next/headers';
import { getCategories, getLocations, getTaskBudgetRange } from '@/lib/api';
import { getTranslations } from '@/lib/translations';
import { TaskListClient } from './TaskListClient';
import { TaskFiltersClient } from './TaskFiltersClient';
import { TasksAuthGuard } from './TasksAuthGuard';
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000';
export default async function TasksPage({ searchParams }) {
const params = await searchParams;
const page = Number(params.page || 1);
const mode = params.mode === 'all' ? 'all' : 'for_me';
const cookieStore = await cookies();
const locale = cookieStore.get('canhelp_locale')?.value ?? 'el';
const cookieLocation = decodeURIComponent(cookieStore.get('canhelp_location')?.value ?? '');
const t = getTranslations(locale);
const catLocale = locale === 'en' ? 'en' : locale === 'ru' ? 'ru' : 'el';
const cookieHeader = cookieStore.getAll().map((c)=>`${c.name}=${c.value}`).join('; ');
let tasks = [];
let total = 0;
let noCards = false;
let categories = [];
let locationTree = [];
let budgetRange = {
min: 0,
max: 0
};
const effectiveLocation = params.location ?? cookieLocation;
const { q, category } = params;
const rangeParams = {};
if (q) rangeParams.q = q;
if (category) rangeParams.category = category;
if (effectiveLocation) rangeParams.location = effectiveLocation;
const effectiveParams = {
page: String(page),
limit: '10',
...params,
...effectiveLocation ? {
location: effectiveLocation
} : {}
};
delete effectiveParams.mode;
try {
;
[categories, locationTree, budgetRange] = await Promise.all([
getCategories(),
getLocations(),
getTaskBudgetRange(Object.keys(rangeParams).length ? rangeParams : undefined)
]);
} catch {}
try {
if (mode === 'for_me') {
const forMeParams = new URLSearchParams(effectiveParams);
const res = await fetch(`${API_BASE}/api/tasks/for-me?${forMeParams}`, {
headers: {
Cookie: cookieHeader
},
cache: 'no-store'
});
if (res.ok) {
const json = await res.json();
if (json.noCards) {
noCards = true;
} else {
tasks = json.data ?? [];
total = json.total ?? 0;
}
}
} else {
const allParams = new URLSearchParams(effectiveParams);
const res = await fetch(`${API_BASE}/api/tasks?${allParams}`, {
headers: {
Cookie: cookieHeader
},
cache: 'no-store'
});
if (res.ok) {
const json = await res.json();
tasks = json.data ?? [];
total = json.total ?? 0;
}
}
} catch {}
const catMap = {};
for (const cat of categories){
catMap[cat.slug] = cat.names[catLocale] ?? cat.names.el;
for (const sub of cat.children ?? []){
catMap[sub.slug] = sub.names[catLocale] ?? sub.names.el;
}
}
const locMap = {};
for (const city of locationTree){
locMap[city.slug] = city.names[catLocale] ?? city.names.el;
for (const d of city.children ?? []){
locMap[d.slug] = d.names[catLocale] ?? d.names.el;
}
}
const hasFilter = !!(params.q || params.category || params.location || params.budgetMin || params.budgetMax);
const filterParams = {};
if (params.q) filterParams.q = params.q;
if (params.category) filterParams.category = params.category;
if (params.location) filterParams.location = params.location;
if (params.budgetMin) filterParams.budgetMin = params.budgetMin;
if (params.budgetMax) filterParams.budgetMax = params.budgetMax;
return /*#__PURE__*/ _jsxs("div", {
className: "max-w-7xl mx-auto px-4 py-8",
children: [
/*#__PURE__*/ _jsx(TasksAuthGuard, {}),
/*#__PURE__*/ _jsxs("div", {
className: "flex flex-col md:flex-row gap-8",
children: [
/*#__PURE__*/ _jsx("aside", {
className: "md:w-64 shrink-0",
children: /*#__PURE__*/ _jsxs("div", {
className: "bg-white rounded-xl border border-gray-200 p-5 sticky top-24",
children: [
/*#__PURE__*/ _jsx("h3", {
className: "font-semibold text-gray-900 mb-4",
children: t('tasks.filters')
}),
/*#__PURE__*/ _jsx(TaskFiltersClient, {
categories: categories,
locationTree: locationTree,
budgetRange: budgetRange,
initialMode: mode,
initialQ: params.q,
initialCategory: params.category,
initialLocation: params.location,
initialBudgetMin: params.budgetMin,
initialBudgetMax: params.budgetMax
})
]
})
}),
/*#__PURE__*/ _jsxs("div", {
className: "flex-1",
children: [
/*#__PURE__*/ _jsx("div", {
className: "mb-6",
children: /*#__PURE__*/ _jsx("h1", {
className: "text-xl font-bold text-white",
children: hasFilter ? /*#__PURE__*/ _jsxs(_Fragment, {
children: [
total,
" ",
t('tasks.title')
]
}) : t('nav.tasks')
})
}),
noCards ? /*#__PURE__*/ _jsxs("div", {
className: "bg-white/15 border border-white/30 rounded-xl p-8 text-center",
children: [
/*#__PURE__*/ _jsx("div", {
className: "text-4xl mb-3",
children: "\uD83D\uDDC2️"
}),
/*#__PURE__*/ _jsx("p", {
className: "text-white font-medium mb-2",
children: t('find_tasks.no_cards')
}),
/*#__PURE__*/ _jsx(Link, {
href: "/profile",
className: "inline-block mt-2 px-5 py-2 bg-white text-blue-600 rounded-lg text-sm font-medium hover:bg-blue-50 transition",
children: t('find_tasks.add_card')
})
]
}) : /*#__PURE__*/ _jsx(TaskListClient, {
initialTasks: tasks,
initialTotal: total,
filterParams: filterParams,
locale: locale,
catMap: catMap,
locMap: locMap,
mode: mode
}, [
mode,
params.q,
params.category,
params.location,
params.budgetMin,
params.budgetMax,
page
].join('|'))
]
})
]
})
]
});
}
exportsTypesideEffectFreenamespace
javascript/autorsc/opt/canhelp/apps/web/src/app/tasksaliasmainFieldsconditionNames`$server-only$client-only$next/dist/compiled/server-only$next/dist/compiled/client-only$/opt/canhelp/node_modules/next/head.js/opt/canhelp/node_modules/next/image.js/opt/canhelp/node_modules/next/constants.js/opt/canhelp/node_modules/next/router.js/opt/canhelp/node_modules/next/dynamic.js/opt/canhelp/node_modules/next/script.js/opt/canhelp/node_modules/next/link.js/opt/canhelp/node_modules/next/form.js/opt/canhelp/node_modules/next/navigation.js/opt/canhelp/node_modules/next/headers.js/opt/canhelp/node_modules/next/og.js/opt/canhelp/node_modules/next/server.js/opt/canhelp/node_modules/next/document.js/opt/canhelp/node_modules/next/app.jsreact$react/compiler-runtime$react/jsx-dev-runtime$react/jsx-runtime$react-dom$react-dom/client$react-dom/server$react-dom/server.browser$react-dom/server.edge$react-dom/static$react-dom/static.browser$react-dom/static.edge$react-server-dom-webpack/client$react-server-dom-webpack/server$react-server-dom-webpack/server.node$react-server-dom-webpack/static$@vercel/turbopack-ecmascript-runtime/browser/dev/hmr-client/hmr-client.tsnextnext/dist/compiled/server-only/emptynext/dist/compiled/client-only/errornext/dist/client/components/noop-headnext/dist/api/imagenext/dist/api/constantsnext/dist/api/routernext/dist/api/app-dynamicnext/dist/api/scriptnext/dist/client/app-dir/linknext/dist/client/app-dir/formnext/dist/api/navigation.react-servernext/dist/api/headersnext/dist/api/ognext/dist/api/servernext/dist/api/documentnext/dist/api/appnext/dist/server/route-modules/app-page/vendored/rsc/reactnext/dist/server/route-modules/app-page/vendored/rsc/react-compiler-runtimenext/dist/server/route-modules/app-page/vendored/rsc/react-jsx-dev-runtimenext/dist/server/route-modules/app-page/vendored/rsc/react-jsx-runtimenext/dist/server/route-modules/app-page/vendored/rsc/react-domnext/dist/compiled/react-dom/clientnext/dist/compiled/react-dom/server.nodenext/dist/compiled/react-dom/server.browsernext/dist/build/webpack/alias/react-dom-server.jsnext/dist/compiled/react-dom/static.nodenext/dist/compiled/react-dom/static.browsernext/dist/compiled/react-dom/static.edgenext/dist/compiled/react-server-dom-webpack/client.nodenext/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-servernext/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-staticnext/dist/client/dev/noop-turbopack-hmr/opt/canhelp/node_modules/nextmodulemainreact-server...`cacheableparsedfileDependenciescontextDependenciesmissingDependenciesbuildDependenciesvalueDependencieshashassetsassetsInfostrictexportsArgumenttopLevelDeclarationssnapshotwebpack/lib/util/LazySet/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js/opt/canhelp/node_modules/next/dist/build/webpack/loaders/next-swc-loader.jswebpack/DefinePlugin_hashwebpack/DefinePlugin process.env.NEXT_PUBLIC_API_URL4028310f"https://api.canhelp.gr"8fc3b9783ac2759etypeactionIdsclientRefsclientEntryTypeisClientRefserver
__webpack_exports__API_BASE*default*TasksPagewebpack/lib/FileSystemInfoSnapshot EyB/opt/canhelp/apps/web/src/app/tasks/page.tsxsafeTimetimestamp! `fyB PfyBe9e3359bb88edae5`webpack/lib/dependencies/HarmonyCompatibilityDependency
d webpack/lib/dependencies/ConstDependency `V
`VaWt
``u@
`'A
`LA
`5A R
`2AS
`8A
`2A
b 00A
b Kwebpack/lib/dependencies/HarmonyExportHeaderDependencyA " A "
@ `$webpack/lib/dependencies/HarmonyImportSideEffectDependencyreact/jsx-runtime
`Vnext/link
`next/headers
`'@/lib/api
`L@/lib/translations
`5./TaskListClient
`2./TaskFiltersClient
`8./TasksAuthGuard
`2webpack/lib/dependencies/PureExpressionDependency A
default
`Kwebpack/lib/dependencies/HarmonyExportSpecifierDependency`
@ webpack/lib/dependencies/HarmonyImportSpecifierDependencyacookiesA
c%getTranslationsA
cgetCategoriesA
c//getLocationsA
c00getTaskBudgetRangeA
c11jsxs_jsxsAh m
cjjjsx_jsxA
cmmTasksAuthGuardA 4
cmm-A
cnnA
cq"q&A
cs0s5A
cv.v2A
cz.z2TaskFiltersClientA 4
cz3zDA
@ `"@ `'AJ N
@ `*@ `.A
@ `8@ `<Ag l
@ `H@ `MFragment_FragmentAm v 4
@ `N@ `WA( -
@ `4@ `9A
@ `2@ `6A
@ `2@ `6A
@ `2@ `6LinkA 4
@ `7@ `;A yy
@ `/@ `3TaskListClientA 4~~
@ `4@ `B
const APP_URL = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000';
export default function robots() {
return {
rules: {
userAgent: '*',
allow: '/',
disallow: [
'/admin/',
'/dashboard/',
'/profile/',
'/chat/',
'/notifications/',
'/favorites/',
'/schedule/',
'/payment/'
]
},
sitemap: `${APP_URL}/sitemap.xml`
};
}
`
/opt/canhelp/apps/web/src/app"1
234webpack/DefinePlugin process.env.NEXT_PUBLIC_APP_URL5"http://canhelp.gr"e21eb76bb0be822f;<
= APP_URL>robots EyB/opt/canhelp/apps/web/src/app/robots.tsA! @v)yB 0v)yB98480c3cfda03512
d a/
b/0a3J
bJ`[@ `L@
aaJ b
`J`
a
const APP_URL = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000';
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000';
const STATIC_ROUTES = [
{
url: `${APP_URL}/`,
changeFrequency: 'daily',
priority: 1.0
},
{
url: `${APP_URL}/tasks`,
changeFrequency: 'hourly',
priority: 0.9
},
{
url: `${APP_URL}/specialists`,
changeFrequency: 'hourly',
priority: 0.9
},
{
url: `${APP_URL}/pricing`,
changeFrequency: 'weekly',
priority: 0.6
},
{
url: `${APP_URL}/become-specialist`,
changeFrequency: 'monthly',
priority: 0.7
}
];
async function fetchAllTasks() {
const entries = [];
let page = 1;
const limit = 100;
try {
while(true){
const res = await fetch(`${API_URL}/api/tasks?page=${page}&limit=${limit}&status=open`, {
next: {
revalidate: 3600
}
});
if (!res.ok) break;
const json = await res.json();
const tasks = json.data ?? [];
for (const { task } of tasks){
entries.push({
url: `${APP_URL}/tasks/${task.id}`,
lastModified: task.updatedAt ? new Date(task.updatedAt) : undefined,
changeFrequency: 'daily',
priority: 0.8
});
}
if (entries.length >= json.total || tasks.length < limit) break;
page++;
}
} catch {
// silently skip if API is unavailable during build
}
return entries;
}
async function fetchAllSpecialists() {
const entries = [];
let page = 1;
const limit = 100;
try {
while(true){
const res = await fetch(`${API_URL}/api/users/specialists?page=${page}&limit=${limit}`, {
next: {
revalidate: 3600
}
});
if (!res.ok) break;
const json = await res.json();
const specialists = json.data ?? [];
for (const specialist of specialists){
entries.push({
url: `${APP_URL}/users/${specialist.id}`,
lastModified: specialist.updatedAt ? new Date(specialist.updatedAt) : undefined,
changeFrequency: 'weekly',
priority: 0.75
});
}
if (entries.length >= json.total || specialists.length < limit) break;
page++;
}
} catch {
// silently skip if API is unavailable during build
}
return entries;
}
export default async function sitemap() {
const [tasks, specialists] = await Promise.all([
fetchAllTasks(),
fetchAllSpecialists()
]);
return [
...STATIC_ROUTES,
...tasks,
...specialists
];
}
`
1833543e201be90f
fetchAllTasksfetchAllSpecialists܇API_URLSTATIC_ROUTESsitemap EyB/opt/canhelp/apps/web/src/app/sitemap.ts! @yB 0yBf44001f3979d6782
d a/
b/0a3J
bJa\{
b/0`@
bJA
A
cZ d`\@ 9
`J7
cZ d
fQ // SSR: use INTERNAL_API_URL (http://localhost:4000) to avoid external DNS/SSL round-trip
// Browser: use NEXT_PUBLIC_API_URL (https://api.canhelp.gr)
const BASE = "undefined" === 'undefined' ? process.env.INTERNAL_API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000' : process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000';
export async function request(path, init) {
const url = `${BASE}/api${path}`;
if ("undefined" === 'undefined') console.log('[api] SSR fetch', url);
const res = await fetch(url, {
...init,
credentials: 'include',
headers: {
'Content-Type': 'application/json',
...init?.headers
}
});
if (!res.ok) {
const err = await res.json().catch(()=>({
error: res.statusText
}));
const msg = typeof err.error === 'string' ? err.error : typeof err.message === 'string' ? err.message : res.statusText || 'Request failed';
throw new Error(msg);
}
return res.json();
}
// ─── Tasks ────────────────────────────────────────────────────────────────
export const getTasks = (params)=>{
const qs = params ? '?' + new URLSearchParams(params) : '';
return request(`/tasks${qs}`);
};
export const getTaskBudgetRange = (params)=>{
const qs = params ? '?' + new URLSearchParams(params) : '';
return request(`/tasks/budget-range${qs}`);
};
export const searchTasks = (params)=>request(`/tasks/search?${new URLSearchParams(params)}`);
export const getMyTasks = ()=>request('/tasks/my');
export const getTasksForSpecialist = (params)=>{
const qs = params ? '?' + new URLSearchParams(params) : '';
return request(`/tasks/for-me${qs}`);
};
export const getTaskCountsByCategory = ()=>request('/tasks/counts-by-category');
export const getTask = (id)=>request(`/tasks/${id}`);
export const createTask = (data)=>request('/tasks', {
method: 'POST',
body: JSON.stringify(data)
});
export const updateTask = (id, data)=>request(`/tasks/${id}`, {
method: 'PATCH',
body: JSON.stringify(data)
});
export const completeTask = (id)=>request(`/tasks/${id}/complete`, {
method: 'PATCH'
});
export const cancelTask = (id)=>request(`/tasks/${id}/cancel`, {
method: 'PATCH'
});
// ─── Offers ────────────────────────────────────────────────────────────────
export const getOffers = (taskId)=>request(`/offers?taskId=${taskId}`);
export const getMyOffers = ()=>request('/offers/my');
export const createOffer = (data)=>request('/offers', {
method: 'POST',
body: JSON.stringify(data)
});
export const acceptOffer = (id)=>request(`/offers/${id}/accept`, {
method: 'PATCH'
});
export const declineOffer = (id)=>request(`/offers/${id}/decline`, {
method: 'PATCH'
});
export const getUserProfile = (id)=>request(`/users/${id}/profile`);
export const getSpecialists = (params)=>{
const qs = params ? '?' + new URLSearchParams(params) : '';
return request(`/users/specialists${qs}`);
};
export const createReview = (data)=>request('/reviews', {
method: 'POST',
body: JSON.stringify(data)
});
export const getTaskReviews = (taskId)=>request(`/reviews/task/${taskId}`);
export const getMyReviews = ()=>request('/reviews/my');
// ─── Chat ──────────────────────────────────────────────────────────────────
export const getChatRooms = ()=>request('/chat/rooms');
export const getOrCreateDirectRoom = (userId)=>request(`/chat/direct/${userId}`);
export const getCanMessage = (userId)=>request(`/chat/can-message/${userId}`);
export const getMessages = (roomId)=>request(`/chat/rooms/${roomId}/messages`);
export const sendMessage = (roomId, body)=>request('/chat/messages', {
method: 'POST',
body: JSON.stringify({
roomId,
body
})
});
// ─── Notifications ────────────────────────────────────────────────────────
export const updateNotifSettings = (data)=>request('/users/me', {
method: 'PATCH',
body: JSON.stringify(data)
});
export const getNotifications = ()=>request('/notifications');
export const getUnreadCount = ()=>request('/notifications/count');
export const markRead = (id)=>request(`/notifications/${id}/read`, {
method: 'PATCH'
});
export const markAllRead = ()=>request('/notifications/read-all', {
method: 'PATCH'
});
export const getTaskInvite = (taskId)=>request(`/notifications?type=task_invite&referenceId=${taskId}`);
export const dismissNotification = (id)=>request(`/notifications/${id}`, {
method: 'DELETE'
});
// ─── Referral ─────────────────────────────────────────────────────────────
export const getMyReferralInfo = ()=>request('/users/me/referral');
// ─── Reviews ──────────────────────────────────────────────────────────────
export const getUserReviews = (userId)=>request(`/reviews/user/${userId}`);
export const getUserRating = (userId)=>request(`/reviews/user/${userId}/rating`);
// ─── Categories ───────────────────────────────────────────────────────────
export const getCategories = ()=>request('/categories');
// ─── Locations ────────────────────────────────────────────────────────────
export const getLocations = ()=>request('/locations');
// ─── Favorites ────────────────────────────────────────────────────────────
export const getFavorites = ()=>request('/favorites');
export const addFavorite = (taskId)=>request(`/favorites/${taskId}`, {
method: 'POST'
});
export const removeFavorite = (taskId)=>request(`/favorites/${taskId}`, {
method: 'DELETE'
});
export const getSpecialistFavorites = ()=>request('/favorites/specialists');
export const addSpecialistFavorite = (specialistId)=>request(`/favorites/specialists/${specialistId}`, {
method: 'POST'
});
export const removeSpecialistFavorite = (specialistId)=>request(`/favorites/specialists/${specialistId}`, {
method: 'DELETE'
});
// ─── Admin ─────────────────────────────────────────────────────────────────
// ─── Admin Categories ──────────────────────────────────────────────────────
export const getAdminCategories = ()=>request('/admin/categories');
export const createCategory = (data)=>request('/admin/categories', {
method: 'POST',
body: JSON.stringify(data)
});
export const updateCategory = (id, data)=>request(`/admin/categories/${id}`, {
method: 'PATCH',
body: JSON.stringify(data)
});
export const deleteCategory = (id)=>request(`/admin/categories/${id}`, {
method: 'DELETE'
});
// ─── Admin ─────────────────────────────────────────────────────────────────
export const getAdminStats = ()=>request('/admin/stats');
export const getAdminUsers = (page = 1, q, role)=>{
const p = new URLSearchParams({
page: String(page),
limit: '20'
});
if (q) p.set('q', q);
if (role) p.set('role', role);
return request(`/admin/users?${p}`);
};
export const deactivateUser = (id)=>request(`/admin/users/${id}/deactivate`, {
method: 'PATCH'
});
export const activateUser = (id)=>request(`/admin/users/${id}/activate`, {
method: 'PATCH'
});
export const changeUserRole = (id, role)=>request(`/admin/users/${id}/role`, {
method: 'PATCH',
body: JSON.stringify({
role
})
});
export const getAdminUser = (id)=>request(`/admin/users/${id}`);
export const getAdminUserSpecialistCards = (userId)=>request(`/admin/users/${userId}/specialist-cards`);
export const adminUpdateSpecialistCard = (id, data)=>request(`/admin/specialist-cards/${id}`, {
method: 'PATCH',
body: JSON.stringify(data)
});
export const updateAdminUser = (id, data)=>request(`/admin/users/${id}`, {
method: 'PATCH',
body: JSON.stringify(data)
});
export const verifyAdminUserEmail = (id)=>request(`/admin/users/${id}/verify-email`, {
method: 'PATCH'
});
export const getAdminTasks = (page = 1, q, status)=>{
const p = new URLSearchParams({
page: String(page),
limit: '20'
});
if (q) p.set('q', q);
if (status) p.set('status', status);
return request(`/admin/tasks?${p}`);
};
export const cancelTaskAdmin = (id)=>request(`/admin/tasks/${id}/cancel`, {
method: 'PATCH'
});
export const deleteTaskAdmin = (id)=>request(`/admin/tasks/${id}`, {
method: 'DELETE'
});
export const getAdminReports = (page = 1)=>request(`/admin/reports?page=${page}&limit=20`);
export const updateReportStatus = (id, status)=>request(`/admin/reports/${id}/status`, {
method: 'PATCH',
body: JSON.stringify({
status
})
});
export const getAdminAiLogs = (page = 1)=>request(`/admin/ai-logs?page=${page}&limit=50`);
export const getAdminActivityLogs = (params = {})=>{
const p = new URLSearchParams();
if (params.page) p.set('page', String(params.page));
if (params.event) p.set('event', params.event);
if (params.userId) p.set('userId', params.userId);
if (params.dateFrom) p.set('dateFrom', params.dateFrom);
if (params.dateTo) p.set('dateTo', params.dateTo);
p.set('limit', '50');
return request(`/admin/activity-logs?${p}`);
};
export const getAdminMailLogs = (params = {})=>{
const p = new URLSearchParams();
if (params.page) p.set('page', String(params.page));
if (params.event) p.set('event', params.event);
if (params.dateFrom) p.set('dateFrom', params.dateFrom);
if (params.dateTo) p.set('dateTo', params.dateTo);
p.set('limit', '50');
return request(`/admin/mail-logs?${p}`);
};
export const getAdminNotifLogs = (params = {})=>{
const p = new URLSearchParams();
if (params.page) p.set('page', String(params.page));
if (params.type) p.set('type', params.type);
if (params.dateFrom) p.set('dateFrom', params.dateFrom);
if (params.dateTo) p.set('dateTo', params.dateTo);
p.set('limit', '50');
return request(`/admin/notification-logs?${p}`);
};
export const getAdminNotifStats = ()=>request('/admin/notification-stats');
export const getAdminMailStats = ()=>request('/admin/mail-stats');
// ─── Admin Locations ───────────────────────────────────────────────────────
export const getAdminLocations = ()=>request('/admin/locations');
export const createLocation = (data)=>request('/admin/locations', {
method: 'POST',
body: JSON.stringify(data)
});
export const updateLocation = (id, data)=>request(`/admin/locations/${id}`, {
method: 'PATCH',
body: JSON.stringify(data)
});
export const deleteLocation = (id)=>request(`/admin/locations/${id}`, {
method: 'DELETE'
});
// ─── Admin Plans ───────────────────────────────────────────────────────────
export const getAdminPlans = ()=>request('/admin/plans');
export const createPlan = (data)=>request('/admin/plans', {
method: 'POST',
body: JSON.stringify(data)
});
export const updatePlan = (id, data)=>request(`/admin/plans/${id}`, {
method: 'PATCH',
body: JSON.stringify(data)
});
export const deletePlan = (id)=>request(`/admin/plans/${id}`, {
method: 'DELETE'
});
// ─── Admin Settings ────────────────────────────────────────────────────────
export const getAdminSettings = ()=>request('/admin/settings');
export const updateAdminSettings = (data)=>request('/admin/settings', {
method: 'PUT',
body: JSON.stringify(data)
});
export const getAdminEmailTemplates = ()=>request('/admin/settings/templates');
export const updateAdminEmailTemplate = (key, data)=>request(`/admin/settings/templates/${key}`, {
method: 'PUT',
body: JSON.stringify(data)
});
export const translateAdminEmailTemplate = (data)=>request('/admin/settings/templates/translate', {
method: 'POST',
body: JSON.stringify(data)
});
export const sendTestEmail = ()=>request('/admin/settings/test-email', {
method: 'POST'
});
// ─── Availability ──────────────────────────────────────────────────────────
export const getMyAvailability = (month)=>request(`/availability/my${month ? `?month=${month}` : ''}`);
export const setAvailability = (date, status, note)=>request('/availability/set', {
method: 'POST',
body: JSON.stringify({
date,
status,
note
})
});
export const setAvailabilityRange = (from, to, status)=>request('/availability/set-range', {
method: 'POST',
body: JSON.stringify({
from,
to,
status
})
});
export const getSpecialistAvailability = (userId, month)=>request(`/availability/user/${userId}${month ? `?month=${month}` : ''}`);
export const getMyPortfolio = ()=>request('/portfolio/my');
export const addPortfolioItem = (formData)=>fetch(`${BASE}/api/portfolio`, {
method: 'POST',
credentials: 'include',
body: formData
}).then(async (res)=>{
if (!res.ok) {
const err = await res.json().catch(()=>({
error: res.statusText
}));
throw new Error(err.error || 'Upload failed');
}
return res.json();
});
export const updatePortfolioItem = (id, data)=>request(`/portfolio/${id}`, {
method: 'PATCH',
body: JSON.stringify(data)
});
export const deletePortfolioItem = (id)=>request(`/portfolio/${id}`, {
method: 'DELETE'
});
export const getSpecialistPortfolio = (userId)=>request(`/portfolio/user/${userId}`);
export const getMySpecialistCards = ()=>request('/specialist-cards/my');
export const createSpecialistCard = (data)=>request('/specialist-cards', {
method: 'POST',
body: JSON.stringify(data)
});
export const updateSpecialistCard = (id, data)=>request(`/specialist-cards/${id}`, {
method: 'PATCH',
body: JSON.stringify(data)
});
export const deleteSpecialistCard = (id)=>request(`/specialist-cards/${id}`, {
method: 'DELETE'
});
export const getSpecialistCards = (userId)=>request(`/specialist-cards/user/${userId}`);
export const getSkillSuggestions = (categorySlugs)=>{
const params = categorySlugs?.length ? '?' + categorySlugs.map((s)=>`category=${encodeURIComponent(s)}`).join('&') : '';
return request(`/skill-suggestions${params}`);
};
export const initiateTopUp = (amount)=>request('/payments/topup/init', {
method: 'POST',
body: JSON.stringify({
amount
})
});
export const getPaymentHistory = ()=>request('/payments/history');
export const getBalanceHistory = (limit = 50)=>request(`/payments/balance-history?limit=${limit}`);
export const getAdminBalanceHistory = (params = {})=>{
const p = new URLSearchParams();
if (params.page) p.set('page', String(params.page));
if (params.userId) p.set('userId', params.userId);
if (params.kind) p.set('kind', params.kind);
p.set('limit', '50');
return request(`/admin/balance-history?${p}`);
};
export const adminTopUpUserBalance = (id, data)=>request(`/admin/users/${id}/balance/topup`, {
method: 'POST',
body: JSON.stringify(data)
});
export const adminWithdrawUserBalance = (id, data)=>request(`/admin/users/${id}/balance/withdraw`, {
method: 'POST',
body: JSON.stringify(data)
});
export const previewPlanChange = (planId)=>request('/payments/plan/preview', {
method: 'POST',
body: JSON.stringify({
planId
})
});
export const getPlans = (role)=>{
const qs = role ? `?role=${role}` : '';
return request(`/plans${qs}`);
};
export const getMyDashboard = ()=>request('/dashboard/me');
export const getDailyUsage = ()=>request('/plans/daily-usage');
export const purchasePlan = (planId, payFromBalance = true)=>request('/payments/plan/purchase', {
method: 'POST',
body: JSON.stringify({
planId,
payFromBalance
})
});
// ─── Statuses ──────────────────────────────────────────────────────────────
export const getMyStatuses = ()=>request('/statuses/me');
export const toggleStatus = (statusType, active)=>request('/statuses/toggle', {
method: 'POST',
body: JSON.stringify({
statusType,
active
})
});
export const getAutoResponseSettings = ()=>request('/auto-response');
export const updateAutoResponseSettings = (data)=>request('/auto-response', {
method: 'PUT',
body: JSON.stringify(data)
});
// ─── FOMO ──────────────────────────────────────────────────────────────────
export const getSpecialistFomoDashboard = ()=>request('/fomo/specialist');
export const getCustomerFomoDashboard = ()=>request('/fomo/customer');
export const getFomoRecommendations = ()=>request('/fomo/recommendations');
// ─── Auto-match ────────────────────────────────────────────────────────────
export const getAutoMatchResults = (taskId)=>request(`/auto-match/${taskId}`);
export const runAutoMatch = (taskId)=>request(`/auto-match/${taskId}`, {
method: 'POST'
});
// ─── Google Calendar ───────────────────────────────────────────────────────
export const getGoogleCalendarStatus = ()=>request('/google/calendar/status');
export const disconnectGoogleCalendar = ()=>request('/google/calendar/disconnect', {
method: 'DELETE'
});
export const importFromGoogleCalendar = ()=>request('/google/calendar/import', {
method: 'POST'
});
export const getGoogleCalendarConnectUrl = ()=>`${BASE}/api/google/calendar/connect`;
// ─── Personal site ─────────────────────────────────────────────────────────
export const getPublicSiteProfile = (slug)=>request(`/users/site/${slug}`);
export const getSiteStats = ()=>request('/users/me/site-stats');
export const trackSiteMessage = (slug)=>request(`/users/site/${slug}/track-message`, {
method: 'POST'
}).catch(()=>{});
// ─── Task stats (FOMO) ─────────────────────────────────────────────────────
export const getTaskStats = (taskId)=>request(`/tasks/${taskId}/stats`);
`}
/opt/canhelp/apps/web/src/lib
0644203e50beb1bc
@ BASErequestgetTasks?searchTasksgetMyTasksgetTasksForSpecialistgetTaskCountsByCategorygetTaskcreateTaskupdateTaskcompleteTaskcancelTaskgetOffersgetMyOfferscreateOfferacceptOfferdeclineOffergetUserProfilegetSpecialistscreateReviewgetTaskReviewsgetMyReviewsgetChatRoomsgetOrCreateDirectRoomgetCanMessagegetMessagessendMessageupdateNotifSettingsgetNotificationsgetUnreadCountmarkReadmarkAllReadgetTaskInvitedismissNotificationgetMyReferralInfogetUserReviewsgetUserRatinggetFavoritesaddFavoriteremoveFavoritegetSpecialistFavoritesaddSpecialistFavoriteremoveSpecialistFavoritegetAdminCategoriescreateCategoryupdateCategorydeleteCategorygetAdminStatsgetAdminUsersdeactivateUseractivateUserchangeUserRolegetAdminUsergetAdminUserSpecialistCardsadminUpdateSpecialistCardupdateAdminUserverifyAdminUserEmailgetAdminTaskscancelTaskAdmindeleteTaskAdmingetAdminReportsupdateReportStatusgetAdminAiLogsgetAdminActivityLogsgetAdminMailLogsgetAdminNotifLogsgetAdminNotifStatsgetAdminMailStatsgetAdminLocationscreateLocationupdateLocationdeleteLocationgetAdminPlanscreatePlanupdatePlandeletePlangetAdminSettingsupdateAdminSettingsgetAdminEmailTemplatesupdateAdminEmailTemplatetranslateAdminEmailTemplatesendTestEmailgetMyAvailabilitysetAvailabilitysetAvailabilityRangegetSpecialistAvailabilitygetMyPortfolioaddPortfolioItemupdatePortfolioItemdeletePortfolioItemgetSpecialistPortfoliogetMySpecialistCardscreateSpecialistCardupdateSpecialistCarddeleteSpecialistCardgetSpecialistCardsgetSkillSuggestionsinitiateTopUpgetPaymentHistorygetBalanceHistorygetAdminBalanceHistoryadminTopUpUserBalanceadminWithdrawUserBalancepreviewPlanChangegetPlansgetMyDashboardgetDailyUsagepurchasePlangetMyStatusestoggleStatusgetAutoResponseSettingsupdateAutoResponseSettingsgetSpecialistFomoDashboardgetCustomerFomoDashboardgetFomoRecommendationsgetAutoMatchResultsrunAutoMatchgetGoogleCalendarStatusdisconnectGoogleCalendarimportFromGoogleCalendargetGoogleCalendarConnectUrlgetPublicSiteProfilegetSiteStatstrackSiteMessagegetTaskStats EyB/opt/canhelp/apps/web/src/lib/api.tsz! +TyB +TyB3d3e7ac4aaff706e@
d Ab A[
aA_ AX
c A A
c A A
c! !]A A
c" "3A A
c# &A A
c' 'PA 9 A 9
c( (5AA A:
c) ,A 6 A 6
c- 0A> A7
c1 3A A
c4 6AS AL
c8 8GA A
c9 95A D
A D
c: =AL
AE
c> @A
A
cA CA Q A
Q
cD DDAY AR
cE HA j A j
cI LAr Ak
cM MKA A
cN N7AE
u
A>
u
cP P7A}
Av
cQ QQA
A
cR RNA f A f
cS SOAn Ag
cT ZAr Ak
c\ _A / A /
c` `>A7 r A0 r
ca aBAz As
cb dA ; A ;
ce gAC A<
ch hhA A
ci kAf A_
cm mCA < A <
co oKAD A=
cp pQA A
cr r8Ak Ad
ct t6A A
cv v6A' A
cw yA A
cz |A = A =
c} }LAE A>
a~ @ A R A R
@ @ A 4 A 4
@ @ `CA< A5
@ @ A O A O
@ @ AW AP
@ @ A B A B
@ @ `9AJ ; AC ;
@ @ AC A<
@ @ A A
@ @ A A
@ @ A A
@ @ `@A j A j
@ @ `hAr Ak
@ @ A A
@ @ A A
@ @ A A
@ @ A A
@ @ A A
@ @ A C! A C!
@ @ `[AK! ! AD! !
@ @ A" U" A! U"
@ @ `ZA]" $ AV" $
@ @ A$ % A$ %
@ @ A% ' A% '
@ @ A%' i' A' i'
@ @ `KAq' ' Aj' '
@ @ `BA( =( A' =(
@ @ `AAE( ( A>( (
@ @ A( V) A( V)
@ @ A^) ) AW) )
@ @ A* H* A* H*
@ @ `9AP* * AI* *
@ @ A* Q+ A* Q+
@ @ AY+ + AR+ +
@ @ A , A, A, A,
@ @ `?AI, , AB, ,
@ @
A, - A, -
@ @ `OA#- - A- -
@ @ A- g. A- g.
@ @ Ao. . Ah. .
@ @ A&/ / A/ /
@ @ `gA/ [0 A/ [0
@ @ Ac0 71 A\0 71
@! @( A?1 1 A81 1
@) A) A1 1 A1 1
@* @* `;A1 3 A1 3
@+ @7 A3 34 A3 34
@8 @; A;4 4 A44 4
@< @> A4 4 A4 4
@? @? `UA4 :5 A4 :5
@@ @@ `HAB5 5 A;5 5
@A @D A5 a6 A5 a6
@E @H Ai6 6 Ab6 6
@I @K A6 *7 A6 *7
@L @L `XA27 8 A+7 8
@M @P A8 8 A8 8
@Q @V A8 8 A8 8
@W @W `BA9 `9 A8 `9
@X @X `cAh9 : Aa9 :
@Y @` A: O; A: O;
@a @d AW; ; AP; ;
@e @h A; <