From 0bfd43c17290a144e77a0c8203c181da01156d08 Mon Sep 17 00:00:00 2001 From: shafi54 <108669266+shafi-aviz@users.noreply.github.com> Date: Sun, 6 Sep 2026 23:05:20 +0530 Subject: [PATCH] enh --- .commandcode/taste/taste/taste.md | 1 + apps/admin-web/.cta.json | 19 + apps/admin-web/README.md | 15 + apps/admin-web/change-log.txt | 9 + apps/admin-web/package-lock.json | 6596 +++++++++++++++++ apps/admin-web/package.json | 60 + apps/admin-web/public/favicon.png | Bin 0 -> 81471 bytes apps/admin-web/public/freshyo-logo.png | Bin 0 -> 81471 bytes apps/admin-web/public/logo192.png | Bin 0 -> 48010 bytes apps/admin-web/public/logo512.png | Bin 0 -> 209072 bytes apps/admin-web/public/manifest.json | 25 + apps/admin-web/public/robots.txt | 3 + apps/admin-web/src/client.tsx | 4 + apps/admin-web/src/components/BannerForm.tsx | 225 + .../src/components/CancelOrderDialog.tsx | 85 + apps/admin-web/src/components/CouponForm.tsx | 558 ++ apps/admin-web/src/components/DateInput.tsx | 31 + .../src/components/DateTimeInput.tsx | 80 + apps/admin-web/src/components/MultiSelect.tsx | 151 + .../src/components/OrderNotesForm.tsx | 70 + .../src/components/OrderOptionsMenu.tsx | 327 + apps/admin-web/src/components/ProductForm.tsx | 659 ++ .../src/components/ProductGroupForm.tsx | 140 + .../src/components/ProductListDialog.tsx | 39 + .../src/components/ProductsSelector.tsx | 177 + .../src/components/SearchableSelect.tsx | 114 + apps/admin-web/src/components/SlotForm.tsx | 229 + apps/admin-web/src/components/SnippetMenu.tsx | 156 + .../src/components/SnippetOrdersView.tsx | 156 + apps/admin-web/src/components/StoreForm.tsx | 197 + apps/admin-web/src/components/TagForm.tsx | 345 + apps/admin-web/src/components/TagMenu.tsx | 122 + .../src/components/UserIncidentsView.tsx | 207 + .../src/components/VendorSnippetForm.tsx | 225 + .../components/context/staff-auth-context.tsx | 112 + apps/admin-web/src/hooks/useJWT.ts | 15 + .../src/hooks/useUploadToObjectStorage.ts | 105 + apps/admin-web/src/lib/event-bus.ts | 33 + apps/admin-web/src/lib/navigation-target.ts | 26 + apps/admin-web/src/lib/query-client.ts | 19 + apps/admin-web/src/lib/refresh-context.tsx | 62 + apps/admin-web/src/lib/theme.ts | 60 + apps/admin-web/src/lib/trpc-client.ts | 39 + apps/admin-web/src/routeTree.gen.ts | 1047 +++ apps/admin-web/src/router.tsx | 19 + apps/admin-web/src/routes/__root.tsx | 64 + .../src/routes/dashboard.banners.$id.edit.tsx | 152 + .../src/routes/dashboard.banners.new.tsx | 83 + .../src/routes/dashboard.banners.tsx | 432 ++ .../src/routes/dashboard.complaints.tsx | 314 + .../src/routes/dashboard.coupons.$id.edit.tsx | 126 + .../src/routes/dashboard.coupons.new.tsx | 70 + .../src/routes/dashboard.coupons.tsx | 509 ++ .../dashboard.customize-app.ordering.tsx | 301 + .../dashboard.customize-app.popular.tsx | 413 ++ .../src/routes/dashboard.customize-app.tsx | 271 + apps/admin-web/src/routes/dashboard.index.tsx | 305 + .../src/routes/dashboard.notifications.tsx | 168 + .../src/routes/dashboard.orders.$id.tsx | 824 ++ .../src/routes/dashboard.orders.list.tsx | 818 ++ .../src/routes/dashboard.orders.sequence.tsx | 798 ++ .../admin-web/src/routes/dashboard.orders.tsx | 99 + .../admin-web/src/routes/dashboard.prices.tsx | 420 ++ .../dashboard.product-groupings.$id.edit.tsx | 49 + .../dashboard.product-groupings.new.tsx | 19 + .../routes/dashboard.product-groupings.tsx | 198 + .../routes/dashboard.product-tags.edit.tsx | 118 + .../src/routes/dashboard.product-tags.new.tsx | 77 + .../routes/dashboard.product-tags.order.tsx | 286 + .../src/routes/dashboard.product-tags.tsx | 142 + .../src/routes/dashboard.products.$id.tsx | 461 ++ .../src/routes/dashboard.products.edit.tsx | 227 + .../src/routes/dashboard.products.new.tsx | 145 + .../src/routes/dashboard.products.tsx | 228 + .../src/routes/dashboard.rebalance.tsx | 248 + .../src/routes/dashboard.slots.$id.edit.tsx | 53 + .../src/routes/dashboard.slots.detail.tsx | 239 + .../src/routes/dashboard.slots.new.tsx | 48 + apps/admin-web/src/routes/dashboard.slots.tsx | 307 + .../src/routes/dashboard.stores.edit.tsx | 83 + .../src/routes/dashboard.stores.new.tsx | 46 + .../admin-web/src/routes/dashboard.stores.tsx | 199 + apps/admin-web/src/routes/dashboard.tsx | 190 + .../src/routes/dashboard.users.$id.tsx | 250 + apps/admin-web/src/routes/dashboard.users.tsx | 265 + .../src/routes/dashboard.vendor-snippets.tsx | 421 ++ apps/admin-web/src/routes/index.tsx | 26 + apps/admin-web/src/routes/login.tsx | 86 + apps/admin-web/src/services/toaster.tsx | 18 + apps/admin-web/src/ssr.tsx | 8 + apps/admin-web/src/styles.css | 150 + apps/admin-web/src/types/drag-order-item.ts | 6 + apps/admin-web/src/types/vendor-snippets.ts | 32 + apps/admin-web/tsconfig.json | 33 + apps/admin-web/vite.config.ts | 26 + apps/admin-web/wrangler.jsonc | 12 + .../trpc/apis/admin-apis/apis/complaint.ts | 38 +- .../src/trpc/apis/admin-apis/apis/product.ts | 92 +- change-log.txt | 25 + package.json | 3 + 100 files changed, 23509 insertions(+), 74 deletions(-) create mode 100644 apps/admin-web/.cta.json create mode 100644 apps/admin-web/README.md create mode 100644 apps/admin-web/change-log.txt create mode 100644 apps/admin-web/package-lock.json create mode 100644 apps/admin-web/package.json create mode 100644 apps/admin-web/public/favicon.png create mode 100644 apps/admin-web/public/freshyo-logo.png create mode 100644 apps/admin-web/public/logo192.png create mode 100644 apps/admin-web/public/logo512.png create mode 100644 apps/admin-web/public/manifest.json create mode 100644 apps/admin-web/public/robots.txt create mode 100644 apps/admin-web/src/client.tsx create mode 100644 apps/admin-web/src/components/BannerForm.tsx create mode 100644 apps/admin-web/src/components/CancelOrderDialog.tsx create mode 100644 apps/admin-web/src/components/CouponForm.tsx create mode 100644 apps/admin-web/src/components/DateInput.tsx create mode 100644 apps/admin-web/src/components/DateTimeInput.tsx create mode 100644 apps/admin-web/src/components/MultiSelect.tsx create mode 100644 apps/admin-web/src/components/OrderNotesForm.tsx create mode 100644 apps/admin-web/src/components/OrderOptionsMenu.tsx create mode 100644 apps/admin-web/src/components/ProductForm.tsx create mode 100644 apps/admin-web/src/components/ProductGroupForm.tsx create mode 100644 apps/admin-web/src/components/ProductListDialog.tsx create mode 100644 apps/admin-web/src/components/ProductsSelector.tsx create mode 100644 apps/admin-web/src/components/SearchableSelect.tsx create mode 100644 apps/admin-web/src/components/SlotForm.tsx create mode 100644 apps/admin-web/src/components/SnippetMenu.tsx create mode 100644 apps/admin-web/src/components/SnippetOrdersView.tsx create mode 100644 apps/admin-web/src/components/StoreForm.tsx create mode 100644 apps/admin-web/src/components/TagForm.tsx create mode 100644 apps/admin-web/src/components/TagMenu.tsx create mode 100644 apps/admin-web/src/components/UserIncidentsView.tsx create mode 100644 apps/admin-web/src/components/VendorSnippetForm.tsx create mode 100644 apps/admin-web/src/components/context/staff-auth-context.tsx create mode 100644 apps/admin-web/src/hooks/useJWT.ts create mode 100644 apps/admin-web/src/hooks/useUploadToObjectStorage.ts create mode 100644 apps/admin-web/src/lib/event-bus.ts create mode 100644 apps/admin-web/src/lib/navigation-target.ts create mode 100644 apps/admin-web/src/lib/query-client.ts create mode 100644 apps/admin-web/src/lib/refresh-context.tsx create mode 100644 apps/admin-web/src/lib/theme.ts create mode 100644 apps/admin-web/src/lib/trpc-client.ts create mode 100644 apps/admin-web/src/routeTree.gen.ts create mode 100644 apps/admin-web/src/router.tsx create mode 100644 apps/admin-web/src/routes/__root.tsx create mode 100644 apps/admin-web/src/routes/dashboard.banners.$id.edit.tsx create mode 100644 apps/admin-web/src/routes/dashboard.banners.new.tsx create mode 100644 apps/admin-web/src/routes/dashboard.banners.tsx create mode 100644 apps/admin-web/src/routes/dashboard.complaints.tsx create mode 100644 apps/admin-web/src/routes/dashboard.coupons.$id.edit.tsx create mode 100644 apps/admin-web/src/routes/dashboard.coupons.new.tsx create mode 100644 apps/admin-web/src/routes/dashboard.coupons.tsx create mode 100644 apps/admin-web/src/routes/dashboard.customize-app.ordering.tsx create mode 100644 apps/admin-web/src/routes/dashboard.customize-app.popular.tsx create mode 100644 apps/admin-web/src/routes/dashboard.customize-app.tsx create mode 100644 apps/admin-web/src/routes/dashboard.index.tsx create mode 100644 apps/admin-web/src/routes/dashboard.notifications.tsx create mode 100644 apps/admin-web/src/routes/dashboard.orders.$id.tsx create mode 100644 apps/admin-web/src/routes/dashboard.orders.list.tsx create mode 100644 apps/admin-web/src/routes/dashboard.orders.sequence.tsx create mode 100644 apps/admin-web/src/routes/dashboard.orders.tsx create mode 100644 apps/admin-web/src/routes/dashboard.prices.tsx create mode 100644 apps/admin-web/src/routes/dashboard.product-groupings.$id.edit.tsx create mode 100644 apps/admin-web/src/routes/dashboard.product-groupings.new.tsx create mode 100644 apps/admin-web/src/routes/dashboard.product-groupings.tsx create mode 100644 apps/admin-web/src/routes/dashboard.product-tags.edit.tsx create mode 100644 apps/admin-web/src/routes/dashboard.product-tags.new.tsx create mode 100644 apps/admin-web/src/routes/dashboard.product-tags.order.tsx create mode 100644 apps/admin-web/src/routes/dashboard.product-tags.tsx create mode 100644 apps/admin-web/src/routes/dashboard.products.$id.tsx create mode 100644 apps/admin-web/src/routes/dashboard.products.edit.tsx create mode 100644 apps/admin-web/src/routes/dashboard.products.new.tsx create mode 100644 apps/admin-web/src/routes/dashboard.products.tsx create mode 100644 apps/admin-web/src/routes/dashboard.rebalance.tsx create mode 100644 apps/admin-web/src/routes/dashboard.slots.$id.edit.tsx create mode 100644 apps/admin-web/src/routes/dashboard.slots.detail.tsx create mode 100644 apps/admin-web/src/routes/dashboard.slots.new.tsx create mode 100644 apps/admin-web/src/routes/dashboard.slots.tsx create mode 100644 apps/admin-web/src/routes/dashboard.stores.edit.tsx create mode 100644 apps/admin-web/src/routes/dashboard.stores.new.tsx create mode 100644 apps/admin-web/src/routes/dashboard.stores.tsx create mode 100644 apps/admin-web/src/routes/dashboard.tsx create mode 100644 apps/admin-web/src/routes/dashboard.users.$id.tsx create mode 100644 apps/admin-web/src/routes/dashboard.users.tsx create mode 100644 apps/admin-web/src/routes/dashboard.vendor-snippets.tsx create mode 100644 apps/admin-web/src/routes/index.tsx create mode 100644 apps/admin-web/src/routes/login.tsx create mode 100644 apps/admin-web/src/services/toaster.tsx create mode 100644 apps/admin-web/src/ssr.tsx create mode 100644 apps/admin-web/src/styles.css create mode 100644 apps/admin-web/src/types/drag-order-item.ts create mode 100644 apps/admin-web/src/types/vendor-snippets.ts create mode 100644 apps/admin-web/tsconfig.json create mode 100644 apps/admin-web/vite.config.ts create mode 100644 apps/admin-web/wrangler.jsonc diff --git a/.commandcode/taste/taste/taste.md b/.commandcode/taste/taste/taste.md index 8e22427..e157291 100644 --- a/.commandcode/taste/taste/taste.md +++ b/.commandcode/taste/taste/taste.md @@ -30,6 +30,7 @@ - Prefers detailed technical documentation of system architecture, data models, flows, and integrations in markdown format. Confidence: 0.8 - Wants edge cases explicitly enumerated when documenting or analyzing existing code/systems. Confidence: 0.8 - Values end-to-end analysis of features (architecture, data model, flows, integrations, and edge cases) when asked to explain how something works. Confidence: 0.7 +- When creating a clone/mirror of an app on a different platform (e.g., a web version of a React Native app), expects EXACT replication — functionality and looks must match the reference app with zero changes ("not even a slight change is acceptable"). The tech stack is inherited from the existing clone, not the original. Confidence: 0.9 - Prefers unifying parallel data structures into a single instance rather than maintaining separate ones (e.g., one cart for flash and regular items instead of separate flash/regular carts). Confidence: 0.9 - Prefers using sentinel values in existing fields (e.g., slotId = 0) to distinguish special-case items rather than creating separate fields or structures. Confidence: 0.9 - Prefers handling special-case logic locally in the relevant component/file rather than globally or via parallel flows. Confidence: 0.85 diff --git a/apps/admin-web/.cta.json b/apps/admin-web/.cta.json new file mode 100644 index 0000000..ccd23b8 --- /dev/null +++ b/apps/admin-web/.cta.json @@ -0,0 +1,19 @@ +{ + "projectName": "web-ui", + "mode": "file-router", + "typescript": true, + "tailwind": true, + "packageManager": "bun", + "git": true, + "install": true, + "intent": true, + "addOnOptions": {}, + "includeExamples": false, + "envVarValues": {}, + "routerOnly": false, + "version": 1, + "framework": "react", + "chosenAddOns": [ + "nitro" + ] +} \ No newline at end of file diff --git a/apps/admin-web/README.md b/apps/admin-web/README.md new file mode 100644 index 0000000..fd4381f --- /dev/null +++ b/apps/admin-web/README.md @@ -0,0 +1,15 @@ +# Freshyo Admin Web + +Web clone of `apps/admin-ui` — same screens, same functionality, same looks — +built on the exact stack of `apps/web-ui` (TanStack Start + Vite + Tailwind v4 + +tRPC + TanStack Router). + +```bash +npm install +npm run dev # http://localhost:4175 +npm run build # production build +npm run typecheck +``` + +Backend: same as admin-ui (`https://devapi.freshyo.in`); override with +`VITE_API_URL` env var. diff --git a/apps/admin-web/change-log.txt b/apps/admin-web/change-log.txt new file mode 100644 index 0000000..ce93400 --- /dev/null +++ b/apps/admin-web/change-log.txt @@ -0,0 +1,9 @@ + +[2026-09-06 00:10:00] admin-web integration fixes batch: (1) dashboard.notifications.tsx SearchableSelect(number[] mismatch) -> MultiSelect (matches original multi BottomDropdown); (2) TagMenu.tsx router.history.push string nav -> typed navigate({to search}); (3) dashboard.orders.$id.tsx user tap /dashboard/users -> /dashboard/users/$id params nav (route exists); (4) dashboard.users.$id.tsx order nav as-any -> typed params nav; (5) remove temp as-any on now-registered navigate literals (dashboard.index, orders hub, slots, banners, stores, prices, products.edit/groupings casts if tsc-clean); (6) regen routeTree.gen.ts via build. + +[2026-09-06 00:20:00] admin-web README: replaced TanStack boilerplate with Freshyo Admin Web run/build notes (npm install/dev/build, port 4175, VITE_API_URL override). +[2026-09-06 00:20:00] COMPLETED apps/admin-web: exact web clone of apps/admin-ui on apps/web-ui stack (TanStack Start + Vite + Tailwind v4 + tRPC + TanStack Router, port 4175, worker admin-web). 38 routes + 21 components + infra, tsc clean, vite build clean, SSR smoke 200s. +Routes: index gate, login, dashboard shell (sidebar/header/titles/refresh) + hub, complaints, coupons(+new,+$id/edit), customize-app(+popular,+ordering), banners(+new,+$id/edit), orders(+list,+sequence,+$id), prices, product-groupings(+new,+$id/edit), product-tags(+new,+edit?tagId,+order), products(+new,+edit?id,+$id), rebalance, notifications, slots(+new?baseslot,+$id/edit,+detail?slotId), stores(+new,+edit?id), users(+$id), vendor-snippets. +New local primitives: MultiSelect, SearchableSelect, DateTimeInput, DateInput (mirror RN BottomDropdown-multi/search + DateTimePickerMod/DatePicker APIs). +Verification: tsc 0 errors; 54/54 file pairs tRPC-procedure parity (2 apparent gaps proven dead code in original: updateAddressCoords declaration, refund commented block); build ok; dev SSR / /login /dashboard /dashboard/coupons 200, /dashboard/orders/sequence 307 redirect, 0 error refs. +Known platform deltas (no web equivalent): Alert.alert->window.alert, destructive confirms->window.confirm, pull-to-refresh->header refresh button, infinite scroll->Load-more buttons, expo-image-picker->file inputs, native date/time pickers->date+time inputs, haptics/blur/share-target->dropped or navigator.share w/ clipboard fallback, push-notification token acquisition dropped (send flow intact). diff --git a/apps/admin-web/package-lock.json b/apps/admin-web/package-lock.json new file mode 100644 index 0000000..e9b792d --- /dev/null +++ b/apps/admin-web/package-lock.json @@ -0,0 +1,6596 @@ +{ + "name": "admin-web", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "admin-web", + "dependencies": { + "@dnd-kit/core": "^6.3.1", + "@dnd-kit/sortable": "^10.0.0", + "@dnd-kit/utilities": "^3.2.2", + "@tailwindcss/vite": "^4.1.18", + "@tanstack/react-devtools": "^0.10.2", + "@tanstack/react-query": "^5.100.0", + "@tanstack/react-query-devtools": "^5.100.0", + "@tanstack/react-router": "^1.167.0", + "@tanstack/react-router-devtools": "^1.166.0", + "@tanstack/react-router-ssr-query": "^1.166.0", + "@tanstack/react-start": "^1.167.0", + "@tanstack/router-plugin": "^1.167.0", + "@trpc/client": "^11.17.0", + "@trpc/react-query": "^11.17.0", + "@trpc/server": "^11.17.0", + "axios": "^1.16.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "date-fns": "^4.1.0", + "dayjs": "^1.11.20", + "formik": "^2.4.9", + "fuse.js": "^7.3.0", + "jwt-decode": "^4.0.0", + "lucide-react": "^0.400.0", + "nitro": "npm:nitro-nightly@latest", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "sonner": "^1.7.4", + "tailwind-merge": "^3.5.0", + "tailwindcss": "^4.1.18", + "yup": "^1.7.1", + "zustand": "^5.0.13" + }, + "devDependencies": { + "@cloudflare/vite-plugin": "^1.36.3", + "@tanstack/devtools-vite": "^0.6.0", + "@types/node": "^22.10.2", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "@vitejs/plugin-react": "^6.0.1", + "typescript": "^5.8.3", + "vite": "^8.0.0", + "vitest": "^4.1.5", + "wrangler": "^4.90.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz", + "integrity": "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==", + "dev": true, + "license": "MIT OR Apache-2.0", + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/@cloudflare/unenv-preset": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz", + "integrity": "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==", + "dev": true, + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.24", + "workerd": ">1.20260305.0 <2.0.0-0" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } + } + }, + "node_modules/@cloudflare/vite-plugin": { + "version": "1.36.3", + "resolved": "https://registry.npmjs.org/@cloudflare/vite-plugin/-/vite-plugin-1.36.3.tgz", + "integrity": "sha512-n3SZhEZQxk4B2xHaCwgXfc7oLkx/4leTxL254P09DK2Qoj1VVOqVELo62CsUYq5dZS+okMdeWqNa13xEOKMs4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cloudflare/unenv-preset": "2.16.1", + "miniflare": "4.20260507.1", + "unenv": "2.0.0-rc.24", + "wrangler": "4.90.0", + "ws": "8.18.0" + }, + "peerDependencies": { + "vite": "^6.1.0 || ^7.0.0 || ^8.0.0", + "wrangler": "^4.90.0" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20260507.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260507.1.tgz", + "integrity": "sha512-S85aMwcaPJUjKWDiG6iMMnioKWtPLACa6m0j/EhHR1GYfVpnxb974cBc6d25L+sf7jHWHJI2u5hGp0UTJ7MtXQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20260507.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260507.1.tgz", + "integrity": "sha512-GMEBu8Zp9Q97HLnf7bWJN4KjWpN5MxpeqdvHjBGWNl8UYprJI0k+Jkp89+Wh5S8vIon+HoVbDfOzPa7VwgL6Eg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20260507.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260507.1.tgz", + "integrity": "sha512-QlrKEBdgA3uVc0Ok0Q3+0/CW0CTjgj5ySir1i1YY5FXVv0X6GpwtnB5umjunjF2MFprss+L+iFGZzxcSvMC1nA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20260507.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260507.1.tgz", + "integrity": "sha512-eGbbupEtK2nh9V9Dhcx3vv3GTKeXqSVNgAEYVCCN0NGS9tl9HbMoHRX/4JL181FKXROMigWBCQVL//qPhsAzBQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20260507.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260507.1.tgz", + "integrity": "sha512-dmClJ/E0BAcuDetQIZFqbeAXejWrG5pysGRMQ6T83Y0IW/7IAamY2zFEkAJ10I5xwZsdHuYsZtzlOxpEXpJs7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@dnd-kit/accessibility": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz", + "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/core": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz", + "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", + "license": "MIT", + "dependencies": { + "@dnd-kit/accessibility": "^3.1.1", + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/sortable": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-10.0.0.tgz", + "integrity": "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==", + "license": "MIT", + "dependencies": { + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@dnd-kit/core": "^6.3.0", + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/utilities": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", + "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oozcitak/dom": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-2.0.2.tgz", + "integrity": "sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w==", + "license": "MIT", + "dependencies": { + "@oozcitak/infra": "^2.0.2", + "@oozcitak/url": "^3.0.0", + "@oozcitak/util": "^10.0.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@oozcitak/infra": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-2.0.2.tgz", + "integrity": "sha512-2g+E7hoE2dgCz/APPOEK5s3rMhJvNxSMBrP+U+j1OWsIbtSpWxxlUjq1lU8RIsFJNYv7NMlnVsCuHcUzJW+8vA==", + "license": "MIT", + "dependencies": { + "@oozcitak/util": "^10.0.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@oozcitak/url": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-3.0.0.tgz", + "integrity": "sha512-ZKfET8Ak1wsLAiLWNfFkZc/BraDccuTJKR6svTYc7sVjbR+Iu0vtXdiDMY4o6jaFl5TW2TlS7jbLl4VovtAJWQ==", + "license": "MIT", + "dependencies": { + "@oozcitak/infra": "^2.0.2", + "@oozcitak/util": "^10.0.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@oozcitak/util": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-10.0.0.tgz", + "integrity": "sha512-hAX0pT/73190NLqBPPWSdBVGtbY6VOhWYK3qqHqtXQ1gK7kS2yz4+ivsN07hpJ6I3aeMtKP6J6npsEKOAzuTLA==", + "license": "MIT", + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.129.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.129.0.tgz", + "integrity": "sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@poppinss/colors": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz", + "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "kleur": "^4.1.5" + } + }, + "node_modules/@poppinss/dumper": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz", + "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@sindresorhus/is": "^7.0.2", + "supports-color": "^10.0.0" + } + }, + "node_modules/@poppinss/exception": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz", + "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0.tgz", + "integrity": "sha512-TWMZnRLMe63C2Lhyicviu7ZHaU4kxa6PS3rofvc9GmcvptzNN11BcfQ4Sl7MwTOsisQoa2keB/EBdNCAnUo8vA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0.tgz", + "integrity": "sha512-6XcD+8k0gPVItNagEw78/qqcBDwKcwDYS8V2hRmVsfUSIrd8cWe/CBvRDI5toqFyPfj+FJr6t8U6Xj2P2prEew==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0.tgz", + "integrity": "sha512-iN/tWVXRQDWvmZlKdceP1Dwug9GDpEymhb9p4xnEe6zvCg5lFmzVljl+1qR1NVx3yfGpr2Na+CuLmv5IU8uzfQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0.tgz", + "integrity": "sha512-jjQMDvvwSOuhOwMszD/klSOjyWMM3zI64hWTj9KT5x4MxRbZAf+7vLQ6qouRhtsLVFHr3f0ILaJAfgENPiQdAQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0.tgz", + "integrity": "sha512-d//Dtg2x6/m3mbV64yUGNnDGNZaDGRpDLLNGerHQUVObuNaIQaaDp25yUiqGXtHEXX+NP2d0wAlmKgpYgIAJ2A==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0.tgz", + "integrity": "sha512-n7Ofp0mx+aB2cC+Sdy5YtMnXtY9lchnHbY+3Yt0uq9JsWQExf4f5Whu0tK0R8Jdc9S6RchTHjIFY7uc92puOVQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0.tgz", + "integrity": "sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0.tgz", + "integrity": "sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0.tgz", + "integrity": "sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0.tgz", + "integrity": "sha512-Dfn7iak9BcMMePxcoJfpSbWqnEyrp/dRF63/8qW/eHBdOZov6x5aShLLEYGYdIeSJ6vMLK/XCVB+lGIxm41bQA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0.tgz", + "integrity": "sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0.tgz", + "integrity": "sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0.tgz", + "integrity": "sha512-E+oHKGiDA+lsKMmFtffDDw91EryDT7uJocrIuCHqhm6bCTM6xFK+3gaCkYOHfPwQr0cCNarSM2xaELoQDz9jJg==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0.tgz", + "integrity": "sha512-yYK02n8Rngo+gbm1y6G0+7jk1sJ/2Wt7K0me0Y7k/ErBpyf+LJ2gFpqWVTcRV1rUepBlQRmpgWkTQCiiwrK0Ow==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0.tgz", + "integrity": "sha512-14bpChMahXRRXiTwahSl+zzHPW6qQTXtkMuJBFlbo+pqSAews2d4BdCSHfrJ/MBsCZtpmTafsY+1QhBzitcmdg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.40.tgz", + "integrity": "sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w==", + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", + "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@solid-primitives/event-listener": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@solid-primitives/event-listener/-/event-listener-2.4.5.tgz", + "integrity": "sha512-nwRV558mIabl4yVAhZKY8cb6G+O1F0M6Z75ttTu5hk+SxdOnKSGj+eetDIu7Oax1P138ZdUU01qnBPR8rnxaEA==", + "license": "MIT", + "dependencies": { + "@solid-primitives/utils": "^6.4.0" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/keyboard": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@solid-primitives/keyboard/-/keyboard-1.3.5.tgz", + "integrity": "sha512-sav+l+PL+74z3yaftVs7qd8c2SXkqzuxPOVibUe5wYMt+U5Hxp3V3XCPgBPN2I6cANjvoFtz0NiU8uHVLdi9FQ==", + "license": "MIT", + "dependencies": { + "@solid-primitives/event-listener": "^2.4.5", + "@solid-primitives/rootless": "^1.5.3", + "@solid-primitives/utils": "^6.4.0" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/resize-observer": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@solid-primitives/resize-observer/-/resize-observer-2.1.5.tgz", + "integrity": "sha512-AiyTknKcNBaKHbcSMuxtSNM8FjIuiSuFyFghdD0TcCMU9hKi9EmsC5pjfjDwxE+5EueB1a+T/34PLRI5vbBbKw==", + "license": "MIT", + "dependencies": { + "@solid-primitives/event-listener": "^2.4.5", + "@solid-primitives/rootless": "^1.5.3", + "@solid-primitives/static-store": "^0.1.3", + "@solid-primitives/utils": "^6.4.0" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/rootless": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@solid-primitives/rootless/-/rootless-1.5.3.tgz", + "integrity": "sha512-N8cIDAHbWcLahNRLr0knAAQvXyEdEMoAZvIMZKmhNb1mlx9e2UOv9BRD5YNwQUJwbNoYVhhLwFOEOcVXFx0HqA==", + "license": "MIT", + "dependencies": { + "@solid-primitives/utils": "^6.4.0" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/static-store": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@solid-primitives/static-store/-/static-store-0.1.3.tgz", + "integrity": "sha512-uxez7SXnr5GiRnzqO2IEDjOJRIXaG+0LZLBizmUA1FwSi+hrpuMzVBwyk70m4prcl8X6FDDXUl9O8hSq8wHbBQ==", + "license": "MIT", + "dependencies": { + "@solid-primitives/utils": "^6.4.0" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/utils": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.4.0.tgz", + "integrity": "sha512-AeGTBg8Wtkh/0s+evyLtP8piQoS4wyqqQaAFs2HJcFMMjYAtUgo+ZPduRXLjPlqKVc2ejeR544oeqpbn8Egn8A==", + "license": "MIT", + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@speed-highlight/core": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.15.tgz", + "integrity": "sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==", + "devOptional": true, + "license": "CC0-1.0" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz", + "integrity": "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.21.0", + "jiti": "^2.6.1", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.0" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz", + "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.0", + "@tailwindcss/oxide-darwin-arm64": "4.3.0", + "@tailwindcss/oxide-darwin-x64": "4.3.0", + "@tailwindcss/oxide-freebsd-x64": "4.3.0", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.0", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.0", + "@tailwindcss/oxide-linux-x64-musl": "4.3.0", + "@tailwindcss/oxide-wasm32-wasi": "4.3.0", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.0" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.0.tgz", + "integrity": "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.0.tgz", + "integrity": "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.0.tgz", + "integrity": "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.0.tgz", + "integrity": "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.0.tgz", + "integrity": "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.0.tgz", + "integrity": "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.0.tgz", + "integrity": "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.0.tgz", + "integrity": "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.0.tgz", + "integrity": "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.0.tgz", + "integrity": "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.10.0", + "@emnapi/runtime": "^1.10.0", + "@emnapi/wasi-threads": "^1.2.1", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.0.tgz", + "integrity": "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.0.tgz", + "integrity": "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.0.tgz", + "integrity": "sha512-t6J3OrB5Fc0ExuhohouH0fWUGMYL6PTLhW+E7zIk/pdbnJARZDCwjBznFnkh5ynRnIRSI4YjtTH0t6USjJISrw==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.3.0", + "@tailwindcss/oxide": "4.3.0", + "tailwindcss": "4.3.0" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@tanstack/devtools": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@tanstack/devtools/-/devtools-0.11.2.tgz", + "integrity": "sha512-K8+tsBx+ptTLqqd4dOF10B6laj1g+XYImqYZL9n0jBINGaT+sOf17PKV9pbBt8kdbZeIGsHaJ5OZWCyZoHqN4A==", + "license": "MIT", + "dependencies": { + "@solid-primitives/event-listener": "^2.4.3", + "@solid-primitives/keyboard": "^1.3.3", + "@solid-primitives/resize-observer": "^2.1.3", + "@tanstack/devtools-client": "0.0.6", + "@tanstack/devtools-event-bus": "0.4.1", + "@tanstack/devtools-ui": "0.5.1", + "clsx": "^2.1.1", + "goober": "^2.1.16", + "solid-js": "^1.9.9" + }, + "bin": { + "intent": "bin/intent.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "solid-js": ">=1.9.7" + } + }, + "node_modules/@tanstack/devtools-client": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@tanstack/devtools-client/-/devtools-client-0.0.6.tgz", + "integrity": "sha512-f85ZJXJnDIFOoykG/BFIixuAevJovCvJF391LPs6YjBAPhGYC50NWlx1y4iF/UmK5/cCMx+/JqI5SBOz7FanQQ==", + "license": "MIT", + "dependencies": { + "@tanstack/devtools-event-client": "^0.4.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/devtools-event-bus": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tanstack/devtools-event-bus/-/devtools-event-bus-0.4.1.tgz", + "integrity": "sha512-cNnJ89Q021Zf883rlbBTfsaxTfi2r73/qejGtyTa7ksErF3hyDyAq1aTbo5crK9dAL7zSHh9viKY1BtMls1QOA==", + "license": "MIT", + "dependencies": { + "ws": "^8.18.3" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/devtools-event-client": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@tanstack/devtools-event-client/-/devtools-event-client-0.4.3.tgz", + "integrity": "sha512-OZI6QyULw0FI0wjgmeYzCIfbgPsOEzwJtCpa69XrfLMtNXLGnz3d/dIabk7frg0TmHo+Ah49w5I4KC7Tufwsvw==", + "license": "MIT", + "bin": { + "intent": "bin/intent.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/devtools-ui": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@tanstack/devtools-ui/-/devtools-ui-0.5.1.tgz", + "integrity": "sha512-T9JjAdqMSnxsVO6AQykD5vhxPF4iFLKtbYxee/bU3OLlk446F5C1220GdCmhDSz7y4lx+m8AvIS0bq6zzvdDUA==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1", + "dayjs": "^1.11.19", + "goober": "^2.1.16", + "solid-js": "^1.9.9" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "solid-js": ">=1.9.7" + } + }, + "node_modules/@tanstack/devtools-vite": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@tanstack/devtools-vite/-/devtools-vite-0.6.0.tgz", + "integrity": "sha512-h0r0ct7zlrgjkhmn4QW6wRjgUXd4JMs+r7gtx+BXo9f5H9Y+jtUdtvC0rnZcPto6gw/9yMUq7yOmMK5qDWRExg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.4", + "@babel/generator": "^7.28.3", + "@babel/parser": "^7.28.4", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@tanstack/devtools-client": "0.0.6", + "@tanstack/devtools-event-bus": "0.4.1", + "chalk": "^5.6.2", + "launch-editor": "^2.11.1", + "picomatch": "^4.0.3" + }, + "bin": { + "intent": "bin/intent.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@tanstack/history": { + "version": "1.161.6", + "resolved": "https://registry.npmjs.org/@tanstack/history/-/history-1.161.6.tgz", + "integrity": "sha512-NaOGLRrddszbQj9upGat6HG/4TKvXLvu+osAIgfxPYA+eIvYKv8GKDJOrY2D3/U9MRnKfMWD7bU4jeD4xmqyIg==", + "license": "MIT", + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.9.tgz", + "integrity": "sha512-SJSFw1S8+kQ0+knv/XGfrbocWoAlT7vDKsSImtLx3ZPQmEcR46hkDjLSvynSy25N8Ms4tIEini1FuBd5k7IscQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-devtools": { + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.100.9.tgz", + "integrity": "sha512-gqiptrTIhbK2PuCaPRHmWXfJG1NGYVFpAr0HqogEqiSBNB5xDz6fmesQt7w4WgMOqOQPnPHJ3ZDMuhDaXvNO8g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-devtools": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-devtools/-/react-devtools-0.10.2.tgz", + "integrity": "sha512-1BmZyxOrI5SqmRJ5MgkYZNNdnlLsJxQRI2YgorrAvcF2MxK6x5RcuStvD8+YlXoMw3JtNukPxoITirKAnKYDQA==", + "license": "MIT", + "dependencies": { + "@tanstack/devtools": "0.11.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "@types/react-dom": ">=16.8", + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.100.9.tgz", + "integrity": "sha512-Oa44XkaI3kCNN6ME0KByU3xT3SEUNOMfZpHxL6+wFoTm+OeUFYHKdeYVe0aOXlRDm/f15sgLwEt2HDorIdW8+A==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.100.9" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-query-devtools": { + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.100.9.tgz", + "integrity": "sha512-mM3slaVGXJmz+pOLgXdANj75ikgQCyudyl3kmFvm6brI1JyVeY/+IeD17uDHIvZrD8hfoO2sdZ54RFsHdYAuhA==", + "license": "MIT", + "dependencies": { + "@tanstack/query-devtools": "5.100.9" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-query": "^5.100.9", + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-router": { + "version": "1.169.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.169.2.tgz", + "integrity": "sha512-OJM7Kguc7ERnweaNRWsyWgIKcl3z23rD1B4jaxjzd9RGdnzpt2HfrWa9rggbT0Hfzhfo4D2ZmsfoTme035tniQ==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.161.6", + "@tanstack/react-store": "^0.9.3", + "@tanstack/router-core": "1.169.2", + "isbot": "^5.1.22" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0" + } + }, + "node_modules/@tanstack/react-router-devtools": { + "version": "1.166.13", + "resolved": "https://registry.npmjs.org/@tanstack/react-router-devtools/-/react-router-devtools-1.166.13.tgz", + "integrity": "sha512-6yKRFFJrEEOiGp5RAAuGCYsl81M4XAhJmLcu9PKj+HZle4A3dsP60lwHoqQYWHMK9nKKFkdXR+D8qxzxqtQbEA==", + "license": "MIT", + "dependencies": { + "@tanstack/router-devtools-core": "1.167.3" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-router": "^1.168.15", + "@tanstack/router-core": "^1.168.11", + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0" + }, + "peerDependenciesMeta": { + "@tanstack/router-core": { + "optional": true + } + } + }, + "node_modules/@tanstack/react-router-ssr-query": { + "version": "1.166.12", + "resolved": "https://registry.npmjs.org/@tanstack/react-router-ssr-query/-/react-router-ssr-query-1.166.12.tgz", + "integrity": "sha512-yDUIoEh+PimAcWmk/2BE0EkI8TwLVeToNzoIuwahmTtBUR+ptZPWbtiPjudO8JZ0BhT3odHtuOn1eBOK0/4NAQ==", + "license": "MIT", + "dependencies": { + "@tanstack/router-ssr-query-core": "1.168.0" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/query-core": ">=5.90.0", + "@tanstack/react-query": ">=5.90.0", + "@tanstack/react-router": ">=1.127.0", + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0" + } + }, + "node_modules/@tanstack/react-start": { + "version": "1.167.65", + "resolved": "https://registry.npmjs.org/@tanstack/react-start/-/react-start-1.167.65.tgz", + "integrity": "sha512-vCGga3RECeR4VpSVuXIU/+zxak5f2qdpUXdZ2yrgcwwKoYPtatdJm6zjS0Py7UOecRqLqMtSeuOjowBJ1higWQ==", + "license": "MIT", + "dependencies": { + "@tanstack/react-router": "1.169.2", + "@tanstack/react-start-client": "1.166.48", + "@tanstack/react-start-rsc": "0.0.44", + "@tanstack/react-start-server": "1.166.52", + "@tanstack/router-utils": "1.161.8", + "@tanstack/start-client-core": "1.168.2", + "@tanstack/start-plugin-core": "1.169.20", + "@tanstack/start-server-core": "1.167.30", + "pathe": "^2.0.3" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@rsbuild/core": "^2.0.0", + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0", + "vite": ">=7.0.0" + }, + "peerDependenciesMeta": { + "@rsbuild/core": { + "optional": true + }, + "@vitejs/plugin-rsc": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@tanstack/react-start-client": { + "version": "1.166.48", + "resolved": "https://registry.npmjs.org/@tanstack/react-start-client/-/react-start-client-1.166.48.tgz", + "integrity": "sha512-6fqwCwe6v+Nvtdf6vg6gxs/0gCXyZEHF18EslNeG/kca2wnXYFuXRhqGJjJaEgMk3WF4IE9mUgFuBSAOY3P7nQ==", + "license": "MIT", + "dependencies": { + "@tanstack/react-router": "1.169.2", + "@tanstack/router-core": "1.169.2", + "@tanstack/start-client-core": "1.168.2" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0" + } + }, + "node_modules/@tanstack/react-start-rsc": { + "version": "0.0.44", + "resolved": "https://registry.npmjs.org/@tanstack/react-start-rsc/-/react-start-rsc-0.0.44.tgz", + "integrity": "sha512-5iYUWSBjTwJbV8bTLJHZ5dHm8c/79J6spxPlKsjt9/R0mQaQQjLVNMpv5CrOZ2vPTaZx1ALoGdSWP4WdPcuKRA==", + "license": "MIT", + "dependencies": { + "@tanstack/react-router": "1.169.2", + "@tanstack/react-start-server": "1.166.52", + "@tanstack/router-core": "1.169.2", + "@tanstack/router-utils": "1.161.8", + "@tanstack/start-client-core": "1.168.2", + "@tanstack/start-fn-stubs": "1.161.6", + "@tanstack/start-plugin-core": "1.169.20", + "@tanstack/start-server-core": "1.167.30", + "@tanstack/start-storage-context": "1.166.35", + "pathe": "^2.0.3" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@rspack/core": ">=2.0.0-0", + "@vitejs/plugin-rsc": ">=0.5.20", + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0", + "react-server-dom-rspack": ">=0.0.2" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "@vitejs/plugin-rsc": { + "optional": true + }, + "react-server-dom-rspack": { + "optional": true + } + } + }, + "node_modules/@tanstack/react-start-server": { + "version": "1.166.52", + "resolved": "https://registry.npmjs.org/@tanstack/react-start-server/-/react-start-server-1.166.52.tgz", + "integrity": "sha512-46Gx+byIndYywUtyna5h3qatHipJkPFqo/miexfuYPgeVAI6ypQzsw7wxF194H6VAP43m2q+fdLPBXStufoOGw==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.161.6", + "@tanstack/react-router": "1.169.2", + "@tanstack/router-core": "1.169.2", + "@tanstack/start-client-core": "1.168.2", + "@tanstack/start-server-core": "1.167.30" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0" + } + }, + "node_modules/@tanstack/react-store": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.9.3.tgz", + "integrity": "sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==", + "license": "MIT", + "dependencies": { + "@tanstack/store": "0.9.3", + "use-sync-external-store": "^1.6.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tanstack/router-core": { + "version": "1.169.2", + "resolved": "https://registry.npmjs.org/@tanstack/router-core/-/router-core-1.169.2.tgz", + "integrity": "sha512-5sm0DJF1A7Mz+9gy4Gz/lLovNailK3yot4vYvz9MkBUPw26uLnhQiR8hSCYxucjE0wD6Mdlc5l+Z0/XTlZ7xHw==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.161.6", + "cookie-es": "^3.0.0", + "seroval": "^1.5.4", + "seroval-plugins": "^1.5.4" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/router-devtools-core": { + "version": "1.167.3", + "resolved": "https://registry.npmjs.org/@tanstack/router-devtools-core/-/router-devtools-core-1.167.3.tgz", + "integrity": "sha512-fJ1VMhyQgnoashTrP763c2HRc9kofgF61L7Jb3F6eTHAmCKtGVx8BRtiFt37sr3U0P0jmaaiiSPGP6nT5JtVNg==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1", + "goober": "^2.1.16" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/router-core": "^1.168.11", + "csstype": "^3.0.10" + }, + "peerDependenciesMeta": { + "csstype": { + "optional": true + } + } + }, + "node_modules/@tanstack/router-generator": { + "version": "1.166.42", + "resolved": "https://registry.npmjs.org/@tanstack/router-generator/-/router-generator-1.166.42.tgz", + "integrity": "sha512-2qBWC0t78r6b3vI+AbnvCZcFAvbYBDlLuWZrTjQbcjUmwG3qyeQp983tJyDuj9wb5//adG1tgAGXZkJ3aDwdBg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5", + "@tanstack/router-core": "1.169.2", + "@tanstack/router-utils": "1.161.8", + "@tanstack/virtual-file-routes": "1.161.7", + "jiti": "^2.7.0", + "magic-string": "^0.30.21", + "prettier": "^3.5.0", + "zod": "^3.24.2" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/router-plugin": { + "version": "1.167.35", + "resolved": "https://registry.npmjs.org/@tanstack/router-plugin/-/router-plugin-1.167.35.tgz", + "integrity": "sha512-UAScU5VAzLYVY4FML/Cbc5S5TucT4I8Ata05yozGOe4ZfepTKRffA5xWLtD2N+ov5svdv0KTX/kqlZnYPe28mA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@tanstack/router-core": "1.169.2", + "@tanstack/router-generator": "1.166.42", + "@tanstack/router-utils": "1.161.8", + "@tanstack/virtual-file-routes": "1.161.7", + "chokidar": "^3.6.0", + "unplugin": "^3.0.0", + "zod": "^3.24.2" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@rsbuild/core": ">=1.0.2 || ^2.0.0", + "@tanstack/react-router": "^1.169.2", + "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0", + "vite-plugin-solid": "^2.11.10 || ^3.0.0-0", + "webpack": ">=5.92.0" + }, + "peerDependenciesMeta": { + "@rsbuild/core": { + "optional": true + }, + "@tanstack/react-router": { + "optional": true + }, + "vite": { + "optional": true + }, + "vite-plugin-solid": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/@tanstack/router-ssr-query-core": { + "version": "1.168.0", + "resolved": "https://registry.npmjs.org/@tanstack/router-ssr-query-core/-/router-ssr-query-core-1.168.0.tgz", + "integrity": "sha512-5yBUAF1d9z2kOFKoz1spvpvkMSTmRnRXEwi+bGKfrXYmt7CfHu3Pk8KUFMln67uQoKQ9VTkcd5tLkjJVrZ2/AQ==", + "license": "MIT", + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/query-core": ">=5.90.0", + "@tanstack/router-core": ">=1.127.0" + } + }, + "node_modules/@tanstack/router-utils": { + "version": "1.161.8", + "resolved": "https://registry.npmjs.org/@tanstack/router-utils/-/router-utils-1.161.8.tgz", + "integrity": "sha512-xyiLWEKjfBAVhauDSSjXxyf7s8elU6SM+V050sbkofvGmIIvkwPFtDsX7Gvwh14kBd6iCwAT+RiPvXTxAptY0Q==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.5", + "@babel/generator": "^7.28.5", + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "ansis": "^4.1.0", + "babel-dead-code-elimination": "^1.0.12", + "diff": "^8.0.2", + "pathe": "^2.0.3", + "tinyglobby": "^0.2.15" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/start-client-core": { + "version": "1.168.2", + "resolved": "https://registry.npmjs.org/@tanstack/start-client-core/-/start-client-core-1.168.2.tgz", + "integrity": "sha512-/bckv9k/yxY4VmSY2V2MeX7NBsS5uqGvdSPs5WIvW3Uv35DXPrdiumKXTNJeZRNRMtxrM+YfxQPjXLx3C7ykvg==", + "license": "MIT", + "dependencies": { + "@tanstack/router-core": "1.169.2", + "@tanstack/start-fn-stubs": "1.161.6", + "@tanstack/start-storage-context": "1.166.35", + "seroval": "^1.5.4" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/start-fn-stubs": { + "version": "1.161.6", + "resolved": "https://registry.npmjs.org/@tanstack/start-fn-stubs/-/start-fn-stubs-1.161.6.tgz", + "integrity": "sha512-Y6QSlGiLga8cHfvxGGaonXIlt2bIUTVdH6AMjmpMp7+ANNCp+N96GQbjjhLye3JkaxDfP68x5iZA8NK4imgRig==", + "license": "MIT", + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/start-plugin-core": { + "version": "1.169.20", + "resolved": "https://registry.npmjs.org/@tanstack/start-plugin-core/-/start-plugin-core-1.169.20.tgz", + "integrity": "sha512-MLSH5P3auFpnol1lMGQhUrpJH7+P5knzBXMnJjXG+nVOvmcYbY0JA+nQMl81kKiqfkEceAiaEdKhl8Zc5Ldolw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "7.27.1", + "@babel/core": "^7.28.5", + "@babel/types": "^7.28.5", + "@rolldown/pluginutils": "1.0.0-beta.40", + "@tanstack/router-core": "1.169.2", + "@tanstack/router-generator": "1.166.42", + "@tanstack/router-plugin": "1.167.35", + "@tanstack/router-utils": "1.161.8", + "@tanstack/start-client-core": "1.168.2", + "@tanstack/start-server-core": "1.167.30", + "cheerio": "^1.0.0", + "exsolve": "^1.0.7", + "lightningcss": "^1.32.0", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "seroval": "^1.5.4", + "source-map": "^0.7.6", + "srvx": "^0.11.9", + "tinyglobby": "^0.2.15", + "ufo": "^1.5.4", + "vitefu": "^1.1.1", + "xmlbuilder2": "^4.0.3", + "zod": "^3.24.2" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@rsbuild/core": "^2.0.0", + "vite": ">=7.0.0" + }, + "peerDependenciesMeta": { + "@rsbuild/core": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@tanstack/start-plugin-core/node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@tanstack/start-server-core": { + "version": "1.167.30", + "resolved": "https://registry.npmjs.org/@tanstack/start-server-core/-/start-server-core-1.167.30.tgz", + "integrity": "sha512-GC0PXzYYSEwfAOC2NxGXFUyYvfbSjVoqnIrzJsyInKd8xQxGEQaVdrebbyx9TV5cj7A5e7EJcWAsf3G3wRDQBw==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.161.6", + "@tanstack/router-core": "1.169.2", + "@tanstack/start-client-core": "1.168.2", + "@tanstack/start-storage-context": "1.166.35", + "fetchdts": "^0.1.6", + "h3-v2": "npm:h3@2.0.1-rc.20", + "seroval": "^1.5.4" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/start-storage-context": { + "version": "1.166.35", + "resolved": "https://registry.npmjs.org/@tanstack/start-storage-context/-/start-storage-context-1.166.35.tgz", + "integrity": "sha512-ZKDkKiorJrKwfEHjatEwRHG7EP3raJPhh6CSl4CFmHW0naIvwaW5gQcxcT8IlHtoGDLYDAjBEcSr3MZyXgqmOA==", + "license": "MIT", + "dependencies": { + "@tanstack/router-core": "1.169.2" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/store": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.9.3.tgz", + "integrity": "sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/virtual-file-routes": { + "version": "1.161.7", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-file-routes/-/virtual-file-routes-1.161.7.tgz", + "integrity": "sha512-olW33+Cn+bsCsZKPwEGhlkqS6w3M2slFv11JIobdnCFKMLG97oAI2kWKdx5/zsywTL8flpnoIgaZZPlQTFYhdQ==", + "license": "MIT", + "bin": { + "intent": "bin/intent.js" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@trpc/client": { + "version": "11.17.0", + "resolved": "https://registry.npmjs.org/@trpc/client/-/client-11.17.0.tgz", + "integrity": "sha512-KpJBFrbKTDeVCFv/3ckL1XBBH5Yssn8hethI/rUy7GIpTj+VzjtPjykDqJpzobuVOz+d26cXCSu1t4I6MYI5Zg==", + "funding": [ + "https://trpc.io/sponsor" + ], + "license": "MIT", + "bin": { + "intent": "bin/intent.js" + }, + "peerDependencies": { + "@trpc/server": "11.17.0", + "typescript": ">=5.7.2" + } + }, + "node_modules/@trpc/react-query": { + "version": "11.17.0", + "resolved": "https://registry.npmjs.org/@trpc/react-query/-/react-query-11.17.0.tgz", + "integrity": "sha512-AGcl5YAF8NnhBmyJ6PqJqKb1M5VTGSoNRNqJ3orct4o4epdcg0GWhW+qT9q6gPzs/2ImIwYCdfFpgNGdZ9yLHA==", + "funding": [ + "https://trpc.io/sponsor" + ], + "license": "MIT", + "peerDependencies": { + "@tanstack/react-query": "^5.80.3", + "@trpc/client": "11.17.0", + "@trpc/server": "11.17.0", + "react": ">=18.2.0", + "typescript": ">=5.7.2" + } + }, + "node_modules/@trpc/server": { + "version": "11.17.0", + "resolved": "https://registry.npmjs.org/@trpc/server/-/server-11.17.0.tgz", + "integrity": "sha512-jbAOUe0PpUTCYqziyu+8vYXZdDXPudZgnEhWCQ2NjKnVEjfE93RqHTt1oycZJv/HNf51YlRXfEEwSIAbb161rw==", + "funding": [ + "https://trpc.io/sponsor" + ], + "license": "MIT", + "bin": { + "intent": "bin/intent.js" + }, + "peerDependencies": { + "typescript": ">=5.7.2" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz", + "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==", + "license": "MIT", + "dependencies": { + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/node": { + "version": "22.19.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.18.tgz", + "integrity": "sha512-9v00a+dn2yWVsYDEunWC4g/TcRKVq3r8N5FuZp7u0SGrPvdN9c2yXI9bBuf5Fl0hNCb+QTIePTn5pJs2pwBOQQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz", + "integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-rc.7" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } + } + }, + "node_modules/@vitejs/plugin-react/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.7", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", + "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/expect": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.5.tgz", + "integrity": "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.5", + "@vitest/utils": "4.1.5", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.5.tgz", + "integrity": "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.5", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.5.tgz", + "integrity": "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.5.tgz", + "integrity": "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.5", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.5.tgz", + "integrity": "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.5", + "@vitest/utils": "4.1.5", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.5.tgz", + "integrity": "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.5.tgz", + "integrity": "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.5", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/ansis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz", + "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==", + "license": "ISC", + "engines": { + "node": ">=14" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/babel-dead-code-elimination": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/babel-dead-code-elimination/-/babel-dead-code-elimination-1.0.12.tgz", + "integrity": "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.7", + "@babel/parser": "^7.23.6", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.29", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz", + "integrity": "sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/blake3-wasm": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", + "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001792", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", + "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-3.1.1.tgz", + "integrity": "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==", + "license": "MIT" + }, + "node_modules/crossws": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.4.5.tgz", + "integrity": "sha512-wUR89x/Rw7/8t+vn0CmGDYM9TD6VtARGb0LD5jq2wjtMy1vCP4M+sm6N6TigWeTYvnA8MoW29NqqXD0ep0rfBA==", + "license": "MIT", + "peerDependencies": { + "srvx": ">=0.11.5" + }, + "peerDependenciesMeta": { + "srvx": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/date-fns": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.4.0.tgz", + "integrity": "sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "license": "MIT" + }, + "node_modules/db0": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/db0/-/db0-0.3.4.tgz", + "integrity": "sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==", + "license": "MIT", + "peerDependencies": { + "@electric-sql/pglite": "*", + "@libsql/client": "*", + "better-sqlite3": "*", + "drizzle-orm": "*", + "mysql2": "*", + "sqlite3": "*" + }, + "peerDependenciesMeta": { + "@electric-sql/pglite": { + "optional": true + }, + "@libsql/client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "drizzle-orm": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "sqlite3": { + "optional": true + } + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.353", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.353.tgz", + "integrity": "sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w==", + "license": "ISC" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.21.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.2.tgz", + "integrity": "sha512-xe9vQb5kReirPUxgQrXA3ihgbCqssmTiM7cOZ+Gzu+VeGWgpV98lLZvp0dl4yriyAePcewxGUs9UpKD8PET9KQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-runner": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/env-runner/-/env-runner-0.1.7.tgz", + "integrity": "sha512-i7h96jxETJYhXy5grgHNJ9xNzCzWIn9Ck/VkkYgOlE4gOqknsLX3CmlVb5LmwNex8sOoLFVZLz+TIw/+b5rktA==", + "license": "MIT", + "dependencies": { + "crossws": "^0.4.4", + "exsolve": "^1.0.8", + "httpxy": "^0.5.0", + "srvx": "^0.11.13" + }, + "bin": { + "env-runner": "dist/cli.mjs" + }, + "peerDependencies": { + "@netlify/runtime": "^4", + "miniflare": "^4.20260317.3" + }, + "peerDependenciesMeta": { + "@netlify/runtime": { + "optional": true + }, + "miniflare": { + "optional": true + } + } + }, + "node_modules/error-stack-parser-es": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", + "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "devOptional": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "devOptional": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/exsolve": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fetchdts": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/fetchdts/-/fetchdts-0.1.7.tgz", + "integrity": "sha512-YoZjBdafyLIop9lSxXVI33oLD5kN31q4Td+CasofLLYeLXRFeOsuOw0Uo+XNRi9PZlbfdlN2GmRtm4tCEQ9/KA==", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formik": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.9.tgz", + "integrity": "sha512-5nI94BMnlFDdQRBY4Sz39WkhxajZJ57Fzs8wVbtsQlm5ScKIR1QLYqv/ultBnobObtlUyxpxoLodpixrsf36Og==", + "funding": [ + { + "type": "individual", + "url": "https://opencollective.com/formik" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fuse.js": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.3.0.tgz", + "integrity": "sha512-plz8RVjfcDedTGfVngWH1jmJvBvAwi1v2jecfDerbEnMcmOYUEEwKFTHbNoCiYyzaK2Ws8lABkTCcRSqCY1q4w==", + "license": "Apache-2.0", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/krisk" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/goober": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.18.tgz", + "integrity": "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==", + "license": "MIT", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/h3": { + "version": "2.0.1-rc.22", + "resolved": "https://registry.npmjs.org/h3/-/h3-2.0.1-rc.22.tgz", + "integrity": "sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==", + "license": "MIT", + "dependencies": { + "rou3": "^0.8.1", + "srvx": "^0.11.15" + }, + "bin": { + "h3": "bin/h3.mjs" + }, + "engines": { + "node": ">=20.11.1" + }, + "peerDependencies": { + "crossws": "^0.4.1" + }, + "peerDependenciesMeta": { + "crossws": { + "optional": true + } + } + }, + "node_modules/h3-v2": { + "name": "h3", + "version": "2.0.1-rc.20", + "resolved": "https://registry.npmjs.org/h3/-/h3-2.0.1-rc.20.tgz", + "integrity": "sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==", + "license": "MIT", + "dependencies": { + "rou3": "^0.8.1", + "srvx": "^0.11.13" + }, + "bin": { + "h3": "bin/h3.mjs" + }, + "engines": { + "node": ">=20.11.1" + }, + "peerDependencies": { + "crossws": "^0.4.1" + }, + "peerDependenciesMeta": { + "crossws": { + "optional": true + } + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hookable": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-6.1.1.tgz", + "integrity": "sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==", + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/httpxy": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/httpxy/-/httpxy-0.5.1.tgz", + "integrity": "sha512-JPhqYiixe1A1I+MXDewWDZqeudBGU8Q9jCHYN8ML+779RQzLjTi78HBvWz4jMxUD6h2/vUL12g4q/mFM0OUw1A==", + "license": "MIT" + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isbot": { + "version": "5.1.40", + "resolved": "https://registry.npmjs.org/isbot/-/isbot-5.1.40.tgz", + "integrity": "sha512-yNeeynhhtIVRBk12tBV4eHNxwB42HzR4Q3Ea7vCOiJhImGaAIdIMrbJtacQlBizGLjUPw+akkFI5Dn9T70XoVQ==", + "license": "Unlicense", + "engines": { + "node": ">=18" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/launch-editor": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.2.tgz", + "integrity": "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1", + "shell-quote": "^1.8.3" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.400.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.400.0.tgz", + "integrity": "sha512-rpp7pFHh3Xd93KHixNgB0SqThMHpYNzsGUu69UaQbSZ75Q/J3m5t6EhKyMT3m4w2WOxmJ2mY0tD3vebnXqQryQ==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/miniflare": { + "version": "4.20260507.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260507.1.tgz", + "integrity": "sha512-PSXBiLExTdZ4UGO/raKCHQauUpYL7F880ZRB7j0+78Rv8h7TsdN2E/iEDK9sK2Y+SPQ5wJSeAa+rDeVKoZZoEw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "sharp": "^0.34.5", + "undici": "7.24.8", + "workerd": "1.20260507.1", + "ws": "8.18.0", + "youch": "4.1.0-beta.10" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/miniflare/node_modules/undici": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.8.tgz", + "integrity": "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/miniflare/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nf3": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/nf3/-/nf3-0.3.17.tgz", + "integrity": "sha512-N9zEWySuJFw+gR0lhS5863YsvNeudOdqRyFvNb+jMXbeTJOdrjDqkCpDginIZfUm0LzT1t1nCRiDeqQm/8kirQ==", + "license": "MIT" + }, + "node_modules/nitro": { + "name": "nitro-nightly", + "version": "3.0.1-20260508-123613-d2e64906", + "resolved": "https://registry.npmjs.org/nitro-nightly/-/nitro-nightly-3.0.1-20260508-123613-d2e64906.tgz", + "integrity": "sha512-vqVPALHX0Couvdvdm9QZs0dHcbLqiZxlNqq0iQcQzzToEzmORCPYx26Fj4iaOSpvXMaf0uc0i6iMsDvFrlYGnQ==", + "license": "MIT", + "dependencies": { + "consola": "^3.4.2", + "crossws": "^0.4.5", + "db0": "^0.3.4", + "env-runner": "^0.1.7", + "h3": "^2.0.1-rc.22", + "hookable": "^6.1.1", + "nf3": "^0.3.16", + "ocache": "^0.1.4", + "ofetch": "^2.0.0-alpha.3", + "ohash": "^2.0.11", + "rolldown": "^1.0.0", + "srvx": "^0.11.15", + "unenv": "^2.0.0-rc.24", + "unstorage": "^2.0.0-alpha.7" + }, + "bin": { + "nitro": "dist/cli/index.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@vercel/queue": "^0.1.6", + "dotenv": "*", + "giget": "*", + "jiti": "^2.6.1", + "rollup": "^4.60.3", + "vite": "^7 || ^8", + "xml2js": "^0.6.2", + "zephyr-agent": "^0.2.0" + }, + "peerDependenciesMeta": { + "@vercel/queue": { + "optional": true + }, + "dotenv": { + "optional": true + }, + "giget": { + "optional": true + }, + "jiti": { + "optional": true + }, + "rollup": { + "optional": true + }, + "vite": { + "optional": true + }, + "xml2js": { + "optional": true + }, + "zephyr-agent": { + "optional": true + } + } + }, + "node_modules/nitro/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/nitro/node_modules/lru-cache": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "license": "BlueOak-1.0.0", + "optional": true, + "peer": true, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/nitro/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/nitro/node_modules/unstorage": { + "version": "2.0.0-alpha.7", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-2.0.0-alpha.7.tgz", + "integrity": "sha512-ELPztchk2zgFJnakyodVY3vJWGW9jy//keJ32IOJVGUMyaPydwcA1FtVvWqT0TNRch9H+cMNEGllfVFfScImog==", + "license": "MIT", + "peerDependencies": { + "@azure/app-configuration": "^1.11.0", + "@azure/cosmos": "^4.9.1", + "@azure/data-tables": "^13.3.2", + "@azure/identity": "^4.13.0", + "@azure/keyvault-secrets": "^4.10.0", + "@azure/storage-blob": "^12.31.0", + "@capacitor/preferences": "^6 || ^7 || ^8", + "@deno/kv": ">=0.13.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.36.2", + "@vercel/blob": ">=0.27.3", + "@vercel/functions": "^2.2.12 || ^3.0.0", + "@vercel/kv": "^1.0.1", + "aws4fetch": "^1.0.20", + "chokidar": "^4 || ^5", + "db0": ">=0.3.4", + "idb-keyval": "^6.2.2", + "ioredis": "^5.9.3", + "lru-cache": "^11.2.6", + "mongodb": "^6 || ^7", + "ofetch": "*", + "uploadthing": "^7.7.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/functions": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "chokidar": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "lru-cache": { + "optional": true + }, + "mongodb": { + "optional": true + }, + "ofetch": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", + "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/ocache": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/ocache/-/ocache-0.1.4.tgz", + "integrity": "sha512-e7geNdWjxSnvsSgvLuPvgKgu7ubM10ZmTPOgpr7mz2BXYtvjMKTiLhjFi/gWU8chkuP6hNkZBsa9LzOusyaqkQ==", + "license": "MIT", + "dependencies": { + "ohash": "^2.0.11" + } + }, + "node_modules/ofetch": { + "version": "2.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-2.0.0-alpha.3.tgz", + "integrity": "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==", + "license": "MIT" + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prettier": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/react": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", + "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", + "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.6" + } + }, + "node_modules/react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==", + "license": "MIT" + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/rolldown": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0.tgz", + "integrity": "sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA==", + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.129.0", + "@rolldown/pluginutils": "1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0", + "@rolldown/binding-darwin-arm64": "1.0.0", + "@rolldown/binding-darwin-x64": "1.0.0", + "@rolldown/binding-freebsd-x64": "1.0.0", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0", + "@rolldown/binding-linux-arm64-gnu": "1.0.0", + "@rolldown/binding-linux-arm64-musl": "1.0.0", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0", + "@rolldown/binding-linux-s390x-gnu": "1.0.0", + "@rolldown/binding-linux-x64-gnu": "1.0.0", + "@rolldown/binding-linux-x64-musl": "1.0.0", + "@rolldown/binding-openharmony-arm64": "1.0.0", + "@rolldown/binding-wasm32-wasi": "1.0.0", + "@rolldown/binding-win32-arm64-msvc": "1.0.0", + "@rolldown/binding-win32-x64-msvc": "1.0.0" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0.tgz", + "integrity": "sha512-aKs/3GSWyV0mrhNmt/96/Z3yczC3yvrzYATCiCXQebBsGyYzjNdUphRVLeJQ67ySKVXRfMxt2lm12pmXvbPFQQ==", + "license": "MIT" + }, + "node_modules/rou3": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/rou3/-/rou3-0.8.1.tgz", + "integrity": "sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==", + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/seroval": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.5.4.tgz", + "integrity": "sha512-46uFvgrXTVxZcUorgSSRZ4y+ieqLLQRMlG4bnCZKW3qI6BZm7Rg4ntMW4p1mILEEBZWrFlcpp0AyIIlM6jD9iw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/seroval-plugins": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.5.4.tgz", + "integrity": "sha512-S0xQPhUTefAhNvNWFg0c1J8qJArHt5KdtJ/cFAofo06KD1MVSeFWyl4iiu+ApDIuw0WhjpOfCdgConOfAnLgkw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "seroval": "^1.0" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "devOptional": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/solid-js": { + "version": "1.9.12", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.12.tgz", + "integrity": "sha512-QzKaSJq2/iDrWR1As6MHZQ8fQkdOBf8GReYb7L5iKwMGceg7HxDcaOHk0at66tNgn9U2U7dXo8ZZpLIAmGMzgw==", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.0", + "seroval": "~1.5.0", + "seroval-plugins": "~1.5.0" + } + }, + "node_modules/sonner": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.7.4.tgz", + "integrity": "sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/srvx": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/srvx/-/srvx-0.11.15.tgz", + "integrity": "sha512-iXsux0UcOjdvs0LCMa2Ws3WwcDUozA3JN3BquNXkaFPP7TpRqgunKdEgoZ/uwb1J6xaYHfxtz9Twlh6yzwM6Tg==", + "license": "MIT", + "bin": { + "srvx": "bin/srvx.mjs" + }, + "engines": { + "node": ">=20.16.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", + "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tailwind-merge": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.5.0.tgz", + "integrity": "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz", + "integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", + "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "license": "MIT" + }, + "node_modules/undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/unenv": { + "version": "2.0.0-rc.24", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz", + "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3" + } + }, + "node_modules/unplugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.0.0.tgz", + "integrity": "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/vite": { + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.11.tgz", + "integrity": "sha512-Jz1mxtUBR5xTT65VOdJZUUeoyLtqljmFkiUXhPTLZka3RDc9vpi/xXkyrnsdRcm2lIi3l3GPMnAidTsEGIj3Ow==", + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.14", + "rolldown": "1.0.0-rc.18", + "tinyglobby": "^0.2.16" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@oxc-project/types": { + "version": "0.128.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.128.0.tgz", + "integrity": "sha512-huv1Y/LzBJkBVHt3OlC7u0zHBW9qXf1FdD7sGmc1rXc2P1mTwHssYv7jyGx5KAACSCH+9B3Bhn6Z9luHRvf7pQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.18.tgz", + "integrity": "sha512-lIDyUAfD7U3+BWKzdxMbJcsYHuqXqmGz40aeRqvuAm3y5TkJSYTBW2RDrn65DJFPQqVjUAUqq5uz8urzQ8aBdQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.18.tgz", + "integrity": "sha512-apJq2ktnGp27nSInMR5Vcj8kY6xJzDAvfdIFlpDcAK/w4cDO58qVoi1YQsES/SKiFNge/6e4CUzgjfHduYqWpQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.18.tgz", + "integrity": "sha512-5Ofot8xbs+pxRHJqm9/9N/4sTQOvdrwEsmPE9pdLEEoAbdZtG6F2LMDfO1sp6ZAtXJuJV/21ew2srq3W8NXB5g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.18.tgz", + "integrity": "sha512-7h8eeOTT1eyqJyx64BFCnWZpNm486hGWt2sqeLLgDxA0xI1oGZ9H7gK1S85uNGmBhkdPwa/6reTxfFFKvIsebw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.18.tgz", + "integrity": "sha512-eRcm/HVt9U/JFu5RKAEKwGQYtDCKWLiaH6wOnsSEp6NMBb/3Os8LgHZlNyzMpFVNmiiMFlfb2zEnebfzJrHFmg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.18.tgz", + "integrity": "sha512-SOrT/cT4ukTmgnrEz/Hg3m7LBnuCLW9psDeMKrimRWY4I8DmnO7Lco8W2vtqPmMkbVu8iJ+g4GFLVLLOVjJ9DQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.18.tgz", + "integrity": "sha512-QWjdxN1HJCpBTAcZ5N5F7wju3gVPzRzSpmGzx7na0c/1qpN9CFil+xt+l9lV/1M6/gqHSNXCiqPfwhVJPeLnug==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.18.tgz", + "integrity": "sha512-ugCOyj7a4d9h3q9B+wXmf6g3a68UsjGh6dob5DHevHGMwDUbhsYNbSPxJsENcIttJZ9jv7qGM2UesLw5jqIhdg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.18.tgz", + "integrity": "sha512-kKWRhbsotpXkGbcd5dllUWg5gEXcDAa8u5YnP9AV5DYNbvJHGzzuwv7dpmhc8NqKMJldl0a+x76IHbspEpEmdA==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.18.tgz", + "integrity": "sha512-uCo8ElcCIAMyYAZyuIZ81oFkhTSIllNvUCHCAlbhlN4ji3uC28h7IIdlXyIvGO7HsuqnV9p3rD/bpH7XhIyhRw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.18.tgz", + "integrity": "sha512-XNOQZtuE6yUIvx4rwGemwh8kpL1xvU41FXy/s9K7T/3JVcqGzo3NfKM2HrbrGgfPYGFW42f07Wk++aOC6B9NWA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.18.tgz", + "integrity": "sha512-tSn/kzrfa7tNOXr7sEacDBN4YsIqTyLqh45IO0nHDwtpKIDNDJr+VFojt+4klSpChxB29JLyduSsE0MKEwa65A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.18.tgz", + "integrity": "sha512-+J9YGmc+czgqlhYmwun3S3O0FIZhsH8ep2456xwjAdIOmuJxM7xz4P4PtrxU+Bz17a/5bqPA8o3HAAoX0teUdg==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.18.tgz", + "integrity": "sha512-zsu47DgU0FQzSwi6sU9dZoEdUv7pc1AptSEz/Z8HBg54sV0Pbs3N0+CrIbTsgiu6EyoaNN9CHboqbLaz9lhOyQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.18.tgz", + "integrity": "sha512-7H+3yqGgmnlDTRRhw/xpYY9J1kf4GC681nVc4GqKhExZTDrVVrV2tsOR9kso0fvgBdcTCcQShx4SLLoHgaLwhg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.18.tgz", + "integrity": "sha512-CUY5Mnhe64xQBGZEEXQ5WyZwsc1JU3vAZLIxtrsBt3LO6UOb+C8GunVKqe9sT8NeWb4lqSaoJtp2xo6GxT1MNw==", + "license": "MIT" + }, + "node_modules/vite/node_modules/rolldown": { + "version": "1.0.0-rc.18", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.18.tgz", + "integrity": "sha512-phmyKBpuBdRYDf4hgyynGAYn/rDDe+iZXKVJ7WX5b1zQzpLkP5oJRPGsfJuHdzPMlyyEO/4sPW6yfSx2gf7lVg==", + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.128.0", + "@rolldown/pluginutils": "1.0.0-rc.18" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.18", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.18", + "@rolldown/binding-darwin-x64": "1.0.0-rc.18", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.18", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.18", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.18", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.18", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.18", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.18", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.18", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.18", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.18", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.18", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.18", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.18" + } + }, + "node_modules/vitefu": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz", + "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==", + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.5.tgz", + "integrity": "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.5", + "@vitest/mocker": "4.1.5", + "@vitest/pretty-format": "4.1.5", + "@vitest/runner": "4.1.5", + "@vitest/snapshot": "4.1.5", + "@vitest/spy": "4.1.5", + "@vitest/utils": "4.1.5", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.5", + "@vitest/browser-preview": "4.1.5", + "@vitest/browser-webdriverio": "4.1.5", + "@vitest/coverage-istanbul": "4.1.5", + "@vitest/coverage-v8": "4.1.5", + "@vitest/ui": "4.1.5", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/workerd": { + "version": "1.20260507.1", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260507.1.tgz", + "integrity": "sha512-z7JhsFSe6+X1b5fUHaVpo15VM1IRMJiLofEkq8iKdCo+Veqc+FUg5lIsuz8NwePxuSKrXtO4ZQpGkQLbPVXFhg==", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20260507.1", + "@cloudflare/workerd-darwin-arm64": "1.20260507.1", + "@cloudflare/workerd-linux-64": "1.20260507.1", + "@cloudflare/workerd-linux-arm64": "1.20260507.1", + "@cloudflare/workerd-windows-64": "1.20260507.1" + } + }, + "node_modules/wrangler": { + "version": "4.90.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.90.0.tgz", + "integrity": "sha512-bmNIykl59TfCUn5xQgU7IWylSsPx3LQaPLMSAq2VQHt89CBrcj9qXQ0eYfjBCWA5XTBVgten391evt7xxtXwcA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "@cloudflare/kv-asset-handler": "0.5.0", + "@cloudflare/unenv-preset": "2.16.1", + "blake3-wasm": "2.1.5", + "esbuild": "0.27.3", + "miniflare": "4.20260507.1", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.24", + "workerd": "1.20260507.1" + }, + "bin": { + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" + }, + "engines": { + "node": ">=22.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20260507.1" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } + } + }, + "node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlbuilder2": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-4.0.3.tgz", + "integrity": "sha512-bx8Q1STctnNaaDymWnkfQLKofs0mGNN7rLLapJlGuV3VlvegD7Ls4ggMjE3aUSWItCCzU0PEv45lI87iSigiCA==", + "license": "MIT", + "dependencies": { + "@oozcitak/dom": "^2.0.2", + "@oozcitak/infra": "^2.0.2", + "@oozcitak/util": "^10.0.0", + "js-yaml": "^4.1.1" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/youch": { + "version": "4.1.0-beta.10", + "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", + "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@poppinss/dumper": "^0.6.4", + "@speed-highlight/core": "^1.2.7", + "cookie": "^1.0.2", + "youch-core": "^0.3.3" + } + }, + "node_modules/youch-core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", + "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@poppinss/exception": "^1.2.2", + "error-stack-parser-es": "^1.0.5" + } + }, + "node_modules/yup": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz", + "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==", + "license": "MIT", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zustand": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.13.tgz", + "integrity": "sha512-efI2tVaVQPqtOh114loML/Z80Y4NP3yc+Ff0fYiZJPauNeWZeIp/bRFD7I9bfmCOYBh/PHxlglQ9+wvlwnPikQ==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + } + } +} diff --git a/apps/admin-web/package.json b/apps/admin-web/package.json new file mode 100644 index 0000000..13ba458 --- /dev/null +++ b/apps/admin-web/package.json @@ -0,0 +1,60 @@ +{ + "name": "admin-web", + "private": true, + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "npm run build && wrangler dev", + "test": "vitest run", + "typecheck": "tsc --noEmit", + "deploy": "npm run build && wrangler deploy", + "cf-typegen": "wrangler types" + }, + "dependencies": { + "@dnd-kit/core": "^6.3.1", + "@dnd-kit/sortable": "^10.0.0", + "@dnd-kit/utilities": "^3.2.2", + "@tailwindcss/vite": "^4.1.18", + "@tanstack/react-devtools": "^0.10.2", + "@tanstack/react-query": "^5.100.0", + "@tanstack/react-query-devtools": "^5.100.0", + "@tanstack/react-router": "^1.167.0", + "@tanstack/react-router-devtools": "^1.166.0", + "@tanstack/react-router-ssr-query": "^1.166.0", + "@tanstack/react-start": "^1.167.0", + "@tanstack/router-plugin": "^1.167.0", + "@trpc/client": "^11.17.0", + "@trpc/react-query": "^11.17.0", + "@trpc/server": "^11.17.0", + "axios": "^1.16.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "dayjs": "^1.11.20", + "date-fns": "^4.1.0", + "formik": "^2.4.9", + "fuse.js": "^7.3.0", + "jwt-decode": "^4.0.0", + "lucide-react": "^0.400.0", + "nitro": "npm:nitro-nightly@latest", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "sonner": "^1.7.4", + "tailwind-merge": "^3.5.0", + "tailwindcss": "^4.1.18", + "yup": "^1.7.1", + "zustand": "^5.0.13" + }, + "devDependencies": { + "@cloudflare/vite-plugin": "^1.36.3", + "@tanstack/devtools-vite": "^0.6.0", + "@types/node": "^22.10.2", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "@vitejs/plugin-react": "^6.0.1", + "typescript": "^5.8.3", + "vite": "^8.0.0", + "vitest": "^4.1.5", + "wrangler": "^4.90.0" + } +} diff --git a/apps/admin-web/public/favicon.png b/apps/admin-web/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..83f0a8cb9c09b3e3196e341283471f3f9e5c70da GIT binary patch literal 81471 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

$pKbm?N%U4 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

$pKbm?N%U4 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 c|12U0jPxk>V674#kVRySv-sEWS7kT)(^j-Q~S` zzezH&m%K?bnMA9r%AunWqW}N^bOm`CO#lG)9}5dWLih)_-V4wF0M15IMG^q0OF)I1 z!T*a>TF7gv006#p06=gU0Pvqk@G$@YSq%8pMe`Hku;eSE?AN^P6|KNw;F#jX{ zFYPz%|CNRX{QmI&`TvRuc!m7^2gok+`tAS#D$aid1IWrI1OOxe3Nn(~-Y{pKUn{Lv zfn=Ujt#@bDf%U5@n$*9XV~ffVi=!G;qS6W?59DLQd8%mT&3mHu6ZDW_1)h;5KFW)o z0T4ix@}w&vVg-a8$pUGP3h|$kU9dF%N-}=j{AtyU8&kAUlx3OxYU-uC*hy~@Cpc{A zepx?V^>tClXt8Pwcxh}uDR`KX(0DIqpXYZ`b$6P&XUAOI^|1XuM>cKZf75it_sjWf z)$~@^D!FLOmeb`HIoW2r81QOs(bEs3sK%(O*`{fIG5kDc@6Kn$>8qn|=@NL+HyopT zWeVR|OiGF~a&y$aWE zPdFE&n-sT^^s`EIxF20R3Ke6?ew|xzl@_yCA0KwsW`zsHfjRV%bVw6Bm^E#32lK<& ziWX~|LK)CA@G7#H)N;^b8ztgHpcnNA<&mdLt|R+^(hPSEIigTgw%rlVXh|vB0|EDV z?Bwi-mFsZl1WS`ra+)x>;t}3ZfF=rFEK6O43_-SloDCuBqUsp^@NW>DKKSmWu4ecr z_vk?X*rH1Yt^g>e&(Q9Gozl>Auli$IYo}eVptEiO`AHUUsrYaC5*jGCV$^(+G!gLc zA6U#iQ+e;S6RyX+h)|nes7Q7odC@dBEFwX(9C%w6$wbJ&vHPzvnMj-QzX{qn+;Glo zJ#RYdg3db!pl~Q-GA-F{7CGh#0 ziFXSMxj%RUiS`!Pbu0QI44_UuFM=hx3gKq3)&9{x*t;rXcuK7@#6o14(x z!lm{em4-dN?h$yskB2eXqHX`P@{B*_2|akH1#LDu^a1PsJ0gMAhD7l#dgR+#>4eoV z4$t$=XUwoR**Q&q1dm|dNhQ_W;UUvm;yb#Z< z6oOiqjNv?sp+Yt$UZ~_BLi=77e!!GPSoge^nDi-7VpI<`zu9S|5Cg5Z(Nu(plNr~@ zLs7u6e8?Em0Y{xexd%v9{*ytoC{jZ-Y%VmUZ6E#S5hhAq@E$jqFEd(D>1ok4%f&`c zv`*D#BE3UE)e=TWebRFl4CH`a_a2gHXC%^J z&y_0GM@wMbjfWD)fgw=x{1a&?j0yv!j{=!=9;yk6L{p4a9+O z{R17=d0~xx=LcXZ&@XD<>TH}M6vVmV|BltXYhvuo7t|u^{&@V1>j@k5BKnTfA=kk^ zESei=ENE^8)u`@A6!ScVg16t+`umlE-@S+6U8L`Y+%40WK11ihf@-Bfp9r3%gZYWi{Edv1RTSamBWoM4DkO zR8Ap;C2=1W!R9j~rjmYS&F+!XBv&ATgc1^k<6dX6M%58ovPs2hRsNXatp#|Pu3F+r z5Vp;j!$<}bJS?J!!>)+IpUs0OPr2pR@3==EVrN8~MGb?9|JLljK)hpjG@z9Cql?5xxSdE4isnO@Y3A~Tg^#LSn8``mT~38qjTWc(X?B2Vr_-U1Hu=eF z#-H^13YQd7+14%EnsU$~Yv$jdGm(G?M-S<9Xdedqd&M2aZ;Z!{o>MJ3@Hu<+@~`b~ zf7jQF3RIgsqt`=E&_B`?IM#>sNF=zN7f2U&3`39VDnHJQo`_Nv#*Ol>oLO!z4q?Y6X@WSI(V? z1peYOG79o!GJ>ZS;q`2;Ho%X-C1sx}B%g)z2p=jw$m|dGp$zR&-aZ|n*EVXVMUP=N zu0>wB3}YmzG$Ay9m{R5!6_b>RPAFoj2oFG#_^0ZJoYhzwe|6NAfm)VB*A-k=dt&}+ zx=N>|-$R`iIh`IkQt*vTxSWgqUn&$nqq14St2dOvUexZ+EE-HsN)`)77ruP@8aK*yNW*CuZu`~e@Y!h( z1sQ0|%Y0q5r_N<`GBJoWWL7;fZ41kFR4cm2k0x^JIVAW%IPF`T@<1ugZ@yd2tY_nm z9umTh_}fQbcyI=!>OGL2$2(WBcP6R-^o`t#j7~AZ8apAZ-=f7fa7>eItB=rV#ejfO z_TZ%r!zu5fR3&#xGWH6m$u+28qRhLL3;H0E0)ikc=>-tM2VlIa6$ZdQY~`(z zR(5v?0^c+_9XDmu%ihUk(C9pd*=!d(DntYBsY?jD&<<7PTTDsxX=_ zH>w}My!U#U-fcu*@>|S0+=luY+co}9Q`{SDDrzVCORjb~%}xQ{n6hZhu5xU5i0@Xg zh-{wjlr9mwfQvpuN#@Z9&YpO7s+IJ8I`8nwe-Sq;s4CKwE1RN!vE z%yZQ#-jcDa)j_OUUcbd%WVa=_b2{`JjPYK*;W|A=Gh(-&M~kn&pEq`UkyfcLruYro z7M`~+@cmVe{ec48Qbju>eG*w%Sj6Gv&uaE7B%%B1*d<`O7h>{~dv5(I)X@~Q^R03B zE7T@LFw!d6k&dYdHf00rf#33YK$k*|L}A8rhD8`M~=kx!e8P3l~Vm7k6LZ0p6o4{T## zam{4nOZrQEAO$Li%p-4p;T?-C${#b(sWxbCpqk}Dj2N|0+!N3$_4yt5Z7FSbRa4U^ zdqA#eBbtQogW8wLQWSvt5_u&u=+;IimtZ;w-`3)`?-#m9={E*jy0~ z;AR{^ra2k}&@fnkl$l@xOh_`CexuKnt^i-z$B7?Ft1O7?31Il~xTFWf0KLh3lI;mR z`*8`axv|v??uO(?6{v?LiR1gJq3AglH0FUTh%;=aRmDTez65xHGRZc2dDLcF3J-lvI!2(|AB@3z$OYcefw^-MY;9 zwPgc^WRotWdJJurdH$*ivWF7$i(eEQjjq?xw4&DFUAA}l-j7#Myftnci@rzKROR|% zkibAoddJVCL)n|rdwlOs)Jz^hy{qlD~y#Il=(ednC-iXjEsPMM$lU-Ds9XfF@H~>@8g3Iz##{L$aK3M4z&b5A@80 zx_6lyW9;QahtfXr|6w-FgSA3jL1P#xdB$gO6)F(~X4(tvsT0P-s~KQmM*BI2f2k|t zq-CVd#_18vtxSlCqT?NYTEMgCpuEpn0LWoj!o!weEy|XwSM900HGXRiZyQ!tc;J1m zvd#=#wPHbmzmNOIkE^&xsKn+@$nwpPUHV>nM89omCnT~=vq}Qn~NY|N6 z!wVCFgG*1f_=lkXPoui|vY{&j9AvPgU^-u&k$#2n4h)CeH5W!1PupO-pgK7-PRgf8s$8Q{r6H6F)IRil8+2q$Xh1uUXC@Xd7?YWizkUpBb1BdZaTMvQ?EQ zrEe7B@&}TX+ScyAmpHiqjI%8@wRIU%7tCirWeK6$3o1J@@L3jQqD7s4-wbT0M4IXsXijTCzu9UI-1=Bg$huEo zmj^k>DB+{;d^uYo%ilwooV{friCVn;j*xT3FW9alv$l4fZ6lWJYPd{g;X+E+6x4LV z-Xr9%YDRYOStEyX-9`%m6|h(XS((*T+JKe2W?$W4ATrMk+uTzm`}~nU5q%h^UEg2H zcaZ^acy+4G9O=VL&atq@CC&o6CVvP+Ir93OB)7w6NOK~qH}f(f3VoETZ7X{i%Y3a8 zbjy0EJ>|uCy+YkVx73|8TQci$_UeASrzWD?=cTcfT;Rv>cp(L}cw4Ze_UY)c_qx6! zFOWUZ!{v;r6=j$o(HEUPj-P(UqNDoK=PlZOn!Nh5xAd{wuYJ{@zV>plB;I}qwbmFw zr@W*Z_JX(}JVih~yQXE3l)Yu6=sX4=#Iwhrx9{W8o;WeRg{QUk5`r_C!kkB0h+lqF z%|B`piD7o0pw&yKl4Y5Xn)upsTIu7zNSCM9i7QLx-R0JGg61h?C|w&_1z&EXr3ToY zhUq1Nn@WO%aZ0;4Pa0*cdBcUP<1HNCun;;bXUgdvD)>*Ql=>d z5*JZ{)M7@(XF`Q7nNA(hEi>nsTo1%SR&8Ucb+%*^OPUd&C_71pTA!&Wk7xmCHR+0_ zL0vO2fs&V;bJKc(1+9%dC$$!yxqa_Zsc89w%{ab9Wpn^Zaw4_v^XECb3 zHcPae&$&CiA(gd3MVWfy`(X^6HeRwA;O)jfLYj9Zoz8^zp;+&#bYuCl&jyYGs%i-V z|2jX^<(sY&_d^Ma|EIMh^M-2Bg}9Qtiwx2spYR$&JFh52?sFpL)|bhQ+iq<*Q6B}T zo>?=*p^II2WX7aDs&r9qTa`EJn4i_jIChrZR2n#bgAE|ZiqVoAPzk-**=hrO45Nfw zx%H29iI>vwHm;u{+*)zn?D#zt);GpP{H5CH)r=bQL%rYuB`$sL%*Lf#>j}70tbU%1 z0|&T38qq(f`ri3sezqHe)X05c1PNI(*L2zRd%9nQs9)SI#Ti_%R@fOewZn(>8foV4 zklU}RQB<%}A4pZRUJ30;V}nv8W(WMy;HL8xl!ROKm||LQ$=b~fmhzQmDczj&{M=iB zqZ|<@wK2~l{J7PwwQB5T=9-aF=A%A65xZ7I@a2|r;E$gO8xs$^Lzc&jpk|h?G{Xr z$;H>s6Qd*DY4T0ar>m>;m0z6--BZm5+u_sSHZqsb-vqnz>!q6w#U0d$zq>j)e+y<8 zYrXt=dxi`CSlH8dX0SZKQ`LXKDhWQTw@tJMPl3)jW3M6vyP8~_|KQnk<`t3X{ZdAeJ=s^#Q~2E%-&6G_tyOX9zU=AMh+Wl% zLTX;x5St0qg0^R^A)=2S@68s~7lY1MCc&!+IFZqrYGo!N9-rCkm-*^c?y~7~vkQ$O ze^SRs$9gF#==K*WiC;o_qWGFu{Y`{IQ9Z|w0`UuuoSI`BQPV7`FA^2Dh4;`tw26Ac za>y=of_Q~;gH5Y5TowC3rMjW3M@dhN@W=5=%RWrqwL?CtgeYP<3&|Q%Gi3z#TEgNQ zIv9iE=L1?8dzR=Ey=6uO<0YPi`kYEhAgmwIf-aUk9uX_n@$S4BO;u-M3{%}~1$eaX zm^9D%P)y-!BP?~3jhIiYJatPWx|7?9L&UoYjE8>}NMjfTMsoW-ES0ppUmIHxxO$&< zMv_V*0QFf3)C`;hjH$2{;wm+(!Ss2a$th})$$Dt2su+dBxffcC7ay=0k_6u^b*~)A zC|(l#4Bb&r^`>#&C+LIgwfEe&J2g#OV z9a;J>4RJOy%UwvE!?DJsZFJROphIpr9~q+wvkc;64Wq-$<__~P4^^Npr|bOc_>A8PbLn!(*}03X z;(alr3zb)gzjDBs)WMx`ME7#NwN6RMypsRzi>;08^_L{CtWIpM&*Yma0mk-9LLuwr z>%7;o>p(1wjIATC1TuY!_RFP=udTq!mn8-ZerpqQzgyh)l+JFM`beqj$=UOX<@4viXyEr_*(JAG!bT)!d;{-s58ZJLsO`jTh=1u|E9!mmo1* zvtmtYK*a!0^atVAyRSi@S?;_iP;2CMDRCD@_r*N{r5|44;H9TB8b8Mdk6ga{kpR`z z?~(!`?||6b&aeAjF2-01dyJf(@g=u#!}gzm`}Y(J85Xv@{?mfBR_MB(0)WEwmxq{N z{@jWfnfSIt)$6tj_OZ7E`3HXsc<=WUT`zx$5y9p8&qWn>9Smo<*Cu`_56vSZ{V3Bs zm4<$=X;wO1I93lwv@Z78G5aQKv-TE*=`VC+~qCp}sqcHEtn@pUMf zBl0&E{kQMYaCA!kJQ_(JauE$AytPi|U&Mk#2aB>{W9XEXC9wOE%7u&;d1Ph43WYvG zH?Ms_Njn9lA#bngOxDf_d(39%mt&4vOLDhJMQis`6CfcbPEUbu(%%y!g{2sAKfM-d3O+kc91`b##4^ z#yXPn(|aTOv5TSx4N>09v%@~o8Y{<z`aMIU~dK#xyn zDR%O3x5oKsx*7YwK9B+4DueE3%GbpnkDE!W)kK54mmZ|`)E+EK$Yo})37|`lqM!HgP?LRXB)_kt-)TwOzjJVSShT#zvV#RHKGff_=6V*p zl_ncXzsv9-up(fTD%~&-%rUOAqoDDq!hkDu$xxm|h4E#=8C2yxUGQt+6ZN9K|6&-C z2dup0cZM8&vPrw!zYm+q@4`r*2;(L+99k)v=hq{skXL$S%2g=+!U=og+Mz_Z%(4zf ziu3b$k=p*C`>mnemjz2t2E&o;3NgH?0`(EX@{RqUMxMRD4sFg2@`W_Lztky-zr2}X zAF=wj0r>&m*WKXz(kb!gPOxxOMQC%CZhBWx=h_D6>55IQrw6`y%mx|$#b9;%^4O!k z2r%oRtG*Ft%@C8CtR}CY{kELj=Ip!K$$=Cmk@nc_)aT{-Bu)>f9IHWeygQLUg-O}) z&ZpGOpbReuJ^0Dw*7I1<7R5?=)vHjaTZ~Xdz(SZBf$0Qn{2J>MSr;z6)KGE?=|E<_ zP9Lp0*1e5Ap@bJ{(2(vuaJ_P6a*^H`lSi{fOe56RsDf=Vt6CcW9E@3cU!*N z>zWSU0uF7bLuHLa;hOMPlw!S}W8l*E0!&nwVJjMOUlgU?X<$QHw2+3opKaYiI8`+@ z?UXSwUnzdr=qP1r%Wq2RCA>^?g&Eq0%^y*4isXDJe?@Ep!&2u0>%}-9dij>jT?!7N z=}ywtijx-b8jmQmlKl zD<$=|uN*_4%Ex7DWqo#&cZ)3*R0ppdItRmk+)4Gl&E#TUE=x1fQ|=3`rIzy$o)?w~ zjY`$StwWUg!R0yB5y*#(`BJ`L?j{34Y>;1xuiQuRUsqWodwuGCg-16lC5{Qg=hj~n zM1iNdvC|ISh`^!CyPECLU!YEg%@4s>1kEUad z>eAd(0aGF&tv!>g&IRz(s(Yl)sQBMnT-p0~3wk5yLjrgC%Tjyz{}`m8MO?4SVPjY< zv(h3Ltp+P=SIGv$#dxvYYx`}*)zf|agaA>nRVkyURT_$Pir$NmjGqvkptmX2`NTmmY4G|D4y~w{ zw{uiVVbWpiC52dxJY>+K1{5xu)29|gQ<`FBe2)$MC~^i!&IB!+4k*P`#(;61B1AG= zFuZuPkw(sm!%%noWK`8jm*~4di{Il*i@Kidu%$?1(*!8p-Hh7fbjRp$_*g89uN&x- zNI&rZ#;Tvf3HeP`7ZiPC*=>{tbScqP_)>130;UhN+O#}rqx*WNSfTe-hkbLLP;{Ia zYrAHQw86qL)jbl$V%$Fu?Y**<7rpYrP&FUiSfQk#ODJLiv2)IK{EQkqPt0^D#alS% z;(2PAKbBP&{9Ak=3`(_DV|vTj@P0gTo*s0OSt@=vaC#I7N_(!8cnf-{zjd1X?^GXJ zD(>g%zWWq=L~cOgxRqcYNI-Y~3LS|})TLWzz>i6~$$TVLU(2L~*$lS`Q*D$gc zKSiRC{1P!zg$(Frl+_`xs=9>e$H8ZZt>M1@(Mcm{*L_x2+FaYeec&-=Yk zmM>ZqvR-VdKHuWWp@M~7)VsiU`RCL>z|gYq zp=A$Vk^R^0;sh}XR( z(VLS*6DTh3-+NTOUy~9lmxAt00`GhK`}@829+=;`tnXMKhk}+{dg;Q`EjEzou!Ve8 zkkoJ&&VCniI@$>Rb-9Nf|HSlf->#?Uqy}d6?fHPc(hl!;&Et&;FA=#IF2?>{MSf6f zU`CvWzVS{8g{XSYA$r2vTs#uf5@)cEWA{7JhYxgxvQNb7OAx8++1AfOiv)qX>YccU*Skfhc7I9RSoM0lk|s}F&URBWysn~qAD?dEf%xwM9&ihp4cfKf5HXIEQ*XrVoKm?3u~P#ab1uokroaZ z+8WXrwySgMG<2~}`cxZ7R%qDs`?8v0iP!LCsfkpMhd0KiiZcvs&_^{8!95m#P>=Gj zefI5<*J}~QUg>g3wIXW_u|Ceq^a8s95{xd#QQ!3kaN}IJuK5|`CXU&9Grr!nY)RRq zWq8(3)=2gs$Wj$sxzS@UCkZ;LdmiNRC56fZ7|`GiPCLLc78~!6v1E(Xzp{6yNlf`$@^gQTl93$ zu`~l*j0y!mq~(*?hpRS}By}doImc_24)u3wP9*2U#*WmB`4=v`R z&f4B z6Ahh?l}HUWIqa}qWz1hb4ZV6~phG~|cdoeQm5-w2tP_3e*DGwFKcu;O^g4-Gw#1Ul zspV-7jCK@}a)nD}p~F$(RY+o`@O# zrTLvWhJ>i&){k`zRCZA9l}$U9M6I_X?6lIvBxIUEE8Puzze#r{O4K6iyLBi zf*yd-&k~^xQ{wr&0@*4ozd@|L^^kfVUK&Qad(bV^Pvz4X^q(&a0ed+t?90GPg0^jq zugoo@?OO@ql#Xlo7$hAIq1>W=nGEa5M>|3#IJ#H944vxh{}nXfoR`aa((X(4$Q-Mf;q2#9_Lo9i|PT z(V=&(>>>|d?~j*5&m32S&N=h37et>8x8Di6ym##h@>*RUp}XCF4Qo4>j})SDvB#<% z7ki`PY)mHVKxuLPqU^yDR(4G_`&Zo_KcAaWueVEJK)zWoBR-Z6OLgvO887^m$%t|vTKN(rUn0&-4yzOD@+0) zD(NK7IVE41)T)}HdeB6ZpD1*82~ET+z`* zLulHA#7RMOSV?xvzd=<`W+6fZAi@;d(b)!kNldZ^!<%~xx>EwHFUtOLl63I6ZzIg{ z*yyj*7AJeh_QsafWRejKJc<>X`UNXLiZz&2pEr&B9+DZR<@mvca+dG+0NE%doku2{oyqmhYNN==ZMt>oRxz(IVJT7hqF0`GNB=zeSFtH z9o`Fm;$(V<{KD&P@_vDrv>|=)=WsIvo1aSRXwOQjvKUME=SS^7Z z5&VwgHJr5C!Dnu)uDG6XY}!CkigR}^rbfrWr$1e$*4EY1={qJQxmz72qO?BeEsh>@ zi^NQ0ks%~1^<7+}1iG}E~%M)y;c#R*F_DYQZ-3ObGmk6|hH5tu1 z)3=P!z!|ok{06koIO13!f<20m0#rEAgv|VSw2#qwuO(^qc{4H{mNh?Gp5ei)`GftE z|AQBa1O~LfGa=0}p_%RKizZ!@-^=Nnn($V!yC@n3*%scYe&4PUZGR;+r@tz31Z3MN zy$*S3$Ui-g$cg=ZqX;~j&V3&nT)ztGzU%&hsr*JscSCah&b-mOb+rujZkfp*$spLq zl~P0UtB+3n7*m~GnMdpu(;4iM*-V7lI1(54P2~FXFIS{2DAJ0ZmwA$@Oi0eh{nQDu zNrxS%A?BAvyK0X?j*@9JNNR7RXMmw_TiyB}dsq5&e;Yt(Zc<~5>@rqoPYJ8Po&!w; zy*?zt^j3$U!vC1Z?g(`}E~%8vGP}R_;Di!uv-tMhh$ zCwe^@z^h#tt?rKd_fKAbl3r+Z*ezetq#FjuNo^64j4L*G`W31RgDc;d6NoFKp_S|k zR}q~JUHWjX?&?@B%LkzuE_-@L`7X>SyxwHg(j|UY$l&V`zF27Y5_Qr(QA?}b`t$+K zbuBOdzAYCEE_b8{g~@?>xgvtF{>S6~M##zrc}1fnpUha=6UBjrj>I*lnhh!2MhN{wDU7OWHT; z);^chf^Aa)t9QMPw6pfyLhjS8 zi>JE;uXih2AOUCX_P47@@s7a#B(KW%-QIQzfsNd^rSsXt{uTUA@`R#?{QJz7@ibv! zheoQTe`6uEozNO(vMaYMnu?cC8!EzY=f7=fUz{@1sY7wL874eJihK|z*LrUqho~m< z^<6twLM0L_@l`?mVz(S?K4WTq@UW}a+EJeAH6F(@+SZ&x$pv$V5i(n(uIXS#s+i-A zCrwd|rydUQnBieVFcQ32cj3=3#Z>%g!2OQPYkrYJf=1M!Go?(PER%y7m7%Xy8VIU_ zkb(RbngT5OKWwqR8e{Zav4TIW^6f?#^y&}i*t5ATA?fwe;+&i|^79gPs0{-AM5>2J zk7s#zic@F=#2-tS2cF6sx^qAVe$|LW`<(owMAB=I1?f@gsD1eH`Ec6bBph~PDhBl) zPm8E1PF|6m=|PfndXc&Bnm-0a$%={Vet0Wo=1FEQ(5G4rKcu*y4_CzlrinhVrzd@m zUOPysE>$WYq#<#)1}rXU+Z^=$SU5hNlLjkA-C55Pr5)kxQLiGA3#rNUlE}G}Zz{Td zkkw$J7OvZ-}2MODEhN~*3`rgft|Dbxd)e2Or(pJN+tQq04pR}O`AJ{AB$e{0Z=l~m$R$B#J(43Z8)Ac6AN^J6MX zHU~d@$2-=BSI@Ey!|q2!x7_vhBARp{RCm3(1Uwr(;`J&8z3K*DoV*{&wp|M0FqX42Owu@m|)DQhKwk16TTt zc2=hj?;Y_%Cbla35vrd{EFnB>9*m)oKs^1Uw6f#r7E7n)c@NXxC=g<_m3Xy~yY31I zgv{GNk0h=fS^QHCxwxqQkF+8xjzZ)Dl!!B?uLe|(fuyhYtpMRmSxh}K0{xBVj3R5n zgdAWEKO(@NKm9K?-PxUF>Biz$UUO5!6PrY&!^Y3l)8a289Bh%H%pOAP8bkVUi3I6+ zA8}$M6f&2q8g7!r+!a1Dps7-Q^jZoRXZ`&pDk^rKOw{xn?i~!TX*5L3d_P5>FS7bu z7_oy#fxg<@)o6LVUYz35Rru&gmK-gO@?c7j#vT?2T3EUK@H|yymUKJgL{#b@d37i$ z#$QULfgM?PR!v!&5dp=Ye=>Q_2L$?Cs;VmCJp^vD|2Cx&D*=*-%S)C^75vW=Ia_~H zVv+86Wh>!bex!r@vE08?^CSnWvq#O{g@mZ%dVcCKrPJ5H=VLN9n#IW#OI}j#(9~;g z=_ZrRjTEUO8k>Nsp=?+qX^VW6I9^2INqkc&hqq$7#8!1Cj4mjnOCvo&Vc|BEzK@4n z7^eE0cHAq#f}FdCGQ_sJ$0cgpyMG&5pbcsv@fxI-w+0=6)c*Xw7DHw@h-GR3x9m& z_wXs{aM$d>Y~QE0?fd2=Ktb?GNKdvGcx1L6;vrZEamAT*r}aPK2)`ySJ$||eN zj67I4`oT>Zsb-Ioj2!%+ckrg?8z3|5GjrKLCDrQqU?vn;-fiJrKn8DkK9$D>$+5wx>>l-j8b{hm3u#0bVAUuRG^tO+~3)W z2oD>+48{3yE@WwN*hMU5cVS+p0DnWWP-H<@jso@q^6;(!0#`y1f4A>#h6tI-msV8F zn8a-v8Ft8ZyA)zi`^mKJ`6K{>o+P7md>krcvDf$1peKrem)YI>b z=b%)5@vGUwA2AB_2~AlK%EQKK4dh>k3<_{E z4WUuE3OL74RFTg-eX3i6;bfNq~c*-vioIFL-SjE7fMU z;i0^c25Xvl9Fp)on9;cjE~DT5KteVL-;Q3|g!!H%ZJ%5B=y#f%i3P-axP>}6O7^cz z4KyySfZ$>z2U7JyHFW)X{x^#CuNOS}^D|Gi3Xb0-_S-+%DhX+vq~?sIbtk2n6Bjfn z{y9Ntu?lFci=>F7ML-}z+jAk|N$pP? zLV1z1zs68Q)4Gi*#CG8zNDOEP85e(Yq5l{_E&i?9Uqdm(R{?sReZG;(X*9)qbjf!4`qu*S(%&{Nd5L2i87z*%-O@Ouc2jaS zM9#k@ov^)?!h+lRshXg5y>sDts$zK4Ql8t%(U%tx)#mV*VQc(6Zwzx+ z+rP)+;Q_r?<-?`c_1c6@e!;I@H;D5a1%*!9-F^uH{t4FPvxahDBmKb`bhP;Oy3{Vj zJPe=p-Q5Gkw?mpsf$`)QnJ+xj;#fmU?X z)0Ou?Ley=%%8XkXxTR4xl)cg9pH;`30bCQq`A%PZmp+jrPJ~kV4B;f>73EwGASC1g z9xZYxZs`NxN;)AMMCzvz?%$C z85ZN@#9&HG$pJ{uSH3fr=rj!G2<;z)<>NH&_2ca?7Od_!?(esA5 zw}ikudiGIq1hAON6E-{8Ys@FWN~lhbYGf#^}sPArpbFn>uv< zjWe7e7IvI37)2rO@B(Ovs(|O|mCk0qPwTc<{hs;!K+bXI3hmDt+9&d293KcHghNk? z9_DQY3*7voE^B(9kCqX^-9gu&@&kRC5ct<>QCiA_h1f+KLE~lc$-*mmHS6KC z$|-U7qd8{Jm*hZaoO`Wd;%S5M#dlJ^WAOm=>;W!ye=0 z%Elm!eNJ*1YjZy+#^{#vmMvQk3^yRqG;`RPB2T`?OK+oUwjL_YIhzVp4DCOHx}X8C z2O{FdIV{ldGAr^(tG;hk=h(Ed%Xk=mmP`KfF;ew%q)5j_(y5*{rwEHGm14V4Pxxzm zh5_#A$s|jeRzYd$E;d~*jVR-Rh|mYHUbC6DI~_J&s;)FAF~qwGmnys=i5(4&>7Hko z#{F3#I?ghEbsXmACu40BZllPqOl7bSED|RIVb;BU_4i%vKrM+iUut48DH63pw_Sr) zICAcbvMS|)V4uojHAfkr~QT&o)0|TvqtP z9ZPaH%0cW_sscKnxEm{F3l6sYlN_3-Q!9amrny6HKvtEK&*bm+AW~?8wAho$L+$ay zY#QQ3M7xTYN7J~LWah9P;h}Sf*A#GEu=jD;OuXG4-pYJ}3wG!x6O2Nujj*@kFnTQ# z&ftrH!=l4xDxKuNiF{g!3}>^8p6n333Zbd4L+SUHW;RBhL7;m>ydSXdyc2P&E}>3V z`t$7D>k~rfQ$2sB|GwDX+W~F9?CS)*af3sH0$m_D#QnB7L6h#A6Cq}o-csw zfSEg*1d+dQ8_QiU_y3&60x7lB&dSO``oda1(6fX~L{gE_ap&3!( zWxiF<>`=di^0d2=7w2blODo-sp34Kz&5vDRlW*cr?Ie-Xr))Fb5 zV_64|`o(OX9B+|}qVd)^(u88|R2@&g@%|m-H^=ZsJF< z8rx2_{_Vd{Tr0)Or!LpWH|LL`BHOXs_Wr_rXCCR)IamO7;V&Vj;f3Zi*N|NTYTKw*xJp>fOud+4L81bGE}i4_?b#5v1|st+qElsb8QF&z|13w(S6X?# z6~U%0MFtdwyz0Yco2v21>SL5T)SiL7tUN^7*7Q=j~X!p!RS`6gUf!82c;N@nt0vcu(Q@$nP2B z`ubrW7&zSP2^woWdh*)ZRC}5da^1`*Jl%U??qSH;m=Y9pLdHMuNG{GZJLj_BwmT+; z%w<;QVW-ikI?KbD@a2R_mB%%ZohYb9ks+8*=UBx zcM5#d0#7XG(k~@rlu1hq;@W2lp|<_Q z{L&i9s>NyY9r6);oV-_!`h@z4p-M~)%now-c-o=8I-SRW*}u^(84QgUv%>=T2Rv#f z9Om4~8`OVC;!bQprqzkCanm8e9Oy>d41{MP2^>T}B$^6Z2GberqkjlEs=;h>;Fq%S z!1(MD`^$uhk6QNbJPvl;l>GjMCUfKDA7u6^ZEfa%0c${%zh#i9LBvKmFIdajx;`?K z9qj`%Ui=^nrxm9;6k`q&QZ;1gQpsa-8VilY%+>X%H~~uI5uZ0WgC}Z67tYDQ1)5S<002M$Nklr*=OIVa)5Rd$I8ZO4Qi&Ka*Ez%T^+rAa_lp6uF& zK(1jU=*c=eqb^xU>Kdm5tRn$+ji-s%lo^7bxhD@8d4yN`E2p8ToCFy(%_@Ozo<=xd z*c=`GwS)Ecw|?->zx7Yw`ObH4`Rjo%bR+PB-vNjSA70~s`CA{}w|xK={5qs{4;I$# z%G=d)D$^QS8f}}Wsp1NwYqh%q?NHkR+u3~OGzZo?;|Ie_qvyEYGU}7$)bTLk&}O9Q zHQLb$FiuPQ8U2L2u!a2OgMf~q?KRC*eA!ZH=~K>W6GCg#$Ug-dl~WV z;~(fLmbuQ4f!&|WNicKX81MRfVYnUZ9$F|bz~|-d!TJqH+oLBRfBbR$$9j)Yvy0pz zJ6>?oTy|LeRD&JJdi8;i-Ffb|yY4zXf5(4?+4xrI-hw4}8sz3jpx${ks?;hAo+i64 z=Vl5gyTD`0$!^;Asq~PK2DvF2PeFsAdfxqN^JZge+XI0y?Ex3m9ZWQ~hPlf(dDeoF zgovEc_3oK+NdTH#Cr#M~Hl9jx;Zv@n1!un*q-AgHIAdb0_4Jw^Y8Iz<9ti~+ZkE%c z<|uWBDlo+slBolXEKo0M2U%p3cJKid1~JB2yK@lwsf5NNB95rRDz`Boq7?_!L^d3B zn)kV}iDcINMmBLSU4mT;-I66^t-3|;TLBM!}|e6RGi)|blUa?W*@yL4So9mi~Sx0r$BVzT9|P3&IGjB957 z%J9XmfF>DE=L^7byfR;|#7nQ`-1$Og^nH$BDAnmdC;vi%&i3fTef8NWTT1@tHaE<{mMgylS`TP*9rCk_BCH*)NB7?O!bfH86BQ zUwZ1GVS0>E;+&zT2BYZZ7~63_I#{Cs!fKq&1v7k2`8Au8hJR8UAK`HvlF-E`yzx{x z@eKsOBqNRo?6NypQ45g`Mg|o)R0?8SmmC73!_IT&ClNVHo2e``unkxCp;2&oK1gn~ z`~cGhK#u|Nrpf#tv-|f@K0NCrsHU2 zXH)A4vAQ~0o=S*MuJ{rz2=p#SjLT{eg}wYWtzu$al*N4t*{JF=K&{bI%RKFeR-WT2 zZ!b_}EkrM19^2C`a@Oh%FXFaPwIx?e$M6p&zW`W~8@aS^eWl<*jOi!{p z&789qT|~a{Q&M)y4SB?S0iri=*XMrh)cU?(#P0+C0_q`DyrV|k)g8zFWxnI6;BfOF z|J6^O`Sr~Q?>tyF0-~-RG@7l~re!xc zQrHJHonbX>HOcV+*1S#(!-8by9JQMOgKwr>x^e9WR!N2zG3ETuN>V`(GuO#(DesJa zVa-fqsgXK03f|fIN?O(p|8ib;*XwXGN;csPK#KS}U;*$GAOefA?@b)JHbrj1ER8Y_ zc@ev_U{;h#Whk9SXfVnR03k!42CdnroBQZIJ^$PT#pP4H%lC$iWVlpr7=~n=2V&gr zfl^G=RZXfxZF+CAiie%h+a*XOuvJ3ogYN{~hW4?e`@Z*I|McJer-x5G`twI0|M1{rR)6|K2qR$Rt5g2>@=y=FY zZ6iTLXt%XCJ5BZj(@2_qOlERbY>^+O3KH$yniRHTpNFyRL+8{iRtwnn%+a0G%yP65$`CB-ns8DNnq>`n z4b~FKc#Cz!S)vg|ivV^q1!qX7x-|B+!J+dWIki}&1Xnj`HFGTXDvrrL&Iq*NK!Sh$ z;OOc9_PIa&-7l6^m5dhx$U;WIb?|5LlzU@a5%{Pr2Hc!4X zc%kI_^c>Y}w}OltWN>IPW;%XF;LK7BYP3$aO)B_kXRfFVNr(jt8tcM~&NaF7PF*zQ zEQ9R2)DDihB*<~bVlXfWloz{^f-FE0AlHfNTHs-)Yg=|Wm7maspOjZk9dY@$K$S>K zH9#bYFRT#@a-YT)wJ#hEV}Oi0S@u2sti9`z#)anCwlSyXq#SXydV~=z<}9Hx4@X)C zXj{!>q~t2FoX6y&zrpNY&I@wy{PIz8P=k#^1C%v^d6=AQkO$ypVO>HQH`tj!fsQjA z(hg#0VGgxCL7{%FGn3|m(=h)Up_6jF;jauPopCJ;aXAmisR%Z6ItePh4h93`T|TDr zDQ8;Py$LdJ57~wt6p2+d>ZgG9>ISoZ>Ub@B9`e<%ud%_9wa;re*PA$f-|2H*^&jh8 zRKE5Yn*C_j!Nj-fy?GS#hc~P0kT-!-uY7?`HPd z(5co9X9Ar}NXAn#5}2&VN`{OVYM|t)%p7-jG>9@P^LEhON7uQ&l;%^QH<{LR(D_RaX8i%xIe zge>kg;q_}rp{ATCkuPDEWK-r_bJXMR{T407eJwUsb%nvmEfwyw^%1KwMzItJ&KS2# z_SE$|oSaB#tCO{k$y^nS6{hLq-naf%YZ+rN@;p8#I+wo`a+}9IA2Wv+n8%X2OLiQ+ zF%D^o$GQ`@B$*T2c&+MgC+Or(FxN}rlG>|5yT+8cM)kA@CuGbNg_>ZLD$DntLUjoLGl@zfn)$dW9VO^zI8#72A6*rB--v02Kt zFwSW}z|fHx86$BjLq?j&gp`?IE}+f>+|*7xv-~lFe>Wy$%JmSm8CIxR1NRq2*Bi3^HRjVB_*YE5~8)OsldD6+=8SEk?jt+G}Ht7D#QQ;uj*ttt+c(lC#b zQUZY#X_qVmpEXZGm==~kqG*F7=4yN7oCaf=W$hxAz>y~o&vnWr3`>*;DBLtSG=7jm zG6pouX%|DB5I)xu72_6}0kdF7sCTR`(~C#E0fXEswf?YONGoOq!ns#xoJK5?jp67` z=qZMPWv6^@RQ|%et`o`=Ym-4cZUAAG35nk*`pSM0pyPfT>RMypMU_15{BFi50TeS% z^RRV&BlfwcKsqLk=8)kR;YewR9N;^x6BmrNNObM-%@JSEEnC{IR<8y2{OZiXJ3jN) z_df;e-&sBS-(8C9KVnbDW1Fkm0GR2yuROT9d=GvVVRPypM1nu}yE+3M)5@cDEmFHA zUy@CXUK!ko3b5?cr59fMbo73Yq080pf_=c0*IjVQW=Uqg<8;Qn(q7*Ru;%>sLV0Bl zu5W#B7MthME$7$s+}o4HXO5F#uMuMxUWV65(_f*kmEyYExzyK0%KtHNbspE|T}Rtf zcdhQakK;>MOLes+UE^o}o1cCD$6s}6{osFwUrl`1(Ps0#aC&AC9ha47@?>FlCcJK> zG4@SxCV!SBU2K{-z>X_lXz<&U0rePK?5S)ioleOCg>-siNm(@7iSN-F7@K*H;!%lX z`tnY3=9iAeNCR5os4>k#ROiABPC;-|?lO zAo_sQdV11094nTnx7L)T=9B}Sz!{nn1%~FetY>Sopy)Uz%e1yFj7X|>QOgt-rztEq z({U}abh2zC_fSdeSdy;k(wO-sh>fJFQjGJOQJ47gKfQL+)wFRjIbBl?SnO}6;BY6N z1&prY{V~{|)`85!9|ExoYsxVU9xH22`kLz@lvxTr?wHYUTG!S7SXId2bgXY18tbuJ z(lN?L8w3K3Yfi%eRSvnnqxd^>B8xaBd5<9q2SrX@#BJ%Z^SKjmdg>`O=OZ`P$uYQQ z9#0IeM7RWoY@TKd$P2-iO=S@YLL4!{7gj%Z;nKlf_pjCm--0mSjF1*MTJ-MD6J(SpIp+2pTUPcK&`I{~uP(X* zpP*wtLfJQ&O}pN*d3zGf%tj{1*i|kW56A5Cn`S*s>*!*Ma*j8LeB_|~k;8ya2wBHa zrDMsVbti4f(Rt|KN0(d1cAvaqP5=?Qu7C5U;iL@5kU89AAT26%4Rm|e1XH@>MxHad zupb)Ow~gDlb*0^BX1QBaxh)=a`b$E|cYqdL=XUC_kM@PW6oBl~xTjO4B$?}Np`Ce+ zi8#GlXJn!uw*w)4iBmsQMG*H3pPP6QcX(ZL1>-u=w*9iG4MD2bYZ2TR7ag*wH z#+1WWv$?L@0Y4dX(D3R)Ho-I>C+yD6n}=kWBX)_62wRVKaaWQ|edD!vz4~KFaC7P4 z!d?H*bN}Wu?_520Rev1FKb5?aU+MWD{ycYh>JI$f8~nw;75=Z{)mzYtBU0ju=FdCg zoBbHmJo@bI9<=V?fry10a_(H?8%#R{3*6j=##0+FKfQdV9ftgQ5PrS}9)1JB%{gHs zjPhY_F6xLugn(Aa$}J3bIVDdt!_ap#wu-(Z2=;bDk3g=-9-g7Yl_)+-P^?;gF5bHC)rw{lmZk!PzVii$DWnZLesKI9vUR$qH2BYjTt zO~>hrJ_+YZl~w%Bx9uGZ#{$!8;V|ARkL6{yrmO>&zL{OF-#&LyZ(@N$82lErgY1q( z`j#LET*UltI-p!L(&(EG^7Ym_)5h35ma=7B{2qK7=+x@uE`tYNRn{4{MQa`7i0|~P zy4a8TdyE~&T$-+u4o<#H!*4lHKaOVPlI|S_+d9atdWlC|6)!t+-zfM<#*s8k@Z^mJ z^Fv3DJ#^%ul;8HNZk|TWg;Iy|W|>N3lz*z>udZME>{i4%j%EYQ@JkCErdA&VC;JZ)`RJbL7GJJ;s63xxuoG$W5Ia9y`?*}>AlKYm@7m;8xgZ|?%1#i5zMfspoG9fa(>>y7@Hr)xGOIIg$Y>Ym?GB5+} zmlIZKb~Gx9?1Df#h8K{;*$aeC2dNZ{Ik=b@4fFn&WZ{o7;E21UP2|Pwc8XiL0%ie4 z7W83GirF{uA>|rjX(LRAg84MP?Bf)%5Ev=QUFIVD5R)JlyIgX}Zvlgq1*VSp;U^@N zsz)1sQ{Y3cF~C}Yonh2^Oqt@8E$zcaxDQ?AL8}G3=1}VZW6nz**#*ZCs>hu8jmlxn zIC^|xA4ZO~$00q#O-FNk$Dg=>31o{jbmQnu{ZK z!6{x?k{jRUImgX|CW*+zsD2aQRHlG)?hxjf99Mi8k67r%N7hllO36IpU(~@cJB-=T zde;jsDHjhLSdTGt9S8GLZnbWwY9Xad8{YdEoAK%w-^^bQNm(3I|FWbW->e3|M`7FA zqE6ri`(YqNoQM;aW?>o%xhO$(sN~{_Yb&5WH&E-+AioKWWUB(@o4S2R+!{FtbA*}M za&^&H|5uAI$~Md$fGnn&3&ffZa`a}tsaxSSe7o7KPk(WB>fYP#dHQ4j`lo*Cr&b^N z$VVEv$QDlvZ{IKCR=KlSv|)8+o1;$O`vu<9xf<*qimA8s)u-n4YfW#kZZ=tJ!{9hi`-l=t(4K%V~9*%!bp}$T|HKwR^js z>rXPil8@lX$Bdeq`?|x`sV_bC)Ke7Bfi~D_ue1S>2W%tRuHW*O zw;cT5`nDgy=H|WdamSR64}3F;HfdUb*s5ul#n+sH0xfrOlNTaTaH|ze@ix8s!>Xkh zLaP)kz!9|lbuIjbO9)3GlJVE#1P$Mgw?!Kv;cQF$3lHIMD)ZuLu>j!w(1kPTc;>F# z#>ydV%Bk$6Py}L@wA%+!AkjeJ1Wh6xdE_wCRRB7X zByvg|$2_Wr=+D=N7mLEs+k69)>rJd8qJ6FjtrvL=OX`i6Uj@%O%rFV#(Vl8XEK%bs zm?pvLg&E7HL*m(-BoWt-tp+?LQBH`1ptI61q;pd{L|UO5@j@j7<)>;7e-0rgHE1mh zO3f|1Hkx(=1P4~f1FOUpCUo+vm_iBze$ti&P8b>;Nn}3CFz=zw`vGNMHdeXHvJ;x8 zV5zwx7mabA)JJ30M_T9|MRcMhVQQV%24Zro00_hX<|AZzooUkM*IYs}oOJ9af{7p- zy}%xG(EDvnaR%+F$&}(U$7r!{X z{^Tb=SwGgtTj5}Ax(6QsyazQbM+5Xnq^J2_$hFIR z-_TeQF^Y+^X1{ETz=(#;Sc|8PyN;_lZam4~aIKrlXkIzr0u|uoc!KsV8tdob?vu}P zeS9r8-TsyS$tu7)_xZGyxq4|lBI^zgaW#m`+_eeM${`olmc*#NBH^Pcw{{EOH9 z=+`}UblV&7!v97T{6V8L6S!_Vw=~13^JpZ z{|jMYO^miZRV2Sd9(I5QJIzC^jc^)Jjq&g;Fo4v9jf64C^jN$3t`yKw9}dEfhWG+U zICF4%_#?<)GRc$Us(KG)#KNe?^qCq?q8oEhX00JxQxCghbu6>E2^Um$Q44k}Duq17 zKqocqY>;paE%A;%Ye_|b5an-=gp zmF);H5t1slbV+##*{RGZ;vb}83ld$Df{yAl=@1cwLrW5^NvP)9k+SSKxBL>ioC~vf z3dneRs@W$x?Mqhqo0xtGjQL|}+l8yjb z0qoh3il=l{Z7I+ZI4$dXkgu?cb9v(;$n_cj+bI~VB-H(Wzo7-Hpg3@D>lGRv)G2Na zcp_CE*>&EOhLe6ac-qPoC;pKzqC1C?mId4J>@g%>TQ*r}nNtReCVP&Pe*lg)u{fqm zgDD*@(?b^|h3^fMT%1Fg`JS63(SV9<3?TxbjcZ;PO`1?Q)&fwcA$Su$5ct%&H~h%A zo!MUgy|+Ga@%Qq{zXv&S$-zlB05Uq--gf79b@p{2J*O~hRqb%zAc6C6OE852^DIY3?XqUsfp6W5>t)$wDuqLC+v;_I_c-jZ$ICAM?ZeJ>C&_1ttIK*mBM#@tcjUL{@CPp+JX~$Q)b+>p`2m8x2R`+` zx&QwA*Ps6Mrw^Wd^#|X#J~;aW+wJC^2O$-)|>}(u1 zPGS~H5OAIH(Suxmcp^~iR}OSS1WB4cQW~59)0Q$2)e{uQ;t3Q66nHRc9dQZ)id{1Z z#hE-o$EP+LT}kvAap=s26)_4ki4gu{bF76N(i&n!7>7^w zJ+SW#T(Kl9xeeFKOnq>HlC@^6q;o9c8{vynaZnrH(_gxCKqL^5g04$A%&7^A;IgKp ziQ!SW?2n7enu1Y~)nqPZt8RwGMEE7+hMAB^9dk)az=BVpekx2C&iYP@bynX3;uJ=7 zsE@fw0*2}^!)DYqAp)2$xNydrl8m*m1B22KIZ=b}KDScFT;~+m1eynss7J=evCLu| zbqxXK!z|qaJ!EOP+n92Y17q&;50qsQ1ei^pI_jH9o?DpeMA=L2!z%dFMAOeRF;K(XBiqYKw}%&hh(5f zkA85#80$r5ky;=uur9{BbYUb6L@+MG>|`(&J2tu^hj{Wn6}Cj;djR3&(sq6DG=4h& z_?=(Jc=4y_D3))` z5mN+{c7)~8Zz8S8R_|*`mj$V-(xrqZRaJu;*V|izcx(<>{fu+AI6__vCXIW%Mg`taS;OCsY6ccgHvI%o2C)BlzFl>k><~A zF%Ah=0M|znNjP-0G;gsLCL|>%*atAd3HHQ?s^+-89d4tctMDrB$$W|tR?VR}+SnzW z)VUm#$7Eux(QSBp88M_o(4b^gyEftze)t7v#gm=kA6P5PjRcxw(rILj_)`{jweR82 zlEel_5NJY^%hw;*bzmxhW|>`I>l_A*yJ;O>G&u;N&$LTCMC^@XOlp<}fwgtuJzB!= z=v=5~dYoO_%L*qic+;wFRGAB|@kF@lE(XM-o`ErUT0~>K>?7tlLtXPRvCyEnZQmf) zNi@$n$1ZRA0=W0X7P9!bowMVAKT&x#mq_-`^=k9SFCDFZ3%|9uId|?H*^Yee;QqG5 zzPJIHaDw%j+aEf$-X7hKiwhqBJo%3eW;|CII<}>%KxXw7Sa#I3TcRXzpL~a8L9j0# z`;)$bB+qdZE3rNvH=~jB?!2{tx^WZVw65cE>moBC%l7rV-U%$pth)tUhpV(bI7ytq z5>C4%Gs^ermgqZ2?=N9ru#67un+iNwToy=^KC2wQ|y$5W=0jqJ}p=bU(fKfPWbylR90C-`Xf0N>p|eEjjp=dg*h zD{TNat8f1BZC`oqH$8+*AHx5r^%|^)gUBX$^|Usj}{u% zR=rr*ywHv*$E%>9n4<`OWsDsaWcbolQXvT94fh<2$9UlHD^JB4=@AM_U4ZJ3NEH*g?M4C&Lq=)U-Rnj|@(3G-X)dWwng0;99t+6T zU_z+Wb?zBY)-GaU{E$~=q9oYYuF{0K1MVt zj3%Rinr6m_; zw>V)Snm7Yt@S$`Z_N4#&+ zybKkkPJo3pejOh78wCnD%8(phI3(My&H(V5^=AE=v+w)K*Zkh*^Iv$wQ@{8e{wPp{ zSwRjLSK0vJzxjF9!S>?03)own!%X7EzZG}zytutyE2p*;0ddxM8)CcM{Ur{{=C%}+ ztU9~arK-*n*-X~4yOgg;Zd3(aceY#*{I+aqfmp|QdY|K0j$5w+^EsN2_eI=sy-)mn zypQ8WkTaCNOx<^g9?wIuelGWTpT5g`pLX-Hxo&7nrzds1gtN@;4Gs3jkZZrSKENyV z`J?rP3zwg{?Th?7fyW(-8vyJ`^g{>y;h)XtF5GkB@Qyp)jLp`4e8S@{EeN@jhR3$B zLdX5>Y?Dx!QQUZ1#F(Pgo68&H*y%toOmJ#T6q`62rzHVAIAotO;0vd~W1wA=G~7EO zM9R`W&C#$Y&e-j8kba?PhcG%3QC5k7BC142dS)7tG>Ov7}P!D-o4dYqg zGH1?-CoB>vq&o=_He{MdTCW>qG`IE`|$T0g-`Qt2Il ze$`XnHG8Ug)DJ*%3dl`6Op}8lF#x%=e+qYxjA|(4AcheO`lxJBC5(Ah4%FixBVgc& z3D^vzrX=jcJTT%&T*$*l{Y-^Kl=75wSn|`h` zZ0ab2O4n{+%+Kh2Mo9T z4+4L~KVVo5!=Ipr8U@(uSwgi07$7Lf(2F8v@iOnt^mxRG8FTKnPv(8_p#oRtUUNpo zh!KxD*V^msJm;k2l0w~etlrL@*W`&OpMfA#RyZ~r%c z|N0;Q;ZOh1Km8~Ca-dJBzB(=+01BvwfVZ!{@#^iHC;ab!_#S|)R5K}^mOk}_?x9${ zxuu!5IVY0-)P;w-d9*EnR=_7@uxVQIwv*yFN#8O53@-0r{3V$GqbTC&8*55kW9_%~ z)`j+r-vvd`p^lsoku#pS=rNuyfu8!|Qqz0Ly5VjPX1nDK#|A$5uWU;f&Wy|Q#m#nZ z<{Zt;KlL}#e2VkQ(YfB?2);@aD!MC|ck#vNcIw|H$B*NQoi@&|YB}=^N5;j$ zhxK_xIvCzQeD&=o55M{F_$u%3dXAW$nFkP=9&D(w|@7PqObOqwTU#$h|4#3@?CAxXg)d8+BBuJtr4e}=Kw znvu01^JKP$2&3~LRh|`}`RgkMs`Kf9e0Dtn=&-RF$bmma!oLKc zU%?4b1(uCqlVQl-ZB=2BPE0G8wpCh^JFikIi!mS5RRidgl>B*ltR)HM#19%w8v!2p zK@?pQjJcdfo@;N}CS+1E3CQhlTX9vs>LFBUPS$VrDfxnLDJxFVtY%iqw@^A1+N++b zj-HvAX9D6;+8HPHG*4lAPtlOvV;f`qmudyFiL{O)(3KK$^*H^29LzxVc!{^*Z*Jq_gki-6P>1|+0IcnvE;$qAy#c%wJ2XG>{6EnD&oxRB|iF%+M+MyGzk_&!h;37j2Ru zKSNqafn8K|&B+j1Y%ptfx{6>~N@*LbT-to9=a!Ku+H zu98J6P2$AN6f2eXi;Q$JoqdcKv;y(OyBj}N5>L5SoujYBEpK8sUb8h~*y>`dRx&P7 zv1fF}z5t?2w5*+Tl(yr<)>lfFY}=;kXQguVsmT&hBYjra4;S>yoMB$Qn|+CO>Ktvv z49JB^;)$>AhR`n6pZHO~*(i*)I&4lH%F>S-5!0l~x0{tfp!I>vf!8l$BuvL3poxR_ z$ThbK=c-})A&dZ1SDy5ga~R*|%Y$+*vhao%(P*gw3xSN{0~zag#w;UTW(S@7GAaY>z9ieulRORo}|$Z*yD z!;kn?;Nk*U1xq5F==l93;T1bP=6Z#8SnHn zpU=}a=Vv~X@3ftMW?rb%9?Nr_&)MRiamL$Y?JUcdCk!%7Z%Yez8$q|a0Px#-AD>=) z^TmsYS9}i-`f7{|ZJbBO_YQvd<=6k+|M<<wm%T1NtV?Fd0yLdZv!E zC1C{fBX_p9cW|)XiV)IJ8`(A}q;q!ARhRmkZrYwNL1sM8?c(1zy&nI0Nja#$kjK12 zG5>tE0_o&RBK6Jzq zEw9%4qg?1$Kaq%8^W%<9m7gfbVmXJi%7T5`!${1^X zK5M5oJ!7rw0CJ~^DO$N&d92Yyr0MaVVp8Mx+xu{!Bmf&`?%c zQFugeeOc53KpW3uu|cl6|CxvPE6sc=x1-0tM**Su#^gHeb-hR}N$lB{6e9y?egTAu z*7W`Y0YEL>elJmGDoakIrXmACfq7r823>>_1aD(t`oz0<vIzj#c9v+mSCdV2FW|I@37|Lafw@sIzHe|UKK z;m6n`uZNS+_nrtBR?s)hjsLvNjqQBbBun@r!IPqeE?8Z zYb3sj%31ahU5)W+(&C6L(g?pEf8ia-nlW(ZS7Q=;Ut93M9)C4Dz;(-UwTADj3kS!O zbJ~7M^Y<;|#JwxsS?as6zjXUq-22ME^u+&TNPzFvFCX5#`tm3L_#0n)`0zVCMlR z!VzK{kO4aZE2QHiv{2O14+oydZt>A1f*^8&e;M_7pS+HzFAynim!kkc^RFsQWyBR3P0EuR7tt0sO5NybjHar`BBs~~*C1Nu zX$wknp$O-mC|7wAVN@-a>oDUaj)u|fq>7>(sIw*_NVu!i4zOeD)Stq>w8%vlPe> z=Za|j;|jztFQ3ZRMo%INvufS^#1!B~?F(G_GK199#?(Ru=i`{%mpRBGC{Wk5uwvVF z)xW*j9e3phS3*}lwYQ-3AKDVFisBMQha%`pil8vRQv( z71fE$xpP|ADl6P?3Qy>?V<cD%Yn!?mxbz&JD=4<-aKVKBUdY&ke-|$JPc@#2{#=55s*J9{X#s6B!>PaZ zo3&*g?~J!z@77%V?(b69m~cOzcTi&l9U14%bZZ2mlXMHe3Dv-W58DX&+?3waGi>kj zxo0OAIj(qOOT3B6{L}P)izw!^3xQQkH-toRT`zJ#9mwfWy z^^2#EKmJ(X2#9cGY-B$G z&;kE*&{O^H;1>^X@bUkvul-99{I-7RfRAU}Q)P3g1pb?H9>MC7z88Z}Y_TDBm9#34 zVm2w(MA5%$K)IT;c-lX8(W#XAiavhoOXc7vNkN5n{Ek?_?e%YW4#hj!;Gj_G<>=D`DF@E=;3#`4L#)o+)q9)OXbbnN$YX ziczzbuNAdEaAnH%pZcsmPSVI{WtV$JzB}H z_Ojy?spF=6jZVUQ3^|Cq`jY%AHMSw^PhdyV1adUJXdA}Xl{?w?c!^^^oTq%8TTn5#XD!I(iXOsk&lrvQwo zd(iSsElZtq7{IpMz%O9U`t2gC%>%TOa zt!SoITGia-%`tt6u5()J*s7Xv#opF`I>u)C7&Z6)y0V>YNqFj`n`<=rCzf;Kbs2x_ z>EY#f-n@GG^5g&SV}7##fFJRHoIeiO4*;R~@sEGZAOCy&yWjZci%%Y2e1L!Y|2nFB z;%_!vH%FCO)i^l|XQC@fteYU+0xd4^bZLt*VbR`;gBF~P?rx&O#n1fH9_N{OrOmL=ZrviU*;+#=Hr;}fsN*&3Zf|u+ zmSUUnBeuj$xRLL%r@F7?D0nYg_Y9o1zhYZ4*fS@P)dO( zsZ9XqDKIdMR^@&O>A(ak!)BwU6qp=2v2VR~ievV&=8N5_ijN!1$7W{Vmg$J6HQeCg z2vu@F^c1h-d5*OnrKAWt%w8nMlWrF^b3>uXNMC&vRdEH~z?}O60?ZxhlN^po_IpeRxQEdi*-x zx<7dH^2;yyw_kVZaw$zv$dbD|o4J^ae zKunrP`}_D@@kDp}U&&Xx_}>|yOEGj?d!sBqidk=&aO#@{YzJKOjJc&1@D^|&rrm04 za(}){I~bmyk}a_l>-4y%2kxHfo_?bSsBxK$iqg~e38ocma)Vu_efA7TClk!brENRg zdr6@q$E3V*ZlEo}9%>oq{u2%$-9HHC{gel9qvbqoGHs`;02|;_2;rK^XC9hhB6Gab zO?%A+!%37UZ>evnregX`{cWsRr^hWSneXWPJ`0x_Iq&0F#9-uC&Uqk>E!lKCV@R;b zi+0U|p$69z#R;Eg>r1me-AxY>-E!PqtBd*cCIb&DHb;(@LA{Ay;U}_j!2V*x*Yu^lcjO=4GID@IwBLhsPJc`S9_ZoA31ttRDdI&41L9 z>+w6^`Ob?sFJI#)0KW9QZy#U$XHY&>WQXP1S=aqTZcGmo8H^*N4t;q59o2TUfH@}o z@~MCx`>PAyvHXP72$K~29703RBvSqjT{*O>-kBMLPifQ-CP^bc7sHr}VLben6I6A# zRV_9or}30WRr%%aY;OKuY}9hrZrgGu05G$3&2by?xD~AKenFHDAEOl=dBlj5DKW}RC&fx+SgK;!lmMGb#$b)y zd6su($&qp7Sq`^;s|Pbrra`XYn>SmEwn;32dqyAIsszf&0y(MDx^; zN->|x81B?62d%KU*($K+NFJgahA}N7dz79Zf#x4VdIu&u#;>>uqmg#yHpvTt1kV(1 ze62|S-n0Rwj{6uUMe7QlufBFIVdmaBfs(&!!=9&bY&sIHqZX3!6ceY!?v};opfD?h z+>jd8{PfQIjowvD-Dbom-%+FRgf8$(SROd3Yzp#TCumS_)~4zh zGF@^c&x+Gd$OVMtOni^Vokq{&G8TZ%wZB zSGr{XoGqANk3atoa2<5Zz?k_QnL+L|S8FzPb56f6;Fy$2GqhK>=qC2mMGns#Pg~^4 zH}RPV7x`CeWO97*C%=+t#xv2WpYs#h`vc(>;xik_#SW_-N-ShSMClg4EL5%Kw_9>nGo z6LZ@Ant~2`V$Gh;BhY%HL%a&VvQRXf@FZVPwv7^qC%oi|Smo${*Y-2M8DuLfHJz8t zsbT$lIH7scOdm2P4&&}TNB|1@(LZ=+Rga90mxudu=aXc8!7=Kk++W zGLqypm=6~QM`~giQTV)1`IyfGXZGDQE0z;uQ>O#!L4-MW+EfIzDZ}LuF!6C(9qn}} z`sgX5k8-4rL9%vAcjFgYEi%o>7YYVizDCSXa$r?1t7p@{imP0ZiF@HiRu!8{^x43x zG58%O^7EGpV{HnbtS}~*QZX0skkXNy2sTLe?^E$GI&P^->F~{-N;XAcXHT*K?TeB!_ML=HHS-nB9e^}WfKKX=>dQ4 zP_W@sVahb1M@`A$|hI@)HJq=m7cg- zc;uQwOoffV@T}_%{@wopp8!1m)|bBijTgW1o$ow+^wCFKhJ^M500n*nAbxM~6Te{q z{>bDl{uw}@0<4Z~f#`Lkpz>GrIO|XD8Iv~U6C2w<$MLL(GF}{bq|}Vm#pT4r#xcjB zk}5tBIE^^zR0KE#c4#EhQs?F^iDx9&(G&1uH+mhZ?tMUamaIt>Jq;9FEL7;sr2<rjD?1jJx{fD4l2e z#C1yUxfSFZr@n0=K5L7f@#q_2KdLOTMS`)BSIL^PBo{e=M6G1o!~3MdgzM zjQn4b@b3or1OSf@x=1Tzz*yUwrU}YGX(c!K>R30TXgJmzq*+26Kv59m$`Ed&Jss@W zUBKiT!CZ3F$p~bD6)!nxT%D$97}}#rzv)6>1Y^Snv*=dOsuV4(`;d>57A7AlC#vGh zv0~L=F0C0LlscCcT3YKJFMS1ma#kho^~u93Pdr12K(%NF`B*Efw`{Zwt*J;gtoy6j zt<6oLeA0W1)$2-y+`0FxZloGw_xw5yO=2_WvQZyhFtJWsx8H3+thGDh@0P9H=Bzkb z!d2g7CS_Sq4CJm|YXXN(06xR$NQqLpal@xomCBNdJp)egoX7cQECRXBY{dW6K#_N z^-YW-xHOy#Is2L48<2ZNV$QK@2sc^p^^O4xzM@tL-VW%e$9kNh?MUw(M= z`ibuk{PF&{2zXIcm^3DO#*TwrN*C1ziLjCFLLl*{ z_0%PXJPRmHfT4tZrJu0O6EAWoG@i201yiV+tQd@BxY(r2jH$`}@jLvUY5m`SESfyjUR z3vfY7$N8X}-hmDKkrWWt_-vkF!Wx-$6DRsU1>K4}lX2F2SrTy@OQhwTPEJnGZ~g2tkwtQF?Js`^-z4zKC!hEefKNWbcmF?q1GHZ=eKj=8UiUs;xIXyQ;X474DN6)Q6PdKcgS%Al!7rfFR+EKR9&DDemQCU0Y-g@z+XrxW z&x;}oab~|YC|?DUFWY z3=P~JFUzU;fGb}4ZF{*l(aNC6mLhT1`ggpzuXt_RCaYc~L*^_)P^DF(um$hD>EXW( zM_}0sApHwpop0ZiP0H1Og$+T*Qm!~Ouu(EFD01NrO~TFRZ5tlqMM8HfYmLye>Jf-Y z*QfwF#*>b9SVdnqL!`E?Y2D6-f88etsU{Xtc$HpIu-()J6|oMY+!HVRfPl=kr%WT5 z0y8uw%g@tQ3~XLwCSt$pmt$AzowFelT`OUxmjePqdh>wy?uT!@e)G|bAN}Y@k6-!9 zS04EuU%%~FKQ^*G05tuYkj;!s_v_i`>VTJNZ)qlmFNApHBzaZ@$(g zxyx6V(=U0A5`L!4=A;bH=Mj8#r+o4Rm(qjJ7(2%+UHpQ(!o>D-8E3%vO=kMMZ&IJd z=Y6?{9dTL(4j1QCblEyd&NMkpet=)S3x|+aUmeF*%ft z4{zbD{MI_0kr^(2sezdA)4pm_R#s7&qi6Z5b^WMTAb>Z@`6jM7%f@=xlhjn|ejKc{ zq8{l$Ra!@+VBMyMM?1-E40SvzkcFFbnDn@Amy}Y`*?8{>VCreOy)fY?FN&i;06^yB zy1pR5T)7cPkRxE?^<)SEM8K2sZB!nu|DrP?DHVqIbQi*0noL{@Vv z0OkN&DLyxZ-$KJ+j9+;IyaCI>9Tgo|mut-z{rQCv&ktZDSOYb6>1@wWe06gK|(!yhNN%lCiDg zuFOUZOcBOjwTm2fRb+IhDr_)p6BLX$|9=1X^RGkz^5;M@wY@Xz^Q`QU>`et%!{6NJ~h zJ^>i`&pMrTDe=!r^v}Z2YdvdD+SPlS)P{kX%R=}td1oFvVy=$KGdYMIa;6i0MR%=> zHz_^WMY4exW>ZU0@tEa~z7U@+pXEQJ&iO*zpH2MCgZk~x0m<@2g?F;ddF;=Ps~^*I zMw#>Hn5Iqn>om1v4qM&{=6y=BaH5Xu9E?19&%u8Wvetj_L0f+fEtB|W0P1H!aC@JF zu<7)p;1f7YH%h?zLDPI=Bx8)Yq+C;J=$@|M$P zOdRiIHR9BsGWW)|mnJdiHx5vZ!nuWRAhh$KA#*8q>@@Kj&K0+==O8i`$<1KvT(^!0F5H4t(G*0s7#B58l3f`7(I)gg*^{ zeo~W{zH^_;p*sMG){_rGY^0l6A-H?^6vAItQCy6!49JB0e}lz^|~`gaEp(J2NY!WfYMbD#eAzCfu; zopj(I{>6)Vxjt)4Ei+wE4m*6YZvY_+F?EQC^=rM&j{yD?5Cc>WNn4^eR4l9pzve|R z=&%^<7_EqBe#YnoIG3GJ@3)evrH}lW8(;auoPr}?`DX25to0!9`e0g0EkVrZ2wG`c z>quN?bHN>W*U-r&Nsdv@+%lgyVH3FO;3noD{j?AO?8iKsr|_p8*wny%1BtK2V1HLk zbr70Et^I91ZDbG&^!#*2Y{Q50#ew$eaA;$o&?0LwoPa$i1?Q5hPR`kiO^1Y3n%#9S zKhlc&sM^Q^iA;nB)1m9q92&)^uwGu4#Et=WLAd|->nO59r5*?!OB5ALO&)W~b*vc! zU0}pRn_m&j{r(WHD@1G|W71xQmBaLlxyQ6O2lQ=7Sbwn_?|$NbKv_X51ip!LiG-GBWZK54sHBH*rxPX5o@hF z-T+#+6pWjEtxZqJbE1`fJFnihswcCaR$_u!p-t_|x*};#n0=gC}4QKDDOr9ZaSsvG?TyDw zf~=K|hBy3P$I5Soz~)GZtZi!O?gcRWX&u+B{oAkbG=wu;jgfH?bJj$=`bG+8a}{Fx zck!9ru}dp!TSpI`Lz^^Si6xFWsD1d2*D`6@Rg#@wRIq~*cWH4NPquFWx?j$6P& z2iwkH@MP!D9=Q!-9M4(0#_SZW)+A3SySAjmQDSsgy|5cC>D*YLBZ7I>{V3+};}#c{ z);9W9ey$0>O4ETLD-JZe5D)4FC7_M+3(wACoS;Od7W?v?yWkdk=oM#$f@MF6s||lvIw8ZQmzA zk8rzBqym&;NcckYDmw?b+t_sgBjX43?MCD4$%gm zk@^w-E-rYEj&+aKZ1>_Zz?Dt44MX-1?trdUb&7vcU*Iv^LJ@&A7w9xo@MVjuCc=dMKO=gW!8#0#aXv#3mltVbXvXLzOE?S zA|k>4qaOhN^iTg(C_E*+{l+)G@$k{BSNM&9a2{QSM8(F2l9JB6S12kB0n;_}&3|C1 z9~ei=j#>s$14us4eWr8C>SD#KC%<4E{5qG}{2gCj-Ha=Ld!(MR6<`QHRfL^m8r=R0 zMt|4Hs)BbOYr&~EckM0GRSLPuuuJ8?9G9+4djxVo^EST_#BmjCl~68u8crQdsqn#4 ztRy-Y>SX6Xc^KF=$VMG)hK;q+GK(iq^-m#S%jnFL^MSv}^NEoALyXj%aAu5Wh`Ick zgFsSgwp^1Gv&=mBf{IyrBICw%ugvYF?Vzlj`>AMp0FqZlRO1v8d2t1eVazI`@u&c&ByQ2)9*V zWlIb@_2pSAntedQIv|9rmpBMQYQA~~1%V@>{?vrv=*zLWX~;ShXRlxBsTLP}Q>Jc|hMg2RO+*``{xO`q^IjPXjy7@Kmo&C4ztzVfDh&v8dRXM4_j)W*o~@(wPJk*_#|Imh@=&-siw z*U`9TU299vrJoXfCOu8taq|E$pAz^TQrK3_%t!Um!BF}(&-XML%1Vv%^5U|LH^J~l}a*2fxK7&)?=)^ei0;(JxBDXB=} zTk*<^QV7!HLXa=ip$f^>*gY4gNxffKOX`H)f0Hca*sfSR3DPUW#ntQ6j?9zc@yo(Y z%BHGE2#OqfDd@ozL!k*9SZhSvahN&=Izr>U#}HKy?ff<;J2M}qlK$05Dj}xL302VY z&kDc+2YptrtjnIV#F{iS`|e)U;VKAe-Iq{^1E;#KiR*R(V?Uj1?pk#3s~9#&C{|$9#d zofJI@$S#5T;rRGxA3eVQ$xj}?{q1kdR{!UZT6gmR(CnXM;`XnWd=9Gja8(_^rT#>Z z>nTT%F($fZPIIU>B@GuxV__Q{oYvA_IDOHo5%?}OG4F%BOYjRdtW0y0or@G}#%W8M z(?(t7*fUx`mywoJ4*FfA{6I<8x}m!(-8IAeYrh!2kr}3SfB)3EK9@^x8}JLq zkmpeZc>{_MVac#* zIp1-)Z<%jq?Kk*^&WsrHO{~4cF{S6{;d~y2-}M^+ehT1$|5*T^rhbB_h1d8+KoGF* ze5xZI)57Q}Mn2Who`&EK#iuep2^-3X4^B%Gg>H(qnZU%m8maKtFV2_1X#GcqVUsJ} z`=BN-%$RrQmpsv863Nz%HKF0uSrs+M?bR`?6|SZ!iYY@SQv%`1xc-f?z%+Q8MDawJ zzVPvpuWr&p#|z`?f6v3U*Xxe1A3Leg$cbNJXm>glhT);ORlt^m&0a<%xWd7oHJ1TSQ&=y)eL3f+A*ri>M5cn$B~$IWxvq*6E5cBwojtUIkT(@5^jPA_7)XALlpFueNUS4Vz{m)wN=HRk0I6PG3NvPKyved6?fh+>Rs;`HnK zDxh+%d0exptqzM*?;0A+$w2^3Z7*2r5BtUS;}PPbOue&zVazB$?pN(u_K*D!!6FrI zo(N)GzT%*@NG|5O#lSE4_(wr~j$kr2hWw?BZ8gOve)=qu_uMd{8u zRf~caFXv;LdDlE_(&=Yb5s5kO2Yw~++x{`Y-Ly;oG@8U}rHo#!sgW8dHmc^lpm0F6 zCVHZ5;)8&+uT-y)%*rPh<&4#-*x{TC6B@b2@gXx_ zpj;0Xv=>*SXExO6Ep}zLOWm zeGW@(?FY^yT%cv}{;zP2bx{}HVTxt!7;#=BFVMz~Z`4@`&zu@KP08@5DlY7KU`%2s zn7u15fQ->lbKaPEbQI2mi&BVEZaNuky`x`<3STtQvoD#~IGOq?J$pQJEQh+Z*0l=0 z)u1BpKH<_{^NYw)?b*pCejImmIbmphVYD7)j(-Ym>~ep0HvIMALU6c-V{SEk7~+vI z-Z&Qy6C`|l(4r9PS=7>wQ}-i)iXrh%yy1Q`%^K5?norQy*D@wN#c-5=OjaK`%@~JY zhwU0$(|uKka%~^}jC8XX7scWzzvOAik!Sn>YFtlZyyFw|tW~-qxY5S}Zpj5wu$qe%?tE3ePD={{@U)Uva6J)F1vc zK0$}>5SP7rm?quevTPRy#E9GCOHNy|H{8m@50Cv65Ij_+xTu?Gq{#*^!m2|aX&cw?6b_J*FEDfr!b zrH~3tWc^9{ZW|Gc6T+uHxPSM!;bX>UUMc5&!gw93203yqkT2%bHo5NABR>Hv*Bb0g zVJcFA*MIWg&X?cvB8vKG(g%AlkA;v0Ny=+$(nQ;z=Uux?Z5P=d`*2i-?&ad1m{q~B zV;a3;fxzsNun7#t3y{&bj9`@e@z;6KLQ+$35&^MpzO1#z+hnVq2 zm@?q$Y|M~>osTHQIx+c$d##hJl3wq)jfep)1VcE<#h0xvI>>Y&SRoxerXD*?PYPIa zy~~f9X;8c_HctYHzvA{T2o|e^b~{A+T9K@eZ#ZW*nFmvjX+n#0Qdp*zol*Dd)fFUC zxg^a*5>xUlBW^CbpMegrMyB`?oHZygPQ-bTNB1CKJ=3kZ%#mc$M7P9o4yYaOoWYaQ z7s6!R`zx-gftl=czT8ucG+C=Qvq2)e=iJEq6T5~WYasm1`fod+0>={`*#kAkvN&(s z(=7;iCYpM|7xUsOATXOPLYX6`<&kNQ?tH>d9j1r}a>!SV#a%<*BYGQ2-#sY*l4Top zZ8C)<6*pBErO>u`c(dl!y#Q0 z=fcr^!J#;;J;mEu=W}tGn{<<>{A6PY+NuYkyxDhTFOHjfW#b7D58L@hmwwBkdJx^r zvseltsbe2F_9D2BR}Esnq|+%VlT*r?q`nI4c=X|`+#dCf%y0kpZ~yk;yWjop!-pS! zs80Zh{er&qjIbTg*<+)_oKJ$%w;2;PqZFDC{3#F97NYqIFy%R){-0}3(pntx zP>yZ}ob%5W@aOEDJkJ`g79iL?rQI`6$UElqNa4TXNIK_o5D49Ke!fpl$6|+5?o(?o z2bX{&lT$V1co9wYln2A*G+4eRW_}4Q<-|CJ6_GRRCRa2h@SNxMBtZRnOrO*CZrS`h zE{rq(9bxI7{p1WEy>5MWbnfk}-|wZ%d(Czp-S=;a73-cY_0-!#M2(@!C}jngZYBa_ za8%E=+F{wjQ|o#B6{mN_l7wZ2d$8Ak#`3 zx4rMA4buk#PxS;RFT3(wy)1PH{qKn|h`6W}%lDUlvQ6O5^>!i;_|EmnHzSD|u?Nk} z%BzG&%MHO0RX6k2lQ%Sgkq(NKj&V$t8S4~EZ6vLvvI$KZyvoyLkdkQ+mk(lRXrRm#{nc79d@>+(=M;!NldXALN=Rp7uUm05nz!)TyI^v3A`wyTt1} z?V23nwYV0=k*5<#8g@un<|&KKT^PyU;2WB3bA2-u>Wl{ns^_)O>Dwt}TitxhP@#?j zOlk(6X=YsZweFivX#wkAA@n>c1)Ta{IKWUF#Z;geEOGU|W>L~8xN}IIxsD^pGjw*W zv{f{z07jEAHno;h|q})Nwv-wDSnY(!KNaoO9wSpE~nId&Y>~ zsC5o5_Q(sdB3;=gE^~4Pn=!UI(&l~Y=-JuCc&CTSsBm$4d#{Ml{+i+xT;w@k?Kk0f ziY{6iIMGStIrMx7+c*n#l|w@KDPbpF_$b6v(Y@5dC3P~GZ z_iP)H1R_^;w{~lCZ{m7q&M5a{(QDzt;W6ju>NqixGiv=nFzXCoFfv{M^aL}&6QZ2Q z=IAdSK>GObx~b1eKLFsn0!5u)7C<0>4iG_b%F_nP>OpGTI}A@fo;blWa_o4vQ*_!m z3ud;4Wnz#dR|R6>y*M#D5_D16qo0mK$090{S?t*6WT86CX39lOjQfxqLUV!#^hu^! zGg;YHoG6@2U`I|=LzUDhx_GJ^n+YhLs`F4w^2trm2JBz$YK6(YAD~sa#km_LDUL8@ zyy}nL9e>W@l08-Gka(oBE0YR6mtxB|Yr4S3ay8PA-V3vl2f6$e6Q}I;4ezwtR^p8u zJ;v;Zxq!XyU3A4utxUu=WU-W`Yj)Osekb}e_DpLiY1Y*9ft%B{jx3_w>uQfLw5z}B z9yCZjb;XY|%3v>I5+P6Ahb)n`6mR>}p7KXbs&y3E%E92c5R?5C-P*4!p2@0~0^a0V zwQ#MMZOxodqJ(jdz_Nx3i95O5R?5^Ho2aHU73IfiOyQ*NJje-qpfcAlxJvJ*OJ7&X zr7Gv1%o_D)5f!&(5Cs!XLC*XjN44cef4tK6&bq)Fa8i!7ho*nQ)}AV&Tu<2-$?bLw zgDsJ^J{4!U7+-r)U}rOPN{qE%!=0>xm}4SSSMz@7nYc3N7nTXWMSuPJ^#gtp&;#Gw z>w5s+=2!ps13(!0jRO28K+*8B-wN+c0>_w@>dlgD+lF0(gi_DKDTbJmZ!q4f)TU?X zb&LYrCTF5TUfO#M)7>D?u^G&8}xi>yCOvxol&q%SAUqsTMhx&w!_dOP}RCRhG zvx0Pg0ZE+hedpbkEF#zvWjU64_zjSa?ZkkU-_)%Lo+YV$kDjO{&)C#Tt^l!xGjih= zjcSTL_*yIVCpJ>^RhX=UBE}|x<+@&7SU05)#Sw30^^R!;I`>rbG0&o?{3E`Dc$g7` zPN|>MTIAd~ESfnPh2WH<=h%HEs1j>DYDjM@+y+`WGJy*U>n2=sD#zcWaw` zaX595qZ$P4uf(AXL*q-a>LJ&1;HL^&lc*A>iQa#*?kT&EsjrE5pDRof+c_gmE9YdG zI^(W*cZTiL6`JA#vg~83#f_6jV3y4e(i6C4QDoWt=)dbG!9p(I!i(qrY2iu3y|rr= z^Ui0id8Y?8l!H#XM!MGMwD(Tu0W@v`z*@vp8)fTyG7>3Q@8M*}VD95|A>WkK=}t|P z#j&u_d1aQKjAaWXWPE??XhAJdb3jEczL08kPufnB$Zy)ZHOf?p~?OOgmp}cPI%)66%%a%RA2w%wH_3!}j#u63!y17~K=dAK!@! z_4bD?6*L~=GgtnyEb~oWheL|84}d* z!)K9tS!+K!FTSM{DQq$(utt8xdh=Cl5TS~UvBP4*OsK+N_JA*mZ~5J4{@)alH)8Tn z+02Po@C>JTE#}M#0hBlH3y$U^@6W*0w=~*t(|ek+Ody}pEg6w|M^e;jCvd{ ziNst3^|w=?PJGk@BJa}0COYp0VOt;E5wFDro?|z$QJJ{O#PSGtMr-$T6_dRsWAaR# zO}2XiWnuL3ggTwz2oI=UI8~U=DSl+@*jIUmBsoL|cI5zC=xhD8^v?3$Ii4#&ep4H@ zN;G+JbOqq|8jG=VNey0a`zO6}i@V2a0P!=(Arliuv^GVv@*6x3DYLZM?pbY`L$s zCM#*~9x!%2yxd;(fA}t_cS6QEkNCmX{MEn3WvA)Qd0aW_ z$fA}1e2SvU&B&EvQJl8D`s%BEs{fe(>xaJth?nsE1fYUtsBaud5@(WuaSUeaGXFHT ziJkLseeN-&9MkDZ8as7!J~8h!-F9i2o zti((cxXSBbCNmpaPI;m4&FsM)v>%gc+NhuM?)AL%d3?#7oxY;1EZv(W8?)qlIdebh zKE6m-8xJSpit@@Q(dc%$Pb2X@(dp*YQ^qBHJOyW-L zj1s@8%ltW8Fc~LyRz2s&u1s!it4Bml&cxyPoGtc=&zyWK`aTzCYye$dN&p@maC$=x zalW@ZPT@_s1yQ{t#;i~3BzXUO03TlRDd79x|2}^$p#1rb0zdoN&yeraTYfyCXB|Iz zDuo20Umd{e%}387>4>bzP#2|lbvwkdI>8D>djWvS%Zd;-=L+FhJniKtFsFow(Bol` zy!?}tlWxgMTe?vT<)k58!rIv-9uT?!>v#~%4^c#why0ncL z2PHp#sm3IBrC2Q0v}!1Sl{1e$QlM)D{h-U#T?v2syS(T`Y%*sYp_LWVn)K;xc?^!6c+6X`m>G<^l99cpU5j(EwK8&D5UQUuGq>9N zr6{v{fQ3L71d`0XoUr8rWF^GGytm(i+_;2}?y(ACN)pgH;)Sn4+ z9}sQa57?f;sAf)i(R3;m)v~SbP6dDt~)Mce0vQn%;{QSOb6svk&Rw_qKl=6r6QG z&YrR}!#JJ-a-V~M{@ES0%ct6*7SJV!0^(#$ayTCtnAj z4#|gfH9te$@Wkgm#`uOiF4V^s-8s@uziXTsCogN~p&P$uJWWKDyKeH&dC(m1>4VuB zqg~PCf8r>|w!A#k`nQrudmHb!2AXHRxoO7j9=H5XVg1d9LQk#dv?VGvSF({lPp*4@JBK~|CcVdEu)VfQK%rczrVJz+p3G;+ zoJ+G#cTCBdX3-8@ocTrkClM~jmwHTw;rD<4_aA=rqaW!%3i$fhzmAo9^Y}*p&Xrq` z%B$P60xCXYV)TC-biof*XO(;l*81UgrK>g7lN+JD%s|B}s&%38TMHhk0PyqBif^0r z?N^wDb%sZt#VrhDGJHY&>;|zG*gRp2)<w72W88r;F zb;UMi`)SR?w%fu(ZR1BAp&{?y=J0u0w0|hlpNY*L#09p_IeW1w+G39Qh;rI&h(=!& zgG2YnV$by)itJ6w@$2=WvT{l9C*F0ykB-W<5*~eO6S){-J@DMrV#smsq^7>&WdAX9 z<|*~zkX}m-VdOR$YyQMH1%5+7j_vmVs9<*0FNVdcp*6lk9Far8Q7aFi|Im@0n12dQ zE*kYBtzH&gwTdPIaqFevk&8@C(E`e9E&atI(VX_{x{7zji_faP2sw;bcu38-^QCY^ z10R>tjp5dknm8T@H?uZ0y!2o9A|5xRHl+RV22MZG>LWw07INTgW8=+7Hz3zaCpl_q z&9(Ag{a73dL9r$d;2^QZFS4zRgEL~zqy3Ol<{6D;t~iP~wi4BkvUOp=ur~JR*k@q@ z9c;y#$tg$g5$yMR6-SQAk13yrZA{r|CjfcdugJDoi4DRTOTrms$$>7-KBGPRY$Vm7 z*j8>fY2Q_T>3Q-ZXX8^tGhR%BQL;y!4d z)P|!VPL9p&2~>>M+UBxKnb2pvdaudPr;eMPIG#uPx#=rlY$dw<>P0vU!&o;*Ff?Qy zJXG?aeD9c)okPXH@+)rkBJfb>p4Kr3rmg!;0gd95j< zoql^Q;|*{*UCvU}rSVeful5o3Cdm^X?u@i!&cE<|&ONP~F{qPI=q5pI+7YWe=}%mk z!F02o+KXd4U6{keXr51pIgj(LE*wOtzEZTlC$q$b$4aPP@K^x^AW2AMv|U*>cnK za)_TsoNjPi#5lRb#KzySB{7ezL+1puYu`v)Xk2TqC*h5CMZK?~V;H#b%ROYqUiu1HqMH%v6ne_Iw;VZv2Rkv3jrlD?KgYuiUt{Ich4Zs0pKD z@CWV@z}UhSc>_+u&9H<(mIkvZllNw{khqkN*jvA1BPHp^Z(rMRESFq4wEy8!{&PLZ zDcnpUKd#L$+I&#EAF(K_$|3t~*>)dFoo|^UQ*6JUP`Sr$X<~|NQyWm~glzvYhY{l>|eYw4YybV}fj!0Ozq0wG^qS~vV|u9gt= zdbU@GRgS zV{qZic;cpfi^Kn<(=y@3B$_>nP`*6eI~inD*W_uu~tIbA^xJN<*5> z22EldFmUXaNc5Q4lP_Txb2Rp|wAdm?Gr8lL@yZszV5WROx1c>vpJ{pCf7Y{Cd-|O+ zV?;M&Q#a+A3-!<0gAH%w_=)(&So^n#xBW$eY^r_gJnkej9v|kTgwvVDVLrvAHg$F? z91IB=EbS-$$`-%yd9>%m?{-V`#{j9Jmp$?OgI}S45V#Y}14++#M&Yc`w&@A9o&fu+ zUsFOPjc`55(;^jw`3y`+)N_g_q&Nz-J?Z9`aX1BdAk*^aFB=(0Wkv{@%hK9`bgkJN z0qZGR(h-PC?l!lP%S9f|4jWjEC|pr8 zuXR|NCr~;Rdi953WmR6Bqb}lK+~5sptNZuFncIp*aCOCP9Af6^`~AyWySY> z9)Itl)P9p7qTSZVC<>n(f+92@QC0f^94Oie=J&n`Tt@VBM*&2D!Igs9g-Zgr`=My* z4+grBB-aJkO@4W$C&1M!EdHWus9henn$hrJXEhCkfbO}|o9eoy` z0!}Rgsd<$j>=n0=GY{7VglxWgI9KFyE1M88g_1Vc46rvL#IVw)XeMToi?e2cIQbMh zOVOvY_A-iK=hHA~lv>w72>-r$c=htt!F+3eK}0mEB-4d;^r=1*V$xS zp3&NG>Cbq<8L>+f8_U!!*5&=2{ltG7dGfjsb(;gpv`tRx@8!)k&)&*N-?4bRaoo@f^LLa$l!T$fjI?pWP!O?9TxdB)pOL!VZ(8P@$mP#@{BBXSuH)uc z0neWT(1RS`9r!N67cVt3ij_|w{%TMcIU5!mqdNm>NI;Bl2KFnK;iM_~@noxk;pAef zV&_-WdXc&g#V-Htb`Su@VDvQAISjznl*!nY)>W2!5n1_lkNEGlwKHU(T)k6l$~l+^ z57v^LdTc}4kqaKl_3!$^mmgvCV64ia7i8jTr-2y8icEEm?&S3WlIl$)loITz4_aO$wbI^fwyk|0m_L5yL>IF6XMUex-)r_(yUye6;hj5&umNvnOi|qwp9ONQlbCyG`dG=LlZ--+YLZkIM(A4n{OXzsV z9NDjTzv?c8PO5g+Q4--)5AJlPOTDM^FveK#%v#PjHVV39s+-AmV4%C)Aw6*{+| zLPYLCka`+lwo_j2o;62LO3!%F9Zrcg5VddAlQrM{$ktVyd9`8H6(0FjD(OpXTKnR< z$(DJZak{1oNT(Z2<-HLWe$>8KH>Alo=Yo)Q#HKEs6T8Kh z-CV!r!+dURl`cb$7MF(;@&2u(W)0y@eUax#Tg8xiVyB+Q3b7V_5@jAx)MU&&wyE$(0t=K3db3RD7@O#Vn^dPyJJPhJHueByC9D`pR4TEjY#hL^T3gXtjSu@i6?y(%!47S>{Tbykl-|r2% zZ9T`Z%}B#WRbB4{S!4TAAEw;`wkC9sR;0bA_y<2)i(A`_4NBz}U8+b;jNmyr zNB9n%SXZ{N++tkW&KZVyb%hez0*K)a=?_iuKfzC+o+V*KqBfHFLySoHYz9*28oasXRC|y1xhDD_{AF zehlzi-}=_$YkUJBkM(_YrsKoOnbMTQiiej>!9riiOH(rp`7V>P=30Zp!gnRj84U>* zE1Z1nst{ELfaDzkn#n|G7K7Z)FpMl| zlh~M3XLFU`#XvtX0Go177&loKGI4?(8xTcbsp366TKbXiWu>$rofG;_mc}lL@ zQ%(E9cz$)zJe9ZnscZx1sdUaK0DA3<;L1k7Lj`0VFf_#hO1zCTejY`gHIAwL>i@j3 zHW=CvkM*x;$svhEb~z-7B_T9kDhpAzr`!%GS6(6OHBKfQpR?0H*;Vc-VZrIJ>Tpi> z^ZCfTYS$X&x~+7#+>&PkmOP{R>0v}4xu3Cn--S0ZIVQ%Lk1*APiO)QKlXK34!#MNF zT%9R=u4n3822jm!|Gr+1IwdxCv1g5w263`t5{jVbePih|gX3A(ki#Vmx#QN8WH5Oa z@Yp>K7B5elw3@#N=)(^`e9KP&c=Q86BYtHkDW<<|VPu*j*}Tk$`Ob9g7P;xYfmqOF z8Sc2YdPckPNy?2Lyc0Z0h#fXgCE}EAy6DQW{WI~Cq;b&A4N4_p&C&OwNZL^0 zD8m~AadQhyKT^at^(2X&^V3FMmT2OnAE#-{8hT`Qs{m#jz1>rf$4J$Mj-dR(v>%ks zod`>_kf&EHSJ>F*_#Do8Ep+l&nnb^1iH$w-LI1^R?c%f?EIneIIy3FI;9|>|Sn*%D zx<>Q<1jDj9U(4kgf{|0l5YPafCw9!oRQJFshl?ZiXD+hCaQa9-l>(b1rpZ_49%u_L z%HU7^i9GLb^f%wF=j6U`4eHa4{Q$s!0(g3Q;&LsH7 z8Jo&ZKey3^RZe+wghx|VA4uhlay5`Usse3yHFpT8av1f}b30T8_6d{okNhAtX0cFX zy6K5fVt6XAlnRQWKH&ftA=!vyfuJ)Qp8z?*{wfv@)dc548Lu3`DeTn6hETF?4l*Jf zKLlq&GZ1YIPtKFjOjOfCKh7TY@2RxWjTXErYVwA%Y?}E*=sHSr=@cp&{F3Ja%jR!* zQZBI|r*a$Q^k=0ZF!GLPTn&qYyg7(rslfvCy}>3XDAE=%t0N zv9xUhq>}9?XP(Z3J!Tq}&`KD({z`qP4wxa!JJIQ5rdm6O>vdDJrC^;VB^hUMbEZ+# z6NhtiHHD+Dt|P{E7aX<9pt^cYJq7&nKoT8pr94V!4hqGFNta^`ocnlx{Qv+!07*na zR5TH2YZk&7B5(Ljt728$icapKNkqn*`pU%wZUcyghGe9D!$8uGR|w$%C`<;a1(A*4 zKzsk_2Y>)7Qrts~dU^$NfE7H;WS1ig9> zlqpQ|i9p*yGR53SNH+DN?3Hx@XKmtOIg%r?kP&7MrsxHriLgLp<`~=5MbGid=fqC@ zvK@JfDJ#pkdu_|_oSlW8@>Pz(WIQ=$fzX@yypc`nf>*-A2^DXRRSL z$a60?GXXQXGUP_k1ki_zkhT}Thwv46qrTFW<6PzDIwl)eWs{u7o8#s+eS!@jHtI8{ z?MjXh$6&Acq6=pF-LnxJTlRST!V^qn+B2tb{7=8gr=9w61`{1e;!k^XVAAhb0n!Nv z-?I2VsoW0Rdh&ynw$56DIX$HjM+tz7mnym*_r10amx6K-%|=@~CpowYQsM;oxbcf& zv)`i5btHVJUOt=!Pt3B=>;5tM%(1YiZCQ5yPZMu)^yle+_Gf?gmfs=Bga2^={{sR3 z9tandQm|e4_%T3Ha2Rm$n>aj>SX1exeio!rk&i1iJ5Ptw>ExXf?n3684BR#=-5+7Y_|MmFVJm zZ}cByx*p&L75hv-xfj0VQ1ikoE-aUh_9;KEBy^6!JAwX?r;bHgGs5|Yo`n}FYXVQ} z2*)8=ILoCJR`~W23wSXqM#&-}5nkC_UqQJ$H!!AC7tBy3FdD=!dH%P zA`7JBKb-TA6K0ZpnL_K#*wq91H(6mzj>}*QvPXDyU7gEx46<~}4D*dMcxrVINY1`D zvfs=%*BxQru6AS&J}8&1`r9_%ugATbNZRxQcjoC&`;idf(Q?d_7yPrAo4`5I?e5Y3 zNU6BBa;0~7$g>~Hq3C;!;lrM_ZMcX#GI8V8>Bf$+Ijw^`{*XI0&XHVo^mXLi?3eT_ zU-nRatXw-^=_|M5Gt}9Xia+6(BR>ZC0{2F|`9AVz1D{^Jc=7aCfAv={e)hAUy?pa8 z{>^Vbee=KgAMl?7{RW&!$H9xNdFS3X82P@+g%tuPDg@+76Pa+re>Nl&doVBx1(|+@ zZ?ceTq)$lI2x8W)Q8JG5Z+saz=!Im8Gcn}Tc*AZmr6#Nx$E5Owf%(ebQEG=#y_O|arB{*VpS+4I ze!@65169In5`{*YS1w4<=5U9AxD^}%qlL3$1Wh{^69b)wow|7_4()oa!V_%e0mjY^ zVE%<1*E0reaaCU+^bLyfQwwi^usPXEtaRWfJD9uB#8l}rmWu`}a4rk|H7&UfK$Ds; zniK}5ulk^*jqWloi~`ju^_PE}qHpfDc#EfpkinN>}+B zpm=ba?S)gXqwAsz_&t!5*F@qghB76OY|PPWWo>Om zY7rPshEZVox<``jP$(K16R-GnEcz%PTKvjPJ*SR}^PnI1DXp>h7*1NL?5zbMpgAKA z4ssIA^T0`P&$N(ODFFq;iNZ=k+I3T-nCpo3zxnawKmOo!4`$zb~{$sqqzxm6* z{L43g{KtR%_WR%e{=-Y09`V)xN>X&kX-4lkC(fkNss}pty@73Zjky@8F3c#;iR`|V zlHi;V;>&4#ZjIs3c#Dt*1mb8IAE-)qpS;T&lM$fE24{?uoAiP-ZuKDew2v|~yO+|k z4Kn!L!;|khn=|8<10VkO-9{qzoc6)N05KYk5g3dd9BQPh!O-a_ytfLKeAQJDjFEL7 zYqjYu*xU1&3N_Of*+`#*SI$CD{YqxdRykz9$4|a+&v=~sCNUY=uO-tydlQ~B*5oy( zJ{5qvKMX7g^3*+u49?S*J_?X; z{*Pe(wjg{0@W5XLzct&nNsTGy5TbV z;ksaJznTsBvQ_V0b<&Nz8iBoF4#-Wb{DiN4W9&K}b+xzB!>x!iAJZ&rgE)2uT>5rq%_ zjgP7P)X$pV!^DMSQkh{(r<$lgd7u-7wyYm8lY&C`b@)fu-6K)$4a{@|L%v){`Y4#P zl?8Of^j@6F-3T#g3cXDQfU@ozjU=G0m2=C>vhbPBo=2CFJc}e+jZ#2cbzhv{{-+U|2M!{w7O8VnNNGCaxr-h z7n|#3@$5k)lFj)A`Da%p^khIVWiW!)657z6E~mla%&m{R%mXt+aUNXL0z2VtKOLv< zVY}~RW^S+CF`^*_{V3aiW-8oEFNNqNg1SE@ zr3!LW4{3u@8bw82g_I_kGT$BE7k3iOJg#iXf96P>^E|aDLvTxf#=BxjEg9)Oaf*E^ zfC+w@R^;26_KBRZN9hy-LL*~bd}}6%65;IjAYWheyPK(pZcO|6K#VZVloDm)qnoLm z_Gt?~<8!vX^2s{qVS4}ZUEZ`mm)Gu}`wKnjN9#g(=JPdYu>QS1A~{a<%Zon|@B*Iz zyuv2{U-{@?|Ih#G?SJ~;{_hWuFTT6^;K_ru{)!y4eiFo!mEtAn@bZqK*Od~wFtAu-K$jOs;`a9-K1cH1FhDfVehe{QMRCUTf~#{YgN3kM=gHGF@NFJo6J?>3JfM(G-<3C#>E_`O6?3Zcg?k>O5{W3z2QJ);djd zc!mfX*z};3NUN;?A_e7aUG6P$pCb^?m;5Hlo?0+~{Fl8j=h&0N!57A|nUaj1%S^9{ z1CK(P(5n`J`q7WTa*5To1Mnj1PY+6$+Jy*?_v1G|c=~_;{eS=EAO5fZ55BSgqpyDT ztFM3iw}1OJei6_o4EoHE0p_V;#Y|pKKl*bF>S`pmioa~smCt+XKt0*%)$&b9TIK;c z7^=0%hkc6A%)>nCn26+|431Po{S32BS6Fgg>Ftq78QmA!?6dU7&-2)yQ~e(Eu%3BQ zA6+n^i=Ogxw%|EVAIkP~6x+f?DQG^&P#+sT?;NJujd25AE;Ru{58-AD6~q6}-rFnN zavWJ>=YjypAU`R@kueS<6d^+n%y|UabmZtA^b#arM~0jU`QyqMb1YekP|U(-qXG?_uByznR%T^Y_wK#V&&5p+ut?DCL2N^2173J0V>aip zZp+&pbAw4QQIXf`tGBq<2&3sn?%WQ`Gnf7`!;6M$>o=qrDx>F_{eG zzM+>X-W@%6;=bSE3HGWO4^*RkqE0(Fr|slm9PRi{&h($YJ;IE5ogJ{x`N*IU00o%f zyfpG!o=jKU4*>Nu03Yh71K<7ekAHlpKLnIN6Ie=o5}~@Y(`82)TCn-be>^oMhwLkb zO@=Fpku{ygBehiLJt=a7m`k9iZ6BU|bZagFYYiHG2?aa)kq3T`mkt?IrW0oj2?R7> z8TK`GJTwK$lbiF*O!#zeU)4{l(P2T8Z!_Ak-wCdB(ezxqh@9ipqI3IT5DUE z)6}q9i5@>4haPAjBE##~W1}5=RuTiI^v+fCr6PktD+}YxfR_|eh(Ohj&s<|Vt z`hUfx52t#Mzt@JI4w#PGAe&8dtXa;QX91RV=kAKb#~f9oaB)4d@1!7$U&7+BYh4-u zm9g=TPIKF%>I^7SoYF~MJOc~Xs4!hu-v>;y$ky`?*sd#ZIa0bPYG0X<_yNzhHHXnj@wK+htfe&qXPh-4IW@h&3a?2kO3`T<}X)&It(4d1p{hyGP!vxE_2uYwG5)0{!DM?2k{OgVa^ zar#A^;H3lWp8JW*xB{fR=tmC#d}a4c_p9Uyw#sIrG*!5s+k^>}yF?Y8nfXTaY=Fr!07B%fU^NBURjTjTRzh#?MLU^>?mHJ?W8j*~fNjROW|& znpu8iTf0d&0OIcRuN<7lz27xyXI<0O?1&Ymoh1b^30ijKnC|J>>mJnECJNb=L*LFU zhk46)GWT)UufV`R=iz=;!U*m-P{TaOP#8GsfG4?PJp15;2m9&EIGCU{)_K)?S@mY; zjD~R()W17J<;;ai!iYMP#DRJy&{O@cr{KhhbNJwip#Cu-1;*$zr?mN}q! z84l8fY(C*KMX|d=8>&zC6=pz+IoVka`K+QcZbmA zmEE@qMcIO9Hzk3IJ$#6B9FbZjAjjs`8cf-S;ZVddahrdGi4K$$E)Nc6as22ILYp1h zBt1CgN8C;{9lW4yJAxax6?*qYygf)FBIwsw;-sC}?uSzZb#Yd&^+vG3n}5@}iI*qV zpqZYv&iS5La7G44b(RlL@4@9szQJw7)H-2zCs5VQ?Sr(n^l7arnO9% zW8<=pjKNSdo;5pO1)CaeS0^#1@Hxh*=5nrI z_$!f48}+0rPAhhh4oF?w{Ha1u6LWH{SDeo7>T?a6lTfn_1~TYZ%iI_WCxhDu+%m(< z+670$8bk}`9LpPvTFoS9qm*9_WG9ljynFx6zkhiDhdzX^ap`1b*S2x$8)0RQVi zAL@qy{ciz$v;L)^Z2YZ2BMyQQ6Pt=(PimP09O*N)aVlTqXzo2ml4#SmxQVwc>iOc~ zAeat6;+;OYv`j@6Av7i+d}ZsT!XI-pzDp*>q-CClTYAH!F13ZX<^>{w8!zW^g(o_t z_nLDF=r3m!iGxf!Xiw+mLIZw_RNDsEv_!U>1GMK_VO&RtxbX>bf94v2jCe^px!mS? zuOq7`ZT>SPeZi$xA>7R&xj5HAG4b38SSR|+3vKu?C;YxXW6`kY8Ijx!3A@e#k~p$K z&vlVkXMJlOp;6B|lJ@}RS|A`bupgZ8f^$Z)Q!*JX(O_tSW*Hjgar>%su61GovuVZP zJoD~wfjSD1KBTaH&=AqmA!A$PVWYy(bX=H+mEkdtENNIr{)I%8U1+Qsdm0Kq*4rq8 zw7v#Xa0DoG)<1}@#h6RiH8F-Sd!g^~$kF?wYvr-_ual2fa(dFD9{dY>peE6>br*nf z;0GHPPN>W?EbjNQ4uj5b8}_#-6U8z3-89UnWNGRotYBRGf<-|8uxhWPDUitZr)xS{ zuJr*lbLzPu2*?xwq7KKGJ;@XxcA@HD1AJHi8sIxT0O0HP697RUpDBqG;=giq&V@VS zGqudI5kF&4TfAk3^ST~gwZE2eAADuaM@QTJ+eo$+XQaI(HZ{n z)WLl^vr%5UqiX+#m{z(N>9$$D&6S-Gk|$h1L;7b`T>$9b>hVyL&U;hcyyo^z41e2Lr0c2;L|)*vFrXgEOWmLpy05@!SY z)5jfC8#(sAy>&vX^T-!&kc@Z4iSJ|Dndi=1p0&ohI+V-uFWza(IPF57y*Z!sgPH8v zkN>U(&QH8t3thDnsae3X=7)6?Gb^ZguvSk4-jCe1;67T)GoJPckrV!GvZrsC>rp=d zeDTE>?|%RL-@knM<(K@o0PrmU+$8a=)ZcUIC%H<0-w_pm#9DL_2xF>?+YQCzD=oC$1#@X#QL=3o7`Q;ok<)w&UIn+7cQja-UokTIb^i@lH(=Pbn4JNug%tK8oUSgDM?BN~Uf{24rxm2$#2?1sPI&JNlO3j)~Qw)YiG?j>uo*(fYj#>`w zY1SJfC5N#Rsd&;vozkrk5ooqmUHmAB)ki!eKtLA#O(q zT!FZMs+;^_HMFxu4eS>Qc>vV1+G!~uHYI@oNoDN`*DGaWIHQq80ze$e!+_0&fOJAn zrG*;+O#vf*F&E`aau%8Jo)eiQL!^9FZy<`oFxmhxlvVF4g;R8;QoikGXKn#`P)kUS zeO*>9+nRkk_68Fj_134mV5B^A77C?2sal3(Pt}a5iL=)RB~1=PO#=KR0DiEdsW@}A z)>J;ln2dfs0idbIRqa%Vx&_gv>#@87)EQ>adDH`9Tr3L}O4qp2o{!VZ2rMhJdk!lO zb`B;j-BGl{a#xiJSuri}N9Dl8e?IU>{_yYp(xgP)mdf2v%GxkJp@dLa0X@B61 zIl38B0E0L-MNIMO5!M|nzEj{yG(w~Ghz}5atM+RJlW;VGMH}0lu53Z8&{6VVB2~+!kW>yzgni=HEyWusJ$uqcUK;fLgeFt~}3C+GTsLU+?@ICb`VhM9@yUrDdCHu%5irALhiNf8w}T0zTSc!J9gGwzA(N<>mW1 zcKPxg!E3nU+gAq611~!puiQ9*zq8Z%Cu-i0} zf@ul3amIuktrdz_7Kr6py#+ga&X>~GPhAKt8)WRNzC`&7T3wDaXBU2AvL*Dexs&XEftbFsZCrPw*!*Fi8gFmn$CZKR_` zUm2kn-{PB)eMo_ztdRRi`Jy@ZBK40`aFlz(3l0&}rn4_!YLWburX;`b&(I_ zo}$T{#<33JlWkve$lA^t&_=;M7uXZ0*R$8*$r_hT=B_!8nU-Lp1cOU~{fd`7!wV+k zM{P1qo}5#Gsh3GOGOTB2H?d%^S6Hj@a?zw7&t+fGJ8kpq%9OCorwdOzP$SxKh-SD z{J5s&Z>YNodjdx@svksFod6@`n`n7)4sTh|o7lV8!|C6d`-r#(S1gA^v-!3(JeYyK z>Cv=YiOHOLv^CzyQ7w>oLC7&P3?glERONzfLC!$c+%=2GMSsMDg7V9n zMDx^{W9=Kw5E*usbZA6;JEE#~RE~xd2JUH_3Nx3bsNV9Wr)oXZo7%Gc_^|2pef!m5AfYeg zU66KV2Fs9Mv@>QKrHYlV{TXt)nMBXshS&oh+PXspFdWszrv<&2AWp}=1!1;#OX@ z!Te|G@qPPtc1ptRDJG{Gr~6@!-4S1Sam9`ryyaMUTo(AR5_Y`hyVg?}EIsGAg_^w0 z@$%WHpS}FFezpJe&p+QCHR=Zd{A+;qZw2#r1o3wOa3CqX8mPcD)#*{76Bj%vnjtI@ z!wEWU(0!ySfX;nWz_7kZPcD(lxLQY{JWjblOqM+h*eDA3=#`Gx6=+W7(OjgZxdh{p zU6Sjmz#4$_OdQ?-#5ymT-bZ$;u?}RqF0R$m3*1ZWML5Gkvv=Ie zp{H@oIoB~*-A@fB7Bz0#nqj08u45E$)ujcLN)2O4 zZYXjc-0tx?%J!nz^>5_OD_XEH*u6`=KEa)*bW9@d0cFr7;lDYTFZu#5^ z(iYUzy8{OoU+||r{?!JVc6na!iG%Zs6P;y=&eb9h>|q6)@gq)fXrE#3e2T}XPs)tF z!ZGh_Bqj@*D@SnFG5gDE?4V-fE=~1=r>_Ru+*e-;1Gz0;4RR?^tK)U2&66kZ#LPZo zWIS1v>i9rRFZz>}K3Kt>9QY<~_9rj>=|45^eOjw^zuj{|^r?e5IHr~?`+54qpS;*6 zE(&+H_|k3|3@q69o(9&;+Bat@1-k0Q+m3OhmYWFJ*cU#sX=#lsZFDj=7(@QpRJGX0 zfx#VUx9I>2z#EPeHzZ0QqlM5|*Y>K)WV|8Z_kcW$bmv3na|RQ$@_#L%wU>dM8t3Sl z($0H^eByf|^2DVjoPh4v+^R_Z?Sc+n)ggw?vNpkp^ApJ?veOR$Uw!ozcMpD5pnh23 z-OHC>zx$k**8Z0f5^F`u<;T|1WApP(p74s48~jQmSWM2>GHE>#Q9NXlBr6`wb+caP z7M86YEjO-`jYlMSR3^vqL+E4m4_! zRJXLkR;E?llBrEHu#Fh&rcEZ0Hlkm4%cKRulch3Rn-l`zkjKjK?^H`>E<}ek)ClFK z*n#Bbp7C7mG3UTa0V3Hvot*v1wBIB|GTaKg<^XM{bN8+X9NGQaBrI}fHCRLZXpMjg zp8lJKB-BoZULGo*9@BS>T*d97}Y8JSGvG2 zUctEtq*Aq`@5?%^PyxFQJSQK{6pJWRxCx+$6JVNjV_x$|W>o1s;H z)K4&+BU1h8!z8`JNqYQXvgif*#20YwE!iMmab|>y5qyFvS41x?oj4`=>f$I<{m*&T z$+cD;=vNG~IR?cSh~iMsC9|gzOFVBD>dKbvrlbXL=3eN#c_Eb&@V^w9#8z8A{SQ+F z+O0aGh(5CZ$caX*F@BI0FaEBH?P4?&j5>sY)rPGH#5@YO<{iEom0Ma|KE}hz`dN>T*MRCE?uYtIfbU=GF9E*bkNo}fKmRkn z8q^N}Z8YHgwqARJ0q z{by(7IpE3Z8AZNa0c#$2oHh6Eu*!e;WCy4M$qEXo z$zD@<<^i?In(EU&IqAbc@v*ZlXZFCU(=mbBNLdpZcb?ayjCgrmJfK_!+<7-&xqwfM z?!+KJ#qNBD-MQ{;L$$kixa2;4dw-5v%AHj29&>L!HAYR!H94~nR-#=MzKbP$G8KRZ zBCe=!i?{GA3%|=PS6+6P@4NMqC8Ldy)X(@xIA%uV&GZ0tDnX`|L-$|2uEM_intIdO za=r0CGxY<&KmF4`b;Mu%;ukMp*B=5}A0Ei1bHd>rSRG;EdrAG4Dn_&g3xx!qvLB`` z{q3zy3Ccg<5OI?BiBmE@o zJ<`(XjJa=i46>(;;WK8mI$jKgj}6>mW{k`eISn7WJr(CWWip4}2++&4fa~1>?J)P6 zD)4@NC7F>#y2TUS^Mw?A&aHjbLH}|LBY8MI!h*cdIY@qgnRTIFM4fjy*>8>ae5(lM1z^NTA7=HtoCelsT;&XjeehvBj%Xcb4g-INY3*X%t6!h!?C$X~ z!d#a1oY|T2)O=e%_Z-E5{uv`W%g)#4t2vfSoBW}WK0vy&Sr^v~nK}b!4>{?JN8s&g z>Ysq+^L=mtat{>-xgg@o1yIxqmZbx$Fsupu8uq(3AackDKvb$VKA1~eq(_iFkDVzF z&L=8*LhL(eMcSF!pNOIULMlSWd$iN)*fwYH?U`$odOq?^`xX-e*GxOA433wXJA%wf z(SoE;@uUCTKgEE=AzOA7Eb%O_QQ9CdZ%0%o4*=Y`WIH{g^UelW1ghIZ+xC#9H?X5i zK}IPf>?>k+kQ}SVC%ZT?ncTTheLpSz-9AT%rRWfr_|BVEH)IDaInd)v8!x4$zd&+w z4|~4_u6D=wt4s$mznUNyf43kVe689Bxo}wpcz~N&O-IF0?qPprWvD%$yU<4WfH-wod?oJ(;%b>Rt0lFN2K zrZuvaWx7Hmnef)_xZN6euQa)Cq)EIpRy5;mg_t-+OEs3Pcs2 zTI8HY=E)l;RVztRrd0P=GBTZd4OHIA+2*`9^}Gi>-QDMSvvR%9BI-GyoDsQw9k|aG zKi~KBpa1;v9|D3VK!5tvpFa8e)BICZB{mc3x^xEW(B96@Z#k3v_{eI(#m*QDntm&J zQkXDp%&U3@3H`}>SOFpW z=3uHXWnI=!KS%(h=2Ki#Ci#a+(`<-POVcvZN^tVMY3boa` zlQ>J`PAfCM^(kDgU(D~U?b>67O=!{j-msEHz6N#P)hQe58to;6o`AW>l3xi?M(b8C zGV%t=*M0&hnN2fu-6374js{|om1K8eT~kJ z%kmH$d|Kev+K?qt%xi+uM=p5jz)M7OX`hP$pStCtb78>`FSXN{%NLU~>E_11y|{P1 zUAyc9gl7g+QZM5T;{di{KdhXSZ)dYQ(85=JuN*ym3jhxQ^XN|irg8Q=pJ{xhKkE@b zD9bME^zD+*J<@rM*|juUvG2T(ZQ#vFr_O8RC`TiBU(-~NjTO@Bnug7~j@gGbV`!tF zF?_w}U@ylu2B41E^Ei3I6t6YABkn9p=0;7rVNq7N9N&5XD|A{gRfAn;X|A4fJ;#YX z?NW^=nXd8dfp<u%*bB6JQvry`tI&&N>+MT=N$EO(kIs91f#)-G` zt@S8izB|i=d0!Kod7x{e_LP-JlF<9`ZD}PywbV^AN9$Xs!VRC5+Y&h#;M@FTFuD(G z7Y(#ICQr6$+1FLMz`v>o&OSPF+%r~)SI&qtv$%twb-BaH1|=!#d{vfZ*@26G=C-_# zBdx4;jZe<(E03i!eY9Q-!p{5IVvpX&%K&X%p`OsTe@U%1epPtHxapqrnUG{LZQs2Q zwe^#HcRH5`06Zns9|9_7{e&H7%Gs(MBRjZgOr@{|)6Xu@ZNhQ=Bvn5Q!Y8n50_XD# z`FKn$RUmT3C+m(~ozX{E$thpCR z9AjMz0Y$G6$`82Z-HOY?OBFuw1d&%L+9GVZ_GP2h`3Y$}8Df^R=5hk9_ zC_bri2039JYF>(oHL0)n@Bj3!ehrZ5kN(#Hw^)fXCOS;+f`M3Q)3>X}%!0!x$ES8J z%5D!j%JD9}Rs1_&Y-uMCw&cW-jrCC(Vpjd*YVox)Y(l zbXG5%#Lrw~pDbKu)4yv1xpbokofEgTpY5%Qy7s3&yotQ6J&Xm64>;u#i=Aw0&C5(r zjpzQ-{_*Sx2p@{YDFE>>?=B7z6UXM7gV_gej;l{TY|Il%uOHw{ndGpT@ZKS^_l4A~ z#lF*=3QOBL9}%YiE&VgzYS=6J~2+s@o zpSB)%w8}ep>j8tOt-FH{WCy-ql5gs{in1avSYp_h;Tbr&EaF0(zG%db3Y@(7%FcOe z!qi-^4CT`w zYL=Qal5<`BI?|YPY}pf5sbPU?aX3yugL~~Te&j1+G%wd4T_nEy9zW%~FfO)d)PAbL@T7weA=JSG(J|#`D?$vS(S^k#F1bwy)KPws~3pu2N&s5olmE z_cCYK1>WIFL7WfoKKu03{y z#<(K!T(9fo`+D1&4UH-cr+50AaOn_b=v0{f3#n>4{aJM2xH*QXKAkRuV{F)~a9ftX zh#I4hp2ez7PsGK-1*iX7vO7}P=Md)^VJYsB7V^2fQ zG$D{JHC#a2Erz}+3cj6p&sqQ7E23i+j zYDEv9LWq;SSl!$CY`F|ccW*gYSkMnWZ*?FYm*9pHPm-Rsh)=YMxDi^W&_aNRwxJyi z9A`nugMCRp>wTJUapuDT*cj})+0JuCov-KR>u9DxzAkN7UBD&HLJni#?|cad%&BGHcK5Y*o<{MBN%m!bO5`+S?_wgAj#r(;%e2nCfepb} zy)z5J{xQ7FJu#wE1JcrAd5`vy?uxE@0S z&K_1L@V2?I$zv0PuL$s+_QP7S(>FIAIAIOUtHt(GA%yKQ?BOmJ&$jpvnoy9Ee7#7G^|Mu73R zBtVL{sPbh!IWBkAuF9fO9wwurcIPEN_ga97l5m?nMuU*|InOzUf8#IS)f`J-_MYxYlmC8^ozCcN%fl!{X=z5V8|xy@NC`qJJ3kSw(QyLVXd!lK}UxB7P;a$ow5!` z8?;v^#6vGL9K7Y9BsnV=7(ihKnwHa>zrX$Jm>f`S2Y;#UL&(n~SMowZj-a@sUt0?aBVFC#eQ(Weg8avaOqt@FF z{fdA65Fr1>-xx2y1rW!}%lkudd6a?Um$@fz$T^}gRm9bAqQ(|$tVVhn(w8siq!F=5LAd-WNA+RK(<+ECIa#Fo6B zk2v9`eLnA9CD>~fu;Rg{O@vijc%lLCi9E-_p7y0Iy=VT3T~}KeiLhs**_=MT_&_7< zHG}wOv^Vx4hEOwHsPV0U@m%pIzc_ca7HDTWYV%3;{8r#AN-g=QlhhLF4)@Fl{xkp7 zyW&m@#(7n`^Fi&j&j{bG-wy!)_>ccc1^gkPJ`yjLLISZBh-TbD){#N1eu}|Um_+&} zyx*^=pnnOex;MTRB0W6Gxu0kpmN9n3R9JY*ib17Be}l@3G;6#})z?4`eKg>Px;7!6 z?ip0)0vCvVPC-@ze3w-{D7Sc)@D=QmF_}!P9tRnHPDipx8m<*8{AIzb0O^2MVj96u zrj^Z;$SUfWXFl29nS((_MoT=W!-4RIA!dnVgeK&*?6kmcK_g1gal4j)INyMyTjOk{ z4#8DP?yi=9g|_wL}&J!n$BoW9Lvo)3ZnZ;~bXhDUMLCU$WvdS>M_#_m0~EzU^floaD0Q zmi^h(y%WxE#Rw`bS^{gbz2*XWwj^4;Yd@0FLx z#VY68dwYK^r0~$2w#i$H%H&zh9h)p+o&AM^*1boVeS>D#>-wGCGbhexh3Vepzeu zE6kMVtp+|Cv#xtE_>dP*z;Pf9_@rXk9r^lf`=DK*Cl%P!CcRjtrV-9j$DWKY*hgBO z;hQ>3ZO3#}tAcU$EgT$G8F7{BGX;-=zT6h0R732rv^D}eVrK8RIPyu+Ny zVQe4##CT5YvQowI%YJ*n4z205ZJN5@ zJ_S%LXcS^-aabqj1y`*VzorfLe09eh;NU&tHG#g6-7Y72s1fqZ{7?bBt7Kb!ynC8s z+RZ^a!U11jWylx8q>uRlx7H#tVJu$*fyz;ia;7%0Vy>Dm2NEp`tp%q(fOP~*TlD2p zV$s6h$NYVuw?@h#zM?3fn9;&W$MW@ho0wdnyQs3JNXk846N9F?*elN}8Q$NQ4f!{2 z!@yk2QqOjUi!$$3x`y#@+1K*Jqho}@V%Bi^a^I1K$W;rg&-zERb6bXGl8n{^d0;;0 zS9rA7fSlks=KPkZ33JV(xoM$p*8`s*z%7S;e&s?*Mluoq@bdnf zZ(jIweM2$b=br$ShE@n-`!OwR6`27!@h@MrmQFCcWkwVN)eIKir5Wq4kkP`)GRLT8 z4s`SGD>g284d|m$ghAti%`x<&3%waHN=s#VHM^ZRa8M8ZAr}qM zdo|my&L-VHC~AN;i8(F2I$%kZ*p??6)3Q)kwS~X)Ehc*-?40&it8H?FzuAY-fXwdH zpZ5Dca(^vaeO=4^j zfH5`#JifEV|8ecU9??yFjAMJG`@|1dOBr|8c-uc`jG^5+C+226Xe)osbPu-yZ-hSH zbo*<7^{0UA*8uC^0^}2D-(C)N*z3R(4-Vza?kb{J1AE@^%ld3{0;q(jxj9x{6rs+! z{lPH%7;iaSXkrd+Q2IE1bKH~AoSTDLMgPVXT%;lcduYLgKHnAaT?POqrsg!6*u3-U zaqys%989bDu|y%BSK2di!Vj$s;XCp0;S2HO>s&yn1NPX0k!L^8IJ>7pXkK%6PvB$k zof z>^I)En9o^^8St@hPNf;QMthTIgGWcXj~gl8j;CffIe0#~E;8S_R!L>D@9tU10+`^M zxAHBQyz%t~+DVo`JE2&|-M*3M{=DK1{~_9#va4S;BSx=*b?c~+KJgeTTNgY~#(vrS z7#u!|29!d1Jbmcna9N^a8=Fg+WX)Lu>pfA~_q|)Lnn3EXMS#YU98J`$GWBDEvutpU zAxQ2L2nrheQ5neD9VBdKXdF6EyXv!|A)nmKR-Dg1`~1UC`RD!jSQzyu0RACBh)C%D z`pa&N4eIO((9|h7)6SgU{gjEKKH+78=O)>h4JzxHXk*}yU>lFl)R->ljY3Wr z`-d+#!M;fV6z$}OTvDqGpQ=2aDRVEjm~r7J2Beq7-h(4KlEL7$*n$?q9eP zxA`NL)Y>|LCi%3XoieZoBcBlfc|eB0(5!BxIdAJ{o~^}BR31bEMq;7WC0pGNU|zhD zL3?@4A_(P;=d2m*br}QE4+4cJuY4od>VYslam*+Khi%QIvCEVd8X>K$%Tkq24iOVM*OEr6 zK|i<@CAYzfU64KSuYUC_{&T>;{`Ie4e)F5(tOtNSuh&N_Q!%Y&2*nlQ^37>nKFpC#^TFzFKao)9}H~>$& z*IXX+S6+`X@Z9AihDvbfhb`+HtlE3)!YHd~o;faDm%mMqIFD)qVmRoZvB)#|^zoW9 znR`puU#n!uOPA!K(3-=B1dbzn7Utv`M#k_3M_&MN)RAHE8Oy74e6dZ;>Z`Zir(1oY zqH(q}#xpc<@IS&t=k%ZBGk(V5XN*XTi|aBO$P@g+fVq#B*2nc`OdOQ{*QbZ_*Fc!(G-#|+$ChI>3F*1e_~PdL;Wj? zg{~@KmWWax50PdSUQiIgQ4aX|MFUT?RtojMeCYX0bIQxi;#jK<)bJ?LG%U@^+EXY~ zkhYh!>W4|Junnu6m@{XNzsH@g!XhoER?g}$Mx7k51I?g}KLTl-g6%3NOuK(?9$SIu)E#(6LqVNgW%Dwa|;2&$@+5O6vu{s~;6 zpaf&JH(z|Ggg={GU;HF4@2aSsQ=*oH_2G$LX?$4kxXb|sSd{}c5!V*@2tbE1k!MX0 zT0qWg6HrwEJyJ#2oKS9AwFgvALUE#SLCRcdluj11m5OeKTD9b1OVr%vWFR%UC3?54qIPoXega$`-hCBL?vK!aV?L^C%39Ux`4a_9DK5$TdeV z^!Qa?NVCsRsES+r7(c8h2inrmJj8{AB&1sZWxo}4984K7VX4tMv?g_yKH(J$H)Vc> zt~O~WJX>(;fR8&|Ggc)wAj-moOyCfKz~;1H@Y=@21rY*g&!1fk#p$^rCga-PiDDh} zRoLp)*T7cna(4>l=6X@d8Sn@HvDp1BfH)qt8~Xx6g7e@_ZW_7|T2`#D}X@!oOmC)tHv3$TrVV z%C)PVv3UC&mR+2xO*Ta2uW8XT-Jx(#m19%&VBY^CdBF|Q)(n`c8>2iSz<&DnagdPP zJ+OS-5v^xB&wP)gP1d9SWA=CP%qW@HYdVwj8uqdOPUX(_SmCvm><54^zWCzZ?|=XM zm#@D1>O+0$hX8A*SGc-9{G>APl4nfZVe!;~qjU6l!>*^tVKyUp$k2q-QS%muYYxCU zuw}YE_*4qdi67%R7ntj7c-LSWk z13Qsr01c^=lX!P?u^8U?<4BBX(>U^@E{!^^JyagYjl1(g+;a0>VVs={QIIVuG%+^ljZ@5)T%5?adctibp&h# zVS@vQI|#Mn(9=FbQkTxjouS!v2)64B@!+kUrW0B5;Sze?Cl+k!B;Toh!NriA7`Khd z0&U4vlF8HfyrY7drb=nnk;FPNtCGztZs!&s0sxFg9a1uztWn1&GLYm;ex1sWU-_fi z80Rfy@KFzMw1EthH+AWTS1oXuc-to7xi2AVkD|6zO6}IZ^)w(W0)kqvohl?#x1BSDoX@-75mN=Z|Mnzb9{>z%krJ^7FM2&PraqIRuMhn;1wc#4r_4Mh$xF??;$cw z*@F`U-#l>76x|}z8IzMpE{B z_E!ACw*j#R>F9P{3v|NH@j)F!AQc!D_Z33_RdvzCczYBvt(e3yxt?>hV>q;FF8)e4 zgw}XgD;2p!4%y_j#LnJbz!S5pTtiHacr(vuT7?CC(gVM<(PvI-JZ&g8H(o>|cGCiK zcWm};P+@5kJC)nD|1>w4tBl-ZuApDzsPH{sbVnZ@*pd-fFUS-xyUv z4i69Do&p{+m!og3qw06IFgmxJz&EC*xig}~b!mgSTln=(0IOkS;yUlVE1AN9(DrP8 zO){hB+l~r+_%a5h163yz2{l@7;cj>^XA6LJI*dvD?%^TOLx2-6WqJ~KyK}clk{Lqj z9+-Wt>;(3}MX__EAs{E(pz6exxOcwTf+tRpyOXB6_)oAvNM3#98< z9kT0O0-h2zN)EmXPMyS4E{!crYl^1rDDkG?8i@$F31VDH1-cq^*n*; z926(f#E@9u3|c#=Ds}jZ$D4FuT$37P%(mvUQ?^8FFbHvhCuaM|gIHb&_q2TWCCq^}ohGQ{j!0i&EvB8VsMF)jsmXEWf_JljgmuJ2mA zN^_%OS!vj;*&|s;1PDOcDqh<(zpg>}oJWJ8Qb&zTga5~6@#0Ip?Zne2hv-JZx#5e3 zr-Oz9(DykchpN@F0CPOoim=P6YitkL_xr1<3gD2z)(Td^w8lZc|K{I6y#K==KHveM z{xv{;l@I(6{QwZ~*(wS)#^b|tC!iPVhR`Ob-eWL5h*s-3Y}+x;)a|PYv!^W4*BFuq z)C@I?x0%UGZulwe^iR~?c*dLkXuy{K$qzm){3rI2k58HxH0GbRn@Ukpo6#L2IX?3R zGxLq+^r1iPvk(0_-gxEcEe+62rdasB3mm-VvWt^m0R)|WLaDLt^|me7mP__tP>Pn( zYUdmtVeahHHZ`OSFTSu_ClZ!9yOjre!2+ZH;))g3oi|6Q39RG;m+s|p9vWLswt-`XS3~9Fz;iJBpqbO=yk1aJPVK=)SQO2j zZMgr6x_de2yi(L@yPsH)@J{rueb4>NT4#1g; z$PWR2`Q?`{`AdMfari}YeZFH6CdPn;ITFJalw6!@H3HR5S0-q)hg0E;U`LJdYe5dg z2e0(ewxd#0TBRduJ^VP|Ce$a>CL}I3h%ZO`R_u{RL0g+N6P(;9ngB$Q3uXcGkb=O7 zYbT%5p=Y1uOrscl0;mwt0Ab0q%ANr~fk!4BuXi6n3j$w#IcMGF5XVVWLmW;;B98{- zVI$j_3$PfMA9PD$1Qr_T)Ip3?1eXOaSJL^qC(!LZXtW|HQ5_>#Cr{ z(!qIf$cPB6Jufdk>qI$tvbIQR&jpJn0^^}u%Ca405iDo?R+rGu#4_?bh~r{zc59y& zC~(#W@gOs4Ffk{TvV(~ivTJQ#Z@^+MwZ<|gN`jgp&8+N72G$DZ8QqMWwy&=tO)O3q z+r@ynR08#1_7RIS)}biCNUpNH?w|4{N$dN*s);8XYmPYF@Ze^aS(s2NwQ@!D2m+#9 zT$JXhQz_8-NyW1O9TCw$wWrMHi1I0FZ4$6z<|CCpRkO1{?>Qs!*&2C7~L9It=H5UP(s@ZRZ)pRA=e`D%E@?a=O3Cqc$Z5doJ2Kv1ea)%P>N2JF8tAr;_+`{Ftr+y zx`|=XZ?X9F?)vSM_M)JgbtI_Ml*!so60zB>l$e#Nz?R2#(TK=G`RH1#mFzOMkEuFe z&wAtqB`+srUB^yaftXQ;#Shmp1@Km6K=G}db*QYI7LBPFd4i2Vl*At~DcUfv62jK*jyK zu#8osv*+NP5~AXE;TXJhoS7$Fqkti#dj%y+YI;gXfn}vi{hbv;aILd53DJd%VUd65 zPJThMSQsaH`IrPw;m|OA2nJv2vNY?{w|!1aL-!;Gt&@|De1={tM$5@Q1gtNOMka(Y zd#_Q}%4Kna8+A!q58BD8V?>V;bh2hm-5Fq!)z2-HHDR=JBv9vD2HIS^A-%fGH)vAg z57OG|6gRn0w@(NL_`5KV7jmaCEFp%k0wtqQ&H^al~xrFgB9BpX`U}a2o~3ji-2wRlYmzMgI66 zbvv8HMx5+!*o2Du8U-KEwS9!pgYMzY=Ale{6)oM!&+$rzUJP?gm~5xz9N#e?VS@cG ztu@_f+UGu>GkFjL{FLWmn$uyzMb5GA_TB|+!<0QS&wRa@bABOA+adY}h_0Og!Jm55 z9_>3@XyuE0%7mJB`hsVhL4dP;=9{>;_wkQW^Ung}w*c@Hf;jM70PpJ`16l{}l)hVH zu^%ot61@Ea-@d30&6v_+PoMib^t8~!6DOZKt%ahpummaR&NuPUK06X1_+UA%!O&(f z$l<9!ybWLWJpILvR@z|5pC{d!TlJGW+!vX|a~mxF>?840+X4rrQ$Fp?Yo3(vsBJk< z5-_)k78Z7EOj-6}KM&NCHLW&r+~LlkUXh}iHt}oRG-=~q$$Dp!c;RJ?m_Aa^2;puU zTlQy<5iGnS%)Lujl1aR7ioMyR=aV*d;S_MmGbO7fd9p7JXZqHrRPY ztXe0kWCLEQU!(((PHJdt^fA<)Rs;kd*HuqSG%VA{9f(t3+-t=g{Jr*y4mTkP#9&;U zDj+nulz|YH2S7H(4c)La-RV z!2uDUbAI>!{Wp9~U+mTEPXPYz@BZ%PU;p)A`4CV)1o+`kpZ^qffn0s1I2DgCxJ%%^ z7d(nt2Nvrg&luu}UMDP24n6K_b}9FAE6%s9NHK<{mnAZqk4NDr-3t~{1}TE)v(zrV z;M*~CY2)ZT@hjR$xy9{4ZthMjQy#vp9wRinp5I#IvO1@AAm6zhRThcc)x}9Nga=MOllC(8ev;Hw>Y6_Tfe9~M1}PQhPayX zT5Fh`Y_0*A>gZpMt$vp?6P>jqnkNZyFD5Z15gMb%wRqiYT+bz7%vW0IfKXV&mv5g} z%buMfN^S|A>jB7VlT7a;4qGatGOSsMAp_Up#%av_H9(sB0U&_cB5a50P8qXO^lm6P zSvkRzI8Od5LV^%wC*{Etyx3JA7=& zBl(^}$?=i@#7|B1H(tcb+SgwQL#Q^hUMuNa3VoT-wCsa=+wCm{Z_#E*sAT+hMR6vc zeTzYF`l9dfXdWJzJC4O)y^wSjWc0TD&z$xcOY38LXQn$B-nT@3Howz1XMXzj=-+wt zF|t|MlXHx>{l~-(z;{me&qw_J8A9PyImgLA_Oz!xg^vB>+Phu&aSD&n$rtU+(e`O- z3Hw65#TXn6hR<-(p7_|lR|~-ej(BVtKMv3j0RBTj?|%8qU)Dzk@9Q3?A4(Fno>E#1 zk6tybR|kfjk1B;>==IF&$n~zs4?2MC=|USX8+DXJK0`3T>kNFpLIuG)qT(cu*c28Y zgdB1f-Kb_2pnd5FQ)4OZdiY^3gjIeDKPb(T^3E;i!E4Lv%rJ&TZ(C*?AEQX3-lWghg&{H@odKvx0XAR_H6H+ExF{l`#sh?;7 zph)#!0ED^B=6R2J(onja$|pIMLJzMKRAg^f*%@ z5tw;#%vky%x4g?wbkOU|Dyfrrm=op)Y3vVzxKlWdG6ZM7MZtk)hDt5DaHP{Ym$E_> z=N!syGr_gxi*PoStK(2aK6wYm@{PsVcu&&^Ih0TFm&A%gr1Ay;5Pf1;FQ+0}OP`EL z;_90vgGebR8dTD^)@<@?fWQ9ruU~%io8PRz1294A=Vt)6yaw!%9gt_fA@O7PhpoUY z`;$$e^#K?lK1?}}Awa&zt>tlGY%};_r*ctCn9k*b_|d=$pir|&8KX@Rze}mU5BIyo z`;l{Bf!EgI&VOgSSO5Q|HPfG$MJ5_w#&_*oFyNiIb9|@0*+7^{M&Pu?4)W|zv1!k1 z`Shy~Wq#Gq0Q{tW2H?~BLBP+-_OqA&;eYw>KK<4I_`kip`^m4GhNl!h$FWsw zft(;41?IUx_5cG)9ex6fLq<aJe{8sSR7(gN3+3OIGlAcoPn zzxRnVB5h+twkR>rlpUzQ0s}5y!H-F+iv^| zO&z7cjJ?LRBp11xBQsJcQ~MORqZ8yg2uCDNbopH2d(o?AAgqJ6a|D-DwS)+GuE9nM z-LW}8*hXZB$vd&-372@PuADIJ9q)*V&scIsA~|u^W%TZk`>u5!VS*%fEYZ3nr*y=u zy}@dK@UJcL*CZ`cjrM4DaIMt;co$J$WnRU0D3g-NkpS^ojPh-jxZw;_bt_rRLqa|y zFpq4BIj0rB-}#iO(!hB+scS)->+-Cg?m-hN5?t!7Pi1VFV5b`_7}$(RVC8e4uhhM; zd#&Sgd($w7Ix#-t6{d4>ydE!pQjcqS*t2`(n|GYKK6*PKoEIxLTpv*3#po??@{c?j zbgnCF2kq9fqIEH1 z5<`2;8mCl+4?cD2sD<5TL3#cvdi5&*IH~#J|Ni9v{XhPvpZ-7p`~UU%=bwL7{~{os z2EM7Ue+Rg~1yFle)ehL<)d-2gC> zIQ=%(CR1bw*|~eAYMzV)X}*u#g+C zi1G=)ZeG!JRzu4cHpG*904gD+a$G*e^6F0+Y0TVasuuE(^_XEKE$AG^6`srCJO6dvR z+2l#ddf1Iy;4MxKg7+(GJ>FRL1dcH{nY>b%<8`y2zQXsr!`LC&ujJD>V!ff8jMqGu z*6K;9)6Trh99!oyVqScM*Te*wzH?si#TNaEpZ)k}3xAU7coXoT&$x%rT9mO?q#HT& ziL>KYXZArFMcBbyMa}!(SP9U|5FD*2>pCl}N7b`mC37-wS*yvf*8vX3FK=rn3 z$2jWN_}v%wen}8tw@!I{l%%Jb$PoVX^c;Bxu;dLZlEEgSYw7x3xGI7`Ln>W&X-(ZH-8G zZjnH{HdWV%g2UG}*Z!K(a z9Sv@9V_F-BKXm*c;3`h_h$$5d-Q_W4ybkq8A;sfgquTSYF-LK>Wx)i#uW@f8>O_}fv#7rkUF z!5T3qSxcSfRji=5c#*nkgGZaaB+YngRjWW6ahFtgJ?M}p-CR4K`3y!LBG^cl2SuZJ zY5{X# zFO}t6wnsgvT@|kA*Km(CuDnOcGv=Jd;_Q0MF1E(Nj({hcxGTM-J}J_m{POii_@d zzx&Ip$S0>SlJ&dC9d`0Gyomv6dgFlYYPx1i!5q7OeQzEGU3oH+m{YJbXTK^b-qe~ zymy~CQl1h?+TWAmX^mj-ppIYJK$}U8`N>p4iY6cOs6*K+Zq|Xh6%1CTsR0nyzRn17;XXML4lq#Om%%|d2Ahdh$4^*!ag*ZdM_*Hp}wv*HzXU?Oo`-j?jIth91YAZ@ENn9+b|dhLsISzkGp8< zs{p~cSH^8FnHO;8wmv$vEsf=i!@lO$SelCjAJ&137;_UCrD{>zFFr?E!@e&i$!2#A zcq?4#F=SG)aH)9i+}qaZunx!U+jp%?!HBF2fT)o-TxFwKzWhbSipx2GNl!OO8Iw>N z_Pu}q^}F|f_`|!u`J2Cie>clyuqo#vhG#FdYwK|g%un+%B7zm9e-W{_3uuPA(-M(t82kg zpZd8|@D0U5O^hzocY0-{4jv%o!u;@#vz)awumPrnJrAW+fSxZo0D6r(R7EwD>o3h# zZP*M%i8@h}bkwe(n~lL*2=!H-IpZCuLU+v-+yKlIhb347_p@)JZt1EM6N%YEZd?;8 z`jexY0~tBkDkP8TGmBVV0?)m$=9)TZlS1F6j#%zm*PPFhYm4eG>L;xttL z-t!zXjpS1EJiyG8T1q}4kasMV%f{0BKof{cW+hv5+~)y3Z3gs;60M?B)N2kM0fj$AMILiL97HU{vMk(eXV3dW0W{!rUvl4_G#efwtqLjJj=LCq;JixG8_7=Ue zRcvT{8243iaaJ7l=7JyOM`Q7SQ7Ok>Slo2>f5kf?PLJhNFbhPJPmE?v2z*tSf8KIN{t(4n|Y2|m~` zfH}l!Emp4$GCHZ5^r}x$!4AFp*;91z%^r|4;wZe|o`d z`_F&=b1MAyx4(Vu4*@CM$YaGndK06myRrxFR6KbTK8thOPu@8W9`@*@oxb$ZKJ!l> z7sdu|hv}?h*J4q2#)e@nXqJpHo_e!cYhg!T@Ih4a;_F zTN&{mH8_t|A5i8|xT0v~K_SgL;NR8?0%Lxrg|4^`f=@{B)lTGt{PF3L{#!oE;zJxv zS_dEYA0Cn%u+Y zZ%v6H$2uYx_cOh%X?RbARXd|SU- zP+x0KRT%uwFLl~kL)ALpzblUq+C2@=+}P9swaXWyjVb6-DMA5|S6tYKu6c~@E2L#Q z9>?R-+c>>n3XW{+|Gr3R>bXc)wt~8L$vvOOLOeWBF;KS3ID99OA=(_dS5%8hbK=28 zoLCtV0{`JAiZ2|oH5}8z7oF;3@A0d7W?f6*ieQeF5@aCZ|2jsEldm^Q0eK;jS1$|r zK^lS4KF#j;{5%G7FO;}ht>qiImTyt!fwC*1!lrZ6UVOuF*8WZiYn4Ez zc3_N`ZwMz3m`tO3Kf zX{FJzX!zF{S<)(b-BE&*0&M8jR!L1dfyAg18dI@i!+aZK5^>_dWW3k*Xr zxUiv8vOF6f1J;RFo-lvhC3hC?i2H2;GAnVye>Yx z%eMgX5Rfbp$iqsE$of*U!iHvCli)!z2;zVFP!Rd zKh>b3bdUOht+`o1HXGns2;jF#cnl6EFnx0(rw`*C6Bk?BiHogTnsIvIAJC8NLU2yv z5&Z`b{3y^5U{9`@+myWX#dhNE>=X0y@)JC~;P{7s_y<(+lRy6Pk3XsQ)0hAD@BW*g z{8#_||6H#BnolBpnh^Pr1y5U|&b-;wD$|IE5PT7UON=nSoWic5T6k)&4&Qjy1)oAh z)v0~ZeuodvkQ4gV)B(R!G8Z${~g>)5?tyq8em2n)Tu&DzlO%+@MUF#{giRpRP6dbr4pBYP+VEp|@rVn5TrHI5jE&3KfmYtp4Xt!UiLx;`2XT&-5Wa_!#toxp0V+zJM<) z*~B3ZF{>0Ab54p!PT@htu}IUFnn%F8P0-lf;f!n*mivRZ0s1jd&b1(@A^WaR4LEjf znO7n!Mb<<1dG5%W&2ZXR4gN2{4W{Z6hj4{-Cu6W1gE>%7S*dSbtfG7!2zxlko_uZ8q~_3cU3O7%e=(358KBtwq&jx?EFosdKJphJ@3K4D6HX-g6tEH=c3 z74TMZ3Z?JKrwAjS?|}q>uc>v4jFkJNwGkj+6}97XikLr1lqes6mmG{Cg}jqXB12Q_ z!E3FUf*@CXaVz}WCx85x|Mk=V@BjRL{e|Ce{_WrX?c0C(mw&@KdM0g3_$)AaQ$n5FTeQ3FW!Cq*-!BJ(4{{+cot!~>(PVz2PeE0uLh4Z@i8#h zk`@g0w8OJ))wo9~fH;;>-8^;i$p#1<^-x~kPy959zQp0CsBr z%Zan~m_WWyqyaH{M?j#YfOmeKE|E^7@~n4K>mT3+t2lljG%{)RgM8U7&)Kr_W#ICJ zgH{IQ2QMtv))0>UNL;q&DO1xk35xC99+78l|EqIIla!h-Bv7Y3vBPe3OJL1pj}F=P zH+mY&$NJdjr}Ki+fD=QjGw0;x0l@mT9@qc{tuJh9&YC(zt?z$|;JLwvcmz7WW)W(_ z77F`o#pAf6PkR}a13IoE;z2*_4m`w=mqOv)3X_J%*MftWMJRvDQat5~HK7t@3Gy7u zjv-I^83awTt?=g%nej`&WIN^KfT3)bK4w<{VyaJLa#_W)WO+F+pb>^>%dMv9UL0U# zuRjFD!}G5`95z}AsZ6U0Yzi8%Ys(zun`g)KOqztL6+;@yd(=~*Q47O@VM?+Q({_l# zj<0!W-C*f>npRn|hvzh%uqDJ%_L*`Qam@y>%+&EUUi;31XjU-_s|n&}=*0G**90 zrN(!-j(Tt>c4A^rd-^htKeDjX=8B{+^p}&xC;&^bk;hB4=Xh8?C|AYAwSM%M4&L!AThqG zJ+@puP~cIaPVc#o2DC47q&RuZIBAz77hFbZ$*w}*O}JU7i+Hl&U!Rj3Xc%~CE4$?wQZH{nlK=ze@dPH>AR}^ z0G0$uQb{0ogorKSrZ2X)w%>>Q));rVGwwOg{K1V6HuN)w??3L?z6J2@w|r8>H)krl z`q4T)Hjhl}Wt6^3xbHfike{j^P9-px=opvz+Pd5a^tEi{YoN8^;{+x=`RUGKS}u*ukR37wysRcK~)m z&qwE*TS)1~mfH&T5+J-5SQXmeX|%ncPDznYEipUGSHt=5*0;Rpz;R6~b;TYz=bl

%1?l4Z9#$epj{ljxcZ<2~xX#3C|9!u+o84@7 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

!Gv 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

A$D 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 literal 0 HcmV?d00001 diff --git a/apps/admin-web/public/manifest.json b/apps/admin-web/public/manifest.json new file mode 100644 index 0000000..a3831d6 --- /dev/null +++ b/apps/admin-web/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "Freshyo", + "name": "Freshyo", + "icons": [ + { + "src": "favicon.png", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/png" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#0033CC", + "background_color": "#ffffff" +} diff --git a/apps/admin-web/public/robots.txt b/apps/admin-web/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/apps/admin-web/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/apps/admin-web/src/client.tsx b/apps/admin-web/src/client.tsx new file mode 100644 index 0000000..e5ac4b1 --- /dev/null +++ b/apps/admin-web/src/client.tsx @@ -0,0 +1,4 @@ +import { hydrateRoot } from 'react-dom/client' +import { StartClient } from '@tanstack/react-start/client' + +hydrateRoot(document, ) diff --git a/apps/admin-web/src/components/BannerForm.tsx b/apps/admin-web/src/components/BannerForm.tsx new file mode 100644 index 0000000..b0755a7 --- /dev/null +++ b/apps/admin-web/src/components/BannerForm.tsx @@ -0,0 +1,225 @@ +import { useRef, useState, type ChangeEvent } from 'react' +import { Formik } from 'formik' +import * as Yup from 'yup' +import { p as P, pInput as PInput, ImageUploader } from 'web-components' +import ProductsSelector from './ProductsSelector' +import { trpc } from '@/lib/trpc-client' +import { useUploadToObjectStorage } from '@/hooks/useUploadToObjectStorage' + +export interface BannerFormData { + name: string + imageUrl: string + description: string + skuIds: number[] + redirectUrl: string + // serialNum removed - will be assigned automatically by backend +} + +interface BannerFormProps { + initialValues: BannerFormData + onSubmit: (values: BannerFormData, imageUrl?: string) => Promise | void + onCancel: () => void + submitButtonText?: string + isSubmitting?: boolean + existingImageUrl?: string + mode?: 'create' | 'edit' +} + +const validationSchema = Yup.object().shape({ + name: Yup.string().trim().required('Banner name is required').max(255), + description: Yup.string().max(500), + skuIds: Yup.array() + .of(Yup.number()) + .optional(), + redirectUrl: Yup.string() + .url('Please enter a valid URL') + .optional(), + // serialNum validation removed - assigned automatically by backend +}) + +export default function BannerForm({ + initialValues, + onSubmit, + onCancel, + submitButtonText = 'Create Banner', + isSubmitting = false, + existingImageUrl, + mode = 'create', +}: BannerFormProps) { + const [selectedImages, setSelectedImages] = useState<{ blob: Blob; mimeType: string }[]>([]) + const [displayImages, setDisplayImages] = useState<{ uri?: string }[]>([]) + const fileInputRef = useRef(null) + + const { uploadSingle } = useUploadToObjectStorage() + + // Fetch products for dropdown + const { data: productsData } = trpc.common.product.getAllProductsSummary.useQuery() + const products = productsData?.products || [] + + const handleImagePick = () => { + fileInputRef.current?.click() + } + + const handleFileChange = (e: ChangeEvent) => { + const files = Array.from(e.target.files || []) + if (files.length === 0) { + setSelectedImages([]) + setDisplayImages([]) + return + } + const file = files[0] + setSelectedImages([{ blob: file, mimeType: file.type || 'image/jpeg' }]) + setDisplayImages([{ uri: URL.createObjectURL(file) }]) + e.target.value = '' + } + + const handleRemoveImage = (uri: string) => { + const index = displayImages.findIndex(img => img.uri === uri) + if (index !== -1) { + const newDisplay = displayImages.filter((_, i) => i !== index) + const newFiles = selectedImages.filter((_, i) => i !== index) + setDisplayImages(newDisplay) + setSelectedImages(newFiles) + } + } + + const handleFormikSubmit = async (values: BannerFormData) => { + try { + let imageUrl: string | undefined + + if (selectedImages.length > 0) { + const { blob, mimeType } = selectedImages[0] + const { presignedUrl } = await uploadSingle(blob, mimeType, 'store') + imageUrl = presignedUrl + } + + await onSubmit(values, imageUrl) + } catch (error) { + console.error('Upload error:', error) + window.alert('Error: Failed to upload image') + } + } + + return ( + + {({ + handleChange, + handleBlur, + handleSubmit, + values, + errors, + touched, + isValid, + dirty, + setFieldValue, + }) => ( +

+ +
+ + {errors.name && touched.name && ( +

{errors.name}

+ )} + +
+

Banner Image

+ { + // Handle removing existing image in edit mode + }} + allowMultiple={false} + /> +
+ + + {errors.description && touched.description && ( +

{errors.description}

+ )} + +
+ { + const selectedValues = Array.isArray(value) ? value : [value] + setFieldValue('skuIds', selectedValues.map(v => Number(v))) + }} + multiple={true} + label="Select Products" + placeholder="Select products for banner (optional)" + labelFormat={(product) => `${product.productName} (₹${product.price})`} + /> +
+ + + {errors.redirectUrl && touched.redirectUrl && ( +

{errors.redirectUrl}

+ )} + + {/* Action Buttons */} +
+ + + +
+
+
+ )} + + ) +} diff --git a/apps/admin-web/src/components/CancelOrderDialog.tsx b/apps/admin-web/src/components/CancelOrderDialog.tsx new file mode 100644 index 0000000..e6e4b89 --- /dev/null +++ b/apps/admin-web/src/components/CancelOrderDialog.tsx @@ -0,0 +1,85 @@ +import React, { useState } from 'react' +import type { OrderDialogBaseProps } from '@packages/shared' +import { p as P, BottomDialog, pInput as PInput } from 'web-components' +import { trpc } from '@/lib/trpc-client' +import { XCircle } from 'lucide-react' + +interface CancelOrderDialogProps extends OrderDialogBaseProps { + onSuccess?: () => void +} + +export default function CancelOrderDialog({ orderId, open, onClose, onSuccess }: CancelOrderDialogProps) { + const [cancelReason, setCancelReason] = useState('') + const cancelOrderMutation = trpc.admin.order.cancelOrder.useMutation() + + const handleCancel = () => { + if (!cancelReason.trim()) { + window.alert('Error: Please enter a cancellation reason') + return + } + + const confirmed = window.confirm( + 'Cancel Order? Are you sure you want to cancel this order? This action cannot be undone.' + ) + if (!confirmed) return + + cancelOrderMutation.mutate( + { orderId, reason: cancelReason }, + { + onSuccess: () => { + onClose() + setCancelReason('') + onSuccess?.() + }, + onError: (error: any) => { + window.alert(`Error: ${error.message || 'Failed to cancel order'}`) + }, + } + ) + } + + return ( + +
+
+
+ +
+

+ Cancel Order +

+

+ This will cancel the order and mark it as cancelled by admin. A refund record will be created. +

+
+ + setCancelReason(e.target.value)} + placeholder="Enter reason for cancellation..." + multiline + className="h-24" + /> + +
+ + +
+
+
+ ) +} diff --git a/apps/admin-web/src/components/CouponForm.tsx b/apps/admin-web/src/components/CouponForm.tsx new file mode 100644 index 0000000..1dfda47 --- /dev/null +++ b/apps/admin-web/src/components/CouponForm.tsx @@ -0,0 +1,558 @@ +import { useState, useEffect, type ChangeEvent } from 'react' +import { Formik } from 'formik' +import * as Yup from 'yup' +import { pInput as PInput, MyButton, AppContainer, Checkbox, BottomDialog, p as P, MyFlatList } from 'web-components' +import DateTimeInput from './DateTimeInput' +import { trpc } from '@/lib/trpc-client' + +// Local copy of common-ui/shared-types CreateCouponPayload (web cannot import +// the RN common-ui package; @packages/shared does not export this type). +export interface CreateCouponPayload { + couponCodes: string[] + discountPercent?: number + flatDiscount?: number + minOrder?: number + maxValue?: number + validTill?: string + maxLimitForUser?: number + isApplyForAll: boolean + isUserBased: boolean + targetUsers?: number[] + productIds?: number[] + skuIds?: number[] + applicableUsers?: number[] + applicableProducts?: number[] + exclusiveApply?: boolean +} + +const USERS_PAGE_SIZE = 10 + +interface CouponFormValues extends CreateCouponPayload { + isReservedCoupon?: boolean + couponCodes: string[] + skuIds?: number[] +} + +interface CouponFormProps { + onSubmit: (values: CouponFormValues) => void + isLoading: boolean + initialValues?: Partial +} + +const couponValidationSchema = Yup.object().shape({ + isReservedCoupon: Yup.boolean().optional(), + couponCodes: Yup.array().of( + Yup.string() + .required('Code is required') + .min(3, 'Code must be at least 3 characters') + .max(50, 'Code cannot exceed 50 characters') + .matches(/^[A-Z0-9_-]+$/, 'Code can only contain uppercase letters, numbers, underscores, and hyphens') + ), + discountPercent: Yup.number() + .min(0, 'Must be positive') + .max(100, 'Cannot exceed 100%') + .optional(), + flatDiscount: Yup.number() + .min(0, 'Must be positive') + .optional(), + minOrder: Yup.number().min(0, 'Must be positive').optional(), + maxValue: Yup.number().min(0, 'Must be positive').optional(), + validTill: Yup.date().optional(), + maxLimitForUser: Yup.number().min(1, 'Must be at least 1').optional(), + exclusiveApply: Yup.boolean().optional(), + isUserBased: Yup.boolean(), + isApplyForAll: Yup.boolean(), + applicableUsers: Yup.array().of(Yup.number()).optional(), +}).test('discount-validation', 'Must provide exactly one discount type with valid value', function(value) { + const { discountPercent, flatDiscount } = value + const hasPercent = discountPercent !== undefined && discountPercent > 0 + const hasFlat = flatDiscount !== undefined && flatDiscount > 0 + + if (hasPercent && hasFlat) { + return this.createError({ message: 'Cannot have both percentage and flat discount' }) + } + if (!hasPercent && !hasFlat) { + return this.createError({ message: 'Must provide either percentage or flat discount' }) + } + return true +}).test('codes-required', 'At least one coupon code is required', function(value: any) { + const codes = (value.couponCodes || []).filter((c: string) => c && c.trim()) + if (codes.length === 0) { + return this.createError({ path: 'couponCodes', message: 'Add at least one coupon code' }) + } + return true +}).test('codes-unique', 'Coupon codes must be unique', function(value: any) { + const codes = (value.couponCodes || []).map((c: string) => c.trim()).filter(Boolean) + if (new Set(codes).size !== codes.length) { + return this.createError({ path: 'couponCodes', message: 'Coupon codes must be unique' }) + } + return true +}) + +export default function CouponForm({ onSubmit, isLoading, initialValues }: CouponFormProps) { + + // User dropdown states + const [userSearchQuery, setUserSearchQuery] = useState('') + const [userOffset, setUserOffset] = useState(0) + const [allUsers, setAllUsers] = useState<{ id: number; name: string; mobile: string | null }[]>([]) + const [hasMoreUsers, setHasMoreUsers] = useState(true) + const [usersDropdownOpen, setUsersDropdownOpen] = useState(false) + + // Add-multiple dialog states (for pattern codes like ABC12) + const [multiDialogOpen, setMultiDialogOpen] = useState(false) + const [multiCount, setMultiCount] = useState('') + + const { data: usersData, isFetching: isFetchingUsers } = trpc.admin.coupon.getUsersMiniInfo.useQuery( + { search: userSearchQuery, limit: USERS_PAGE_SIZE, offset: userOffset }, + { enabled: usersDropdownOpen } + ) + + useEffect(() => { + if (usersData?.users) { + if (userOffset === 0) { + setAllUsers(usersData.users) + } else { + setAllUsers(prev => [...prev, ...usersData.users]) + } + setHasMoreUsers(usersData.users.length === USERS_PAGE_SIZE) + } + }, [usersData, userOffset]) + + useEffect(() => { + setUserOffset(0) + setHasMoreUsers(true) + }, [userSearchQuery]) + + useEffect(() => { + if (usersDropdownOpen) { + setUserOffset(0) + setAllUsers([]) + setHasMoreUsers(true) + setUserSearchQuery('') + } + }, [usersDropdownOpen]) + + // User search functionality will be inside Formik + + const defaultValues: CouponFormValues = { + couponCodes: [''], + isUserBased: false, + isApplyForAll: false, + targetUsers: [], + discountPercent: undefined, + flatDiscount: undefined, + minOrder: undefined, + maxValue: undefined, + validTill: undefined, + maxLimitForUser: undefined, + skuIds: undefined, + applicableUsers: [], + applicableProducts: [], + exclusiveApply: false, + isReservedCoupon: false, + } + + return ( + + initialValues={(initialValues || defaultValues) as CouponFormValues} + validationSchema={couponValidationSchema} + onSubmit={onSubmit} + > + {({ values, errors, touched, setFieldValue, handleSubmit }) => { + + const toggleUserSelection = (userId: number) => { + const current = values.applicableUsers || [] + const newSelection = current.includes(userId) + ? current.filter(id => id !== userId) + : [...current, userId] + setFieldValue('applicableUsers', newSelection) + } + + const isReserved = (values as any).isReservedCoupon + + // Detect pattern codes like ABC12 (ends in digits) for bulk generation. + // Continue numbering from the highest code with the same prefix. + const patternCode = (values.couponCodes || []).find( + (c: string) => /^[A-Z0-9_-]*\d+$/.test(c.trim()) + ) + const patternPrefix = patternCode ? patternCode.replace(/\d+$/, '') : '' + const patternStart = (values.couponCodes || []).reduce((max, c) => { + const trimmed = c.trim() + if (!patternPrefix || !trimmed.startsWith(patternPrefix)) return max + const m = trimmed.match(/\d+$/) + if (!m) return max + return Math.max(max, parseInt(m[0], 10)) + }, patternCode ? parseInt((patternCode.match(/\d+$/) || ['0'])[0], 10) : 0) + + const handleAddMultiple = () => { + const count = parseInt(multiCount, 10) + if (!count || count < 1 || count > 100) return + // Start from the next number after the highest existing code + const newCodes = Array.from( + { length: count }, + (_, i) => `${patternPrefix}${patternStart + 1 + i}` + ) + const existing = (values.couponCodes || []).filter((c: string) => c && c.trim()) + setFieldValue('couponCodes', [...existing, ...newCodes]) + setMultiDialogOpen(false) + setMultiCount('') + } + + return ( + + {/* Is Reserved Coupon Checkbox */} +
+ setFieldValue('isReservedCoupon', !(values as any).isReservedCoupon)} + /> +

Is Reserved Coupon

+
+ + {/* Coupon Codes */} +
+

Coupon Codes

+

+ Each code creates a separate coupon with the same settings. +

+ {(values.couponCodes || []).map((code: string, index: number) => { + const codeError = Array.isArray(errors.couponCodes) + ? (errors.couponCodes as any)[index] + : errors.couponCodes + return ( +
+
+ ) => { + const next = [...(values.couponCodes || [])] + next[index] = e.target.value.toUpperCase() + setFieldValue('couponCodes', next) + }} + error={!!codeError} + /> + {codeError &&

{codeError}

} +
+ +
+ ) + })} + {(errors.couponCodes as any)?.message && ( +

{(errors.couponCodes as any).message}

+ )} +
+ + + {patternCode && ( + + )} +
+
+ + {/* Discount Type Selection */} +

+ Discount Type * +

+ +
+ + + +
+ + {/* Discount Value */} + {values.discountPercent !== undefined && ( +
+ setFieldValue('discountPercent', parseFloat(e.target.value) || 0)} + type="number" + inputMode="numeric" + error={!!(touched.discountPercent && errors.discountPercent)} + /> +
+ )} + + {values.flatDiscount !== undefined && ( +
+ setFieldValue('flatDiscount', parseFloat(e.target.value) || 0)} + type="number" + inputMode="numeric" + error={!!(touched.flatDiscount && errors.flatDiscount)} + /> +
+ )} + + {/* Minimum Order */} +
+ setFieldValue('minOrder', parseFloat(e.target.value) || undefined)} + type="number" + inputMode="numeric" + error={!!(touched.minOrder && errors.minOrder)} + /> +
+ + {/* Maximum Discount Value - only for percentage discounts */} + {values.flatDiscount === undefined && ( +
+ setFieldValue('maxValue', parseFloat(e.target.value) || undefined)} + type="number" + inputMode="numeric" + error={!!(touched.maxValue && errors.maxValue)} + /> +
+ )} + + {/* Validity Period */} +
+

Valid Till

+ { + + setFieldValue('validTill', date?.toISOString()) + }} + /> +
+ + {/* Usage Limit */} +
+ setFieldValue('maxLimitForUser', parseInt(e.target.value) || undefined)} + type="number" + inputMode="numeric" + error={!!(touched.maxLimitForUser && errors.maxLimitForUser)} + /> +
+ + {/* Exclusive Apply */} +
+

Exclusive Apply

+ +
+ + {/* Target Audience */} +

+ Target Audience {isReserved ? '(Disabled for Reserved Coupons)' : ''} +

+ +
+ + + +
+ + {/* Applicable User Selection */} +
+

Applicable Users (Optional)

+ +
+ + setUsersDropdownOpen(false)}> +
+

Select Applicable Users

+ setUserSearchQuery(e.target.value)} + /> +
+ item.id.toString()} + renderItem={(item) => ( + + )} + ListFooterComponent={ + <> + {isFetchingUsers ?

Loading...

: null} + {hasMoreUsers && !isFetchingUsers ? ( + + ) : null} + + } + /> +
+ +
+
+ + {/* Add Multiple Coupons Dialog */} + setMultiDialogOpen(false)}> +
+

Add Multiple Coupons

+

+ Generate {patternCode ? `${patternPrefix}${patternStart + 1}, ${patternPrefix}${patternStart + 2}, ...` : 'sequential'} codes from your pattern +

+ setMultiCount(e.target.value)} + type="number" + inputMode="numeric" + /> +
+ + +
+
+
+ + {/* Submit Button */} + handleSubmit()} + disabled={isLoading} + textContent={isLoading ? 'Creating...' : 'Create Coupon'} + /> +
+ ) + }} + + ) +} diff --git a/apps/admin-web/src/components/DateInput.tsx b/apps/admin-web/src/components/DateInput.tsx new file mode 100644 index 0000000..a7ef9dd --- /dev/null +++ b/apps/admin-web/src/components/DateInput.tsx @@ -0,0 +1,31 @@ +import { p as P } from 'web-components' + +interface DateInputProps { + value: Date | null + setValue: (d: Date | null) => void + showLabel?: boolean + placeholder?: string +} + +function toDateStr(d: Date | null): string { + if (!d) return '' + const y = d.getFullYear() + const m = String(d.getMonth() + 1).padStart(2, '0') + const day = String(d.getDate()).padStart(2, '0') + return `${y}-${m}-${day}` +} + +export default function DateInput({ value, setValue, showLabel = true, placeholder = 'Select Date' }: DateInputProps) { + return ( +
+ {showLabel ?

{placeholder}

: null} + setValue(e.target.value ? new Date(`${e.target.value}T00:00:00`) : null)} + placeholder={placeholder} + className="w-full rounded border border-gray-300 px-2 py-2 text-sm font-medium text-gray-800" + /> +
+ ) +} diff --git a/apps/admin-web/src/components/DateTimeInput.tsx b/apps/admin-web/src/components/DateTimeInput.tsx new file mode 100644 index 0000000..2260dac --- /dev/null +++ b/apps/admin-web/src/components/DateTimeInput.tsx @@ -0,0 +1,80 @@ +import { p as P } from 'web-components' + +interface DateTimeInputProps { + value: Date | null + setValue: (d: Date | null) => void + showLabels?: boolean + timeOnly?: boolean +} + +function toDateStr(d: Date | null): string { + if (!d) return '' + const y = d.getFullYear() + const m = String(d.getMonth() + 1).padStart(2, '0') + const day = String(d.getDate()).padStart(2, '0') + return `${y}-${m}-${day}` +} + +function toTimeStr(d: Date | null): string { + if (!d) return '' + return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}` +} + +export default function DateTimeInput({ value, setValue, showLabels = true, timeOnly = false }: DateTimeInputProps) { + const handleDateChange = (dateStr: string) => { + if (!dateStr) { + setValue(null) + return + } + const base = value ? new Date(value) : new Date() + const [y, m, day] = dateStr.split('-').map((n) => parseInt(n, 10)) + base.setFullYear(y, m - 1, day) + setValue(base) + } + + const handleTimeChange = (timeStr: string) => { + if (!timeStr) return + const base = value ? new Date(value) : new Date() + const [h, min] = timeStr.split(':').map((n) => parseInt(n, 10)) + base.setHours(h, min, 0, 0) + setValue(base) + } + + if (timeOnly) { + return ( +
+ {showLabels ?

Select Time

: null} + handleTimeChange(e.target.value)} + className="w-full rounded border border-gray-300 px-2 py-1 text-sm font-medium text-gray-800" + /> +
+ ) + } + + return ( +
+
+ {showLabels ?

Select Date

: null} + handleDateChange(e.target.value)} + className="w-full rounded border border-gray-300 px-2 py-1 text-sm font-medium text-gray-800" + /> +
+
+
+ {showLabels ?

Select Time

: null} + handleTimeChange(e.target.value)} + className="w-full rounded border border-gray-300 px-2 py-1 text-sm font-medium text-gray-800" + /> +
+
+ ) +} diff --git a/apps/admin-web/src/components/MultiSelect.tsx b/apps/admin-web/src/components/MultiSelect.tsx new file mode 100644 index 0000000..2c430a4 --- /dev/null +++ b/apps/admin-web/src/components/MultiSelect.tsx @@ -0,0 +1,151 @@ +import { useMemo, useState } from 'react' +import { BottomDialog, Checkbox, SearchBar, p as P } from 'web-components' +import { Check, ChevronDown } from 'lucide-react' + +export interface MultiSelectOption { + label: string + value: string | number + disabled?: boolean +} + +interface MultiSelectProps { + label?: string + topLabel?: string + options: MultiSelectOption[] + value: (string | number)[] + onValueChange: (v: (string | number)[]) => void + placeholder?: string + disabled?: boolean + onSearch?: (q: string) => void + error?: boolean + className?: string + testID?: string + // Tolerated for screen compatibility (RN BottomDropdown leftovers) — ignored on web + multiple?: boolean + triggerComponent?: any +} + +export function MultiSelect({ + label, + topLabel, + options, + value, + onValueChange, + placeholder, + disabled = false, + onSearch, + error = false, + className, + testID, +}: MultiSelectProps) { + const [open, setOpen] = useState(false) + const [query, setQuery] = useState('') + + const selectedSet = useMemo(() => new Set(value.map((v) => String(v))), [value]) + + const displayText = useMemo(() => { + if (value.length === 0) return placeholder ?? label ?? 'Select...' + if (value.length === 1) { + const found = options.find((o) => String(o.value) === String(value[0])) + return found ? found.label : (placeholder ?? label ?? 'Select...') + } + return `${value.length} selected` + }, [value, options, placeholder, label]) + + const filtered = useMemo(() => { + const q = query.trim().toLowerCase() + if (!q) return options + return options.filter((o) => o.label.toLowerCase().includes(q)) + }, [options, query]) + + const toggle = (optionValue: string | number) => { + const key = String(optionValue) + if (selectedSet.has(key)) { + onValueChange(value.filter((v) => String(v) !== key)) + } else { + onValueChange([...value, optionValue]) + } + } + + const heading = topLabel ?? label + + return ( +
+ {heading ? ( +

{heading}

+ ) : null} + + setOpen(false)}> +
+

{heading ?? placeholder ?? 'Select'}

+ { + setQuery(q) + onSearch?.(q) + }} + onSearch={onSearch} + className="mb-3" + /> +
+ {filtered.map((option) => { + const checked = selectedSet.has(String(option.value)) + return ( +
{ + if (!option.disabled) toggle(option.value) + }} + className={`flex flex-row items-center p-3 border-b border-gray-100 ${option.disabled ? 'opacity-50' : 'cursor-pointer hover:bg-gray-50'}`} + > + e.stopPropagation()}> + { + if (!option.disabled) toggle(option.value) + }} + /> + + {option.label} + {checked ? : null} +
+ ) + })} + {filtered.length === 0 ? ( +

No options found

+ ) : null} +
+
+ + +
+
+
+
+ ) +} + +export default MultiSelect diff --git a/apps/admin-web/src/components/OrderNotesForm.tsx b/apps/admin-web/src/components/OrderNotesForm.tsx new file mode 100644 index 0000000..4c736f4 --- /dev/null +++ b/apps/admin-web/src/components/OrderNotesForm.tsx @@ -0,0 +1,70 @@ +import { useState, type FC } from 'react' +import { p as P, MyButton, pInput as PInput } from 'web-components' +import { trpc } from '@/lib/trpc-client' + +interface OrderNotesFormProps { + orderId: number + initialNotes?: string + onSuccess?: () => void + onCancel?: () => void +} + +export const OrderNotesForm: FC = ({ + orderId, + initialNotes = '', + onSuccess, + onCancel, +}) => { + const [notes, setNotes] = useState(initialNotes) + const updateNotesMutation = trpc.admin.order.updateNotes.useMutation() + + const handleSubmit = async () => { + if (!notes.trim()) { + window.alert('Error: Please enter some notes') + return + } + + try { + await updateNotesMutation.mutateAsync({ + orderId, + adminNotes: notes.trim(), + }) + window.alert('Success: Notes updated successfully') + onSuccess?.() + } catch (error) { + window.alert('Error: Failed to update notes') + } + } + + return ( +
+

+ Add Order Notes +

+ + setNotes(e.target.value)} + placeholder="Enter notes for this order..." + multiline + numberOfLines={4} + className="min-h-24" + /> + +
+ + +
+
+ ) +} diff --git a/apps/admin-web/src/components/OrderOptionsMenu.tsx b/apps/admin-web/src/components/OrderOptionsMenu.tsx new file mode 100644 index 0000000..87c1d0c --- /dev/null +++ b/apps/admin-web/src/components/OrderOptionsMenu.tsx @@ -0,0 +1,327 @@ +import React from 'react' +import { p as P, BottomDialog, Checkbox } from 'web-components' +import { trpc } from '@/lib/trpc-client' +import { ChevronRight, Eye, Pencil, XCircle, MapPin, Map, MessageCircle, Phone } from 'lucide-react' + +interface OrderOptionsMenuProps { + open: boolean + onClose: () => void + order: { + id: number + readableId: number + isPackaged: boolean + isDelivered: boolean + isFlashDelivery?: boolean + address: string + addressId: number + adminNotes?: string | null + userNotes?: string | null + latitude?: number | null + longitude?: number | null + status?: string + } + onViewDetails: () => void + onTogglePackaged: () => void + onToggleDelivered: () => void + onOpenAdminNotes: () => void + onCancelOrder: () => void + onAttachLocation: () => void + onWhatsApp: () => void + onDial: () => void +} + +function getCurrentPosition(): Promise { + return new Promise((resolve, reject) => { + if (!navigator.geolocation) { + reject(new Error('Geolocation is not supported by this browser')) + return + } + navigator.geolocation.getCurrentPosition(resolve, reject, { enableHighAccuracy: true }) + }) +} + +export function OrderOptionsMenu({ + open, + onClose, + order, + onViewDetails, + onTogglePackaged, + onToggleDelivered, + onOpenAdminNotes, + onCancelOrder, + onAttachLocation, + onWhatsApp, + onDial, +}: OrderOptionsMenuProps) { + const updateAddressCoordsMutation = trpc.admin.order.updateAddressCoords.useMutation() + + const handleAttachLocation = async () => { + try { + const location = await getCurrentPosition() + const { latitude, longitude } = location.coords + await updateAddressCoordsMutation.mutateAsync({ + addressId: order.addressId, + latitude, + longitude, + }) + window.alert('Success: Location attached to address successfully.') + onAttachLocation() + } catch (error: any) { + if (error?.code === 1) { + window.alert('Permission Denied: Location permission is required to attach coordinates.') + return + } + window.alert('Error: Failed to attach location. Please try again.') + } + } + + const extractPhone = (address: string) => { + const phoneMatch = address.match(/Phone: (\d+)/) + return phoneMatch ? phoneMatch[1] : null + } + + const handleWhatsApp = () => { + const phone = extractPhone(order.address) + if (phone) { + window.open(`https://wa.me/91${phone}`, '_blank') + } else { + window.alert('No phone number found') + } + } + + const handleDial = () => { + const phone = extractPhone(order.address) + if (phone) { + window.open(`tel:${phone}`, '_blank') + } else { + window.alert('No phone number found') + } + } + + const handleOpenInMaps = () => { + if (order.latitude && order.longitude) { + const url = `https://www.google.com/maps/search/?api=1&query=${order.latitude},${order.longitude}` + window.open(url, '_blank') + } else { + window.alert('No location coordinates available') + } + } + + const hasCoordinates = order.latitude !== null && order.latitude !== undefined && + order.longitude !== null && order.longitude !== undefined + + return ( + +
+
+
+
+
+

+ Order #{order.readableId} +

+

+ Select an action to perform +

+
+ + + +
+ + +
+ +
+ + +
+ + + + {order.status !== 'cancelled' && ( + + )} + + + + {hasCoordinates && ( + + )} + + + + +
+
+
+ + ) +} diff --git a/apps/admin-web/src/components/ProductForm.tsx b/apps/admin-web/src/components/ProductForm.tsx new file mode 100644 index 0000000..c8f8610 --- /dev/null +++ b/apps/admin-web/src/components/ProductForm.tsx @@ -0,0 +1,659 @@ +import { useState, useImperativeHandle, forwardRef, useMemo } from 'react' +import { Formik, FieldArray } from 'formik' +import * as Yup from 'yup' +import { pInput as PInput, Dropdown, p as P, Checkbox, BottomDialog, ImageUploaderNeo } from 'web-components' +import type { ImageUploaderNeoItem, ImageUploaderNeoPayload } from 'web-components' +import SearchableSelect from './SearchableSelect' +import { Plus, Trash2, X, RotateCcw, Info } from 'lucide-react' +import { trpc } from '@/lib/trpc-client' +import type { CreateComboItemInput, CreateSkuInput } from '@packages/shared' +import type { SkuFeatureLike } from '@packages/shared' + +// Feature input shape — single source: shared SkuFeatureLike +type Attribute = SkuFeatureLike + +// Variant form state — anchored to the shared CreateSkuInput (numeric prices, +// same field names). Images are managed separately via variantImages state. +type Variant = Omit< + CreateSkuInput, + 'name' | 'price' | 'marketPrice' | 'flashPrice' | 'images' | 'features' | 'comboItems' +> & { + id?: number + name: string + price?: number + marketPrice: number | null + flashPrice: number | null + isFlashAvailable: boolean + isOffer: boolean + isComboOnly: boolean + isSuspended: boolean + features: Attribute[] + comboItems: CreateComboItemInput[] +} + +interface ProductFormData { + name: string + shortDescription: string + longDescription: string + storeId: number + productType: 'item' | 'combo' + variants: Variant[] +} + +export interface ProductFormRef { + clearImages: () => void +} + +interface ProductFormProps { + mode: 'create' | 'edit' + initialValues: ProductFormData + onSubmit: (values: ProductFormData, variantImages: ImageUploaderNeoPayload[][], deletedImageKeys: string[]) => void + isLoading: boolean + existingVariantImages?: ImageUploaderNeoItem[][] + existingVariantImageKeys?: string[][] +} + +// Web rebuild of common-ui InfoDialog: info icon button + BottomDialog + p +function InfoDialog({ message, className }: { message?: string; className?: string }) { + const [open, setOpen] = useState(false) + return ( + <> + + setOpen(false)}> +
+

{message ?? ''}

+
+
+ + ) +} + +const defaultAttribute = (): Attribute => ({ featureName: '', featureValue: '' }) + +// The quantity feature is auto-added as the first attribute of every SKU. +const quantityAttribute = (): Attribute => ({ featureName: 'quantity', featureValue: '' }) + +const isQuantityFeature = (attr: Attribute): boolean => + (attr.featureName ?? '').trim().toLowerCase() === 'quantity' + +const defaultVariant = (): Variant => ({ + id: undefined, + name: '', + price: undefined, + marketPrice: null, + isFlashAvailable: false, + flashPrice: null, + isOffer: false, + isComboOnly: false, + isDeleted: false, + isSuspended: false, + features: [quantityAttribute()], + comboItems: [], +}) + +const variantSignature = (attributes: Attribute[]): string => + attributes + .map((a) => `${(a.featureName ?? '').trim().toLowerCase()}::${a.featureValue.trim().toLowerCase()}`) + .sort() + .join('|') + +const productValidationSchema = Yup.object().shape({ + name: Yup.string().required('Product name is required'), + storeId: Yup.number().required('Store is required').min(1, 'Store is required'), + productType: Yup.string().oneOf(['item', 'combo'], 'Product type is required').required('Product type is required'), + variants: Yup.array() + .min(1, 'At least one variant is required') + .of( + Yup.object().shape({ + price: Yup.number() + .typeError('Price must be a number') + .positive('Price must be a positive number') + .required('Price is required'), + marketPrice: Yup.number() + .typeError('Market price must be a number') + .min(0, 'Market price cannot be negative') + .nullable() + .transform((value, originalValue) => (originalValue === '' ? null : value)) + .optional(), + flashPrice: Yup.number() + .typeError('Flash price must be a number') + .min(0, 'Flash price cannot be negative') + .nullable() + .transform((value, originalValue) => (originalValue === '' ? null : value)) + .optional(), + features: Yup.array() + .min(1, 'At least one attribute is required') + .of( + Yup.object().shape({ + featureValue: Yup.string().required('Value is required'), + }) + ), + }) + ) + .test('unique-variants', 'Two variants have the same attributes', function (variants) { + if (!Array.isArray(variants)) return true + const seen = new Set() + for (const variant of variants) { + const attrs = variant?.features || [] + const signature = variantSignature(attrs as Attribute[]) + if (seen.has(signature)) { + return this.createError({ message: 'Two variants have the same attributes' }) + } + seen.add(signature) + } + return true + }) + .test('quantity-feature', 'Each SKU must have exactly one quantity feature', function (variants) { + if (!Array.isArray(variants)) return true + for (const variant of variants) { + const attrs = variant?.features || [] + const quantityCount = attrs.filter( + (a) => ((a as Attribute)?.featureName ?? '').trim().toLowerCase() === 'quantity' + ).length + if (quantityCount === 0) { + return this.createError({ message: 'Every SKU must have a quantity feature' }) + } + if (quantityCount > 1) { + return this.createError({ message: 'Each SKU can have only one quantity feature' }) + } + } + return true + }), +}) + +// Collect every string message from a Formik errors tree (objects, arrays, strings). +// Variant-level errors (e.g. 'Each SKU can have only one quantity feature') can get +// hidden by Formik when index-level errors are also present, so we walk everything. +const collectErrorMessages = (errors: unknown, depth = 0): string[] => { + if (depth > 6) return [] + if (typeof errors === 'string') return [errors] + if (Array.isArray(errors)) return errors.flatMap((e) => collectErrorMessages(e, depth + 1)) + if (errors && typeof errors === 'object') { + return Object.values(errors).flatMap((e) => collectErrorMessages(e, depth + 1)) + } + return [] +} + +const ProductForm = forwardRef(({ + mode, + initialValues, + onSubmit, + isLoading, + existingVariantImages = [], + existingVariantImageKeys = [], +}, ref) => { + const [variantImages, setVariantImages] = useState(() => + initialValues.variants.length > 0 + ? initialValues.variants.map((_, i) => existingVariantImages[i] || []) + : [[]] + ) + + useImperativeHandle(ref, () => ({ + clearImages: () => setVariantImages(initialValues.variants.map(() => [])), + }), [initialValues.variants]) + + const { data: storesData } = trpc.common.getStoresSummary.useQuery() + const storeOptions = storesData?.stores.map((store) => ({ + label: store.name, + value: store.id, + })) || [] + + const { data: skusData } = trpc.common.product.getAllSkusSummary.useQuery() + const skuOptions = (skusData?.skus || []).map((sku) => ({ + label: sku.label, + value: sku.id, + })) + + // Make sure every SKU starts with a 'quantity' feature (auto-added at the + // beginning if the provided initial values don't have one). + const formInitialValues = useMemo(() => { + return { + ...initialValues, + variants: (initialValues.variants || []).map((v) => { + const hasQuantity = (v.features || []).some( + (a) => (a.featureName ?? '').trim().toLowerCase() === 'quantity' + ) + if (hasQuantity) return v + return { ...v, features: [quantityAttribute(), ...(v.features || [])] } + }), + } + }, [initialValues]) + + return ( + { + // Normalize feature names before sending to backend: the mandatory + // 'quantity' feature must always go out lowercase (case-insensitive + // matching means 'Quantity'/'QUANTITY' are treated the same), and + // names are trimmed like the backend does. + // TextInputs emit strings — coerce price fields to the numeric types + // the backend zod schema requires (price required; market/flash nullable). + const toNumber = (value: unknown): number | null => { + if (value == null || value === '') return null + const n = Number(value) + return Number.isFinite(n) ? n : null + } + const normalizedValues: ProductFormData = { + ...values, + variants: values.variants.map((v) => ({ + ...v, + price: toNumber(v.price) ?? undefined, + marketPrice: toNumber(v.marketPrice), + flashPrice: toNumber(v.flashPrice), + features: v.features.map((a) => ({ + ...a, + featureName: isQuantityFeature(a) ? 'quantity' : (a.featureName ?? '').trim() || null, + })), + })), + } + const images = variantImages.map((imgs) => + imgs.map((img) => ({ url: img.imgUrl, mimeType: img.mimeType })) + ) + const deletedKeys: string[] = [] + if (mode === 'edit') { + variantImages.forEach((currentImgs, vIndex) => { + const existing = existingVariantImages[vIndex] || [] + existing.forEach((existingImg) => { + if (!currentImgs.some((cur) => cur.imgUrl === existingImg.imgUrl)) { + const key = existingVariantImageKeys[vIndex]?.[existingVariantImages[vIndex]?.indexOf(existingImg)] + if (key) deletedKeys.push(key) + } + }) + }) + } + onSubmit(normalizedValues, images, deletedKeys) + }} + enableReinitialize + > + {({ handleChange, handleSubmit, values, setFieldValue, validateForm }) => { + return ( +
+ + + +
+

Store

+ setFieldValue('storeId', Number(value))} + className="w-full" + /> +
+ +
+

Product Type

+ setFieldValue('productType', value as 'item' | 'combo')} + className="w-full" + /> +
+ + + {({ push, remove }) => ( +
+
+

Variants

+ +
+ + {values.variants.map((variant, vIndex) => { + const isExistingSku = variant.id != null + const isMarkedDeleted = !!variant.isDeleted + return ( +
+
+
+

Variant {vIndex + 1}

+ {isMarkedDeleted && ( +
+

Deleted

+
+ )} +
+ {(values.variants.length > 1 || isExistingSku) && ( + + )} +
+ + + + + {({ push: pushAttr, remove: removeAttr }) => ( +
+
+

Attributes

+ +
+ {variant.features.map((attr, aIndex) => { + const quantityCount = variant.features.filter(isQuantityFeature).length + // Quantity features are locked (non-editable), but if there + // are duplicates (e.g. 'quantity' + 'Quantity') the user must + // be able to delete the extras to fix the form. + const canDelete = variant.features.length > 1 && (!isQuantityFeature(attr) || quantityCount > 1) + return ( +
+
+ + setFieldValue( + `variants.${vIndex}.features.${aIndex}.featureName`, + e.target.value.trim().toLowerCase() === 'quantity' ? 'quantity' : e.target.value + ) + } + disabled={isQuantityFeature(attr)} + className={isQuantityFeature(attr) ? 'text-gray-400' : undefined} + /> +
+
+ +
+ {canDelete && ( + + )} +
+ ) + })} +
+ + +
+
+ )} +
+ +
+
+ +
+
+ +
+
+ +
+ { + setFieldValue(`variants.${vIndex}.isFlashAvailable`, !variant.isFlashAvailable) + if (variant.isFlashAvailable) setFieldValue(`variants.${vIndex}.flashPrice`, null) + }} + /> +

Flash Available

+
+ +
+ setFieldValue(`variants.${vIndex}.isOffer`, !variant.isOffer)} + /> +

Offer SKU

+
+ + {!(values.productType === 'combo' && (variant.comboItems?.length || 0) > 0) && ( +
+ setFieldValue(`variants.${vIndex}.isComboOnly`, !variant.isComboOnly)} + /> +

Combo Only SKU

+
+ )} + + {mode === 'edit' && ( +
+ setFieldValue(`variants.${vIndex}.isSuspended`, !variant.isSuspended)} + /> +

Suspend SKU

+
+ )} + + {variant.isFlashAvailable && ( + + )} + + + setVariantImages((prev) => { + const next = [...prev] + next[vIndex] = [...(next[vIndex] || []), ...payloads.map((pl) => ({ imgUrl: pl.url, mimeType: pl.mimeType }))] + return next + }) + } + onImageRemove={(payload) => + setVariantImages((prev) => { + const next = [...prev] + next[vIndex] = (next[vIndex] || []).filter((img) => img.imgUrl !== payload.url) + return next + }) + } + allowMultiple={true} + /> + + {values.productType === 'combo' && ( +
+
+

Included Items

+ +
+ {variant.comboItems?.map((ci, cIndex) => ( +
+
+ ({ + ...opt, + // Disable SKUs already picked in another row of this combo. + disabled: (variant.comboItems || []).some( + (item, idx) => idx !== cIndex && String(item.skuId) === String(opt.value) + ), + }))} + onValueChange={(val) => { + const current = variant.comboItems || [] + const isDuplicate = current.some( + (item, idx) => idx !== cIndex && String(item.skuId) === String(val) + ) + if (isDuplicate) { + window.alert('Duplicate: This product is already in the combo') + return + } + setFieldValue(`variants.${vIndex}.comboItems.${cIndex}.skuId`, Number(val)) + }} + placeholder="Select SKU" + /> +
+ +
+ ))} +
+ )} +
+ ) + })} + + +
+ )} +
+ + +
+ ) + }} +
+ ) +}) + +ProductForm.displayName = 'ProductForm' + +export default ProductForm diff --git a/apps/admin-web/src/components/ProductGroupForm.tsx b/apps/admin-web/src/components/ProductGroupForm.tsx new file mode 100644 index 0000000..8ae88f7 --- /dev/null +++ b/apps/admin-web/src/components/ProductGroupForm.tsx @@ -0,0 +1,140 @@ +import { type FC } from 'react' +import { useFormik } from 'formik' +import { p as P, pInput as PInput } from 'web-components' +import ProductsSelector from './ProductsSelector' +import { trpc } from '@/lib/trpc-client' +import { X } from 'lucide-react' +import type { AdminProductGroup as SharedAdminProductGroup } from '@packages/shared' + +// Serialized product group (string date, loosely typed products) anchored to shared +export type ProductGroup = Omit & { + createdAt: string + products: any[] +} + +interface ProductGroupFormProps { + group?: ProductGroup | null + onClose: () => void + onSuccess: () => void +} + +const ProductGroupForm: FC = ({ + group, + onClose, + onSuccess, +}) => { + // Fetch products + const { data: productsData } = trpc.common.product.getAllProductsSummary.useQuery() + + const createGroup = trpc.admin.product.createGroup.useMutation() + const updateGroup = trpc.admin.product.updateGroup.useMutation() + + const isEditing = !!group + + const products = productsData?.products || [] + + const formik = useFormik({ + initialValues: { + group_name: group?.groupName || '', + description: group?.description || '', + product_ids: group?.products?.map(p => p.id) || [], + }, + validate: (values) => { + const errors: {[key: string]: string} = {} + + if (!values.group_name.trim()) { + errors.group_name = 'Group name is required' + } + + return errors + }, + onSubmit: async (values) => { + try { + if (isEditing) { + await updateGroup.mutateAsync({ + id: group.id, + group_name: values.group_name, + description: values.description, + product_ids: values.product_ids, + }) + } else { + await createGroup.mutateAsync({ + group_name: values.group_name, + description: values.description, + product_ids: values.product_ids, + }) + } + onSuccess() + } catch (error: any) { + window.alert(`Error: ${error.message || 'Failed to save group'}`) + } + }, + }) + + return ( +
+ {/* Header */} +
+

+ {isEditing ? 'Edit Product Group' : 'Create Product Group'} +

+ +
+ +
+ {/* Group Name */} + formik.setFieldValue('group_name', e.target.value)} + style={{ marginBottom: 16 }} + /> + {formik.errors.group_name && ( +

{formik.errors.group_name}

+ )} + + {/* Description */} + formik.setFieldValue('description', e.target.value)} + style={{ marginBottom: 16 }} + /> + + {/* Products Selection */} + formik.setFieldValue('product_ids', value as number[])} + multiple={true} + label="Products" + placeholder="Select products" + labelFormat={(product) => product.label} + /> + + {/* Actions */} +
+
+ Cancel +
+
formik.handleSubmit()} + className="flex-1 bg-brand-600 rounded-lg py-4 items-center text-center text-white font-medium cursor-pointer" + > + {createGroup.isPending || updateGroup.isPending ? 'Saving...' : 'Save'} +
+
+
+
+ ) +} + +export default ProductGroupForm diff --git a/apps/admin-web/src/components/ProductListDialog.tsx b/apps/admin-web/src/components/ProductListDialog.tsx new file mode 100644 index 0000000..a8071cc --- /dev/null +++ b/apps/admin-web/src/components/ProductListDialog.tsx @@ -0,0 +1,39 @@ +import type { FC } from 'react' +import { BottomDialog, p as P } from 'web-components' +import type { IdName } from '@packages/shared' + +type VendorSnippetProduct = IdName + +interface ProductListDialogProps { + open: boolean + onClose: () => void + products: VendorSnippetProduct[] +} + +export const ProductListDialog: FC = ({ + open, + onClose, + products, +}) => { + return ( + +
+

+ Products ({products.length}) +

+
+ {products.map((product, index) => ( +
+

+ {product.name} +

+
+ ))} +
+
+
+ ) +} diff --git a/apps/admin-web/src/components/ProductsSelector.tsx b/apps/admin-web/src/components/ProductsSelector.tsx new file mode 100644 index 0000000..e4e71c9 --- /dev/null +++ b/apps/admin-web/src/components/ProductsSelector.tsx @@ -0,0 +1,177 @@ +import React, { useState, useMemo } from 'react' +import { trpc } from '@/lib/trpc-client' +import type { SkuSummary as SharedSkuSummary } from '@packages/shared' +import MultiSelect from './MultiSelect' +import SearchableSelect from './SearchableSelect' + +// Selector works with skus that may not have images resolved yet +type SkuSummary = Omit + +interface Group { + id: number + groupName: string + products: { id: number }[] +} + +interface ProductsSelectorProps { + value: number | number[] + onChange: (value: number | number[]) => void + multiple?: boolean + label?: string + placeholder?: string + disabled?: boolean + error?: boolean + isDisabled?: (product: SkuSummary) => boolean + labelFormat?: (product: SkuSummary) => string + groups?: Group[] + selectedGroupIds?: number[] + onGroupChange?: (groupIds: number[]) => void + showGroups?: boolean +} + +export default function ProductsSelector({ + value, + onChange, + multiple = true, + label = 'Select Products', + placeholder = 'Select products', + disabled = false, + error = false, + isDisabled, + labelFormat, + groups = [], + showGroups = true, + selectedGroupIds = [], + onGroupChange, +}: ProductsSelectorProps) { + const { data: skusData } = trpc.common.product.getAllSkusSummary.useQuery() + const allSkus: SkuSummary[] = skusData?.skus || [] + const [searchQuery, setSearchQuery] = useState('') + + // Handle group selection changes + const handleGroupChange = (newGroupIds: number[]) => { + if (!onGroupChange) return + + const previousGroupIds = selectedGroupIds + + const addedGroups = newGroupIds.filter(id => !previousGroupIds.includes(id)) + const removedGroups = previousGroupIds.filter(id => !newGroupIds.includes(id)) + + let currentSkus = Array.isArray(value) ? [...value] : value ? [value] : [] + + const addedSkus = addedGroups.flatMap(groupId => { + const group = groups.find(g => g.id === groupId) + if (!group) return [] + const productIds = new Set(group.products.map(p => p.id)) + return allSkus.filter(s => productIds.has(s.productId)).map(s => s.id) + }) + + const removedSkus = removedGroups.flatMap(groupId => { + const group = groups.find(g => g.id === groupId) + if (!group) return [] + const productIds = new Set(group.products.map(p => p.id)) + return allSkus.filter(s => productIds.has(s.productId)).map(s => s.id) + }) + + currentSkus = [...new Set([...currentSkus, ...addedSkus])] + currentSkus = currentSkus.filter(id => !removedSkus.includes(id)) + + onGroupChange(newGroupIds) + if (multiple) { + onChange(currentSkus.length > 0 ? currentSkus : []) + } else { + onChange(currentSkus.length > 0 ? currentSkus[0] : 0) + } + } + + // Filter products based on search query + const filteredSkus = useMemo(() => { + if (!searchQuery.trim()) return allSkus + + const query = searchQuery.toLowerCase() + return allSkus.filter(sku => + sku.label.toLowerCase().includes(query) || + sku.productName.toLowerCase().includes(query) + ) + }, [allSkus, searchQuery]) + + // Build dropdown options + const productOptions = useMemo(() => { + return filteredSkus.map((sku) => { + const isFromGroup = selectedGroupIds.length > 0 && groups.some(group => { + if (!selectedGroupIds.includes(group.id)) return false + return group.products.some(p => p.id === sku.productId) + }) + + const isProductDisabled = isDisabled ? isDisabled(sku) : false + + const displayLabel = labelFormat + ? labelFormat(sku) + : sku.label + + return { + label: `${displayLabel}${isFromGroup ? ' (from group)' : ''}`, + value: sku.id.toString(), + disabled: isProductDisabled, + } + }) + }, [filteredSkus, selectedGroupIds, groups, isDisabled, labelFormat]) + + // Build group options if groups are provided + const groupOptions = useMemo(() => { + return groups.map(group => ({ + label: group.groupName, + value: group.id.toString(), + })) + }, [groups]) + + return ( +
+ {showGroups && groups.length > 0 && ( +
+ id.toString())} + onValueChange={(selectedValue) => { + const selectedValues = Array.isArray(selectedValue) ? selectedValue : typeof selectedValue === 'string' ? [selectedValue] : [] + const newGroupIds = selectedValues.map(v => parseInt(v as string)) + handleGroupChange(newGroupIds) + }} + placeholder="Select product groups (optional)" + /> +
+ )} + + {multiple ? ( + id.toString()) : []} + onValueChange={(selectedValue) => { + const selectedValues = Array.isArray(selectedValue) ? selectedValue : typeof selectedValue === 'string' ? [selectedValue] : [] + onChange(selectedValues.map(v => Number(v))) + }} + placeholder={placeholder} + disabled={disabled} + error={error} + onSearch={setSearchQuery} + /> + ) : ( + { + onChange(Number(selectedValue)) + }} + placeholder={placeholder} + disabled={disabled} + error={error} + onSearch={setSearchQuery} + /> + )} +
+ ) +} diff --git a/apps/admin-web/src/components/SearchableSelect.tsx b/apps/admin-web/src/components/SearchableSelect.tsx new file mode 100644 index 0000000..98ef9eb --- /dev/null +++ b/apps/admin-web/src/components/SearchableSelect.tsx @@ -0,0 +1,114 @@ +import { useMemo, useState } from 'react' +import { BottomDialog, SearchBar, p as P } from 'web-components' +import { Check, ChevronDown } from 'lucide-react' + +export interface SearchableSelectOption { + label: string + value: string | number + disabled?: boolean +} + +interface SearchableSelectProps { + label: string + options: SearchableSelectOption[] + value: string | number + onValueChange: (v: string | number) => void + onSearch?: (q: string) => void + placeholder?: string + disabled?: boolean + error?: boolean + className?: string + testID?: string + // Tolerated for screen compatibility (RN BottomDropdown leftover) — ignored on web + triggerComponent?: any +} + +export function SearchableSelect({ + label, + options, + value, + onValueChange, + onSearch, + placeholder, + disabled = false, + error = false, + className, + testID, +}: SearchableSelectProps) { + const [open, setOpen] = useState(false) + const [query, setQuery] = useState('') + + const selectedLabel = useMemo(() => { + const found = options.find((o) => String(o.value) === String(value)) + return found ? found.label : null + }, [options, value]) + + const displayText = selectedLabel ?? placeholder ?? label + + const filtered = useMemo(() => { + const q = query.trim().toLowerCase() + if (!q) return options + return options.filter((o) => o.label.toLowerCase().includes(q)) + }, [options, query]) + + const handleSelect = (optionValue: string | number) => { + onValueChange(optionValue) + setOpen(false) + } + + return ( +
+

{label}

+ + setOpen(false)}> +
+

{label}

+ { + setQuery(q) + onSearch?.(q) + }} + onSearch={onSearch} + className="mb-3" + /> +
+ {filtered.map((option) => { + const selected = String(option.value) === String(value) + return ( + + ) + })} + {filtered.length === 0 ? ( +

No options found

+ ) : null} +
+
+
+
+ ) +} + +export default SearchableSelect diff --git a/apps/admin-web/src/components/SlotForm.tsx b/apps/admin-web/src/components/SlotForm.tsx new file mode 100644 index 0000000..18a7537 --- /dev/null +++ b/apps/admin-web/src/components/SlotForm.tsx @@ -0,0 +1,229 @@ +import React from 'react' +import type { SlotSnippetInput } from '@packages/shared' +import { Formik, FieldArray } from 'formik' +import DateTimeInput from './DateTimeInput' +import { p as P, pInput as PInput } from 'web-components' +import { trpc } from '@/lib/trpc-client' +import ProductsSelector from './ProductsSelector' + +// Snippet form row — single source in @packages/shared (complete payload) +type VendorSnippet = SlotSnippetInput + +interface SlotFormProps { + onSlotAdded?: () => void + initialDeliveryTime?: Date | null + initialFreezeTime?: Date | null + initialIsActive?: boolean + slotId?: number + initialProductIds?: number[] + initialGroupIds?: number[] +} + +export default function SlotForm({ + onSlotAdded, + initialDeliveryTime, + initialFreezeTime, + initialIsActive = true, + slotId, + initialProductIds = [], + initialGroupIds = [], +}: SlotFormProps) { + const { data: slotData } = trpc.admin.slots.getSlotById.useQuery( + { id: slotId! }, + { enabled: !!slotId } + ) + + const vendorSnippetsFromSlot = (slotData?.slot?.vendorSnippets || []).map((snippet: any) => ({ + name: snippet.name || '', + groupIds: snippet.groupIds || [], + skuIds: snippet.skuIds || [], + validTill: snippet.validTill || null, + })) as VendorSnippet[] + + const initialValues = { + deliveryTime: initialDeliveryTime || (slotData?.slot?.deliveryTime ? new Date(slotData.slot.deliveryTime) : null), + freezeTime: initialFreezeTime || (slotData?.slot?.freezeTime ? new Date(slotData.slot.freezeTime) : null), + selectedGroupIds: initialGroupIds.length > 0 ? initialGroupIds : (slotData?.slot?.groupIds || []), + selectedSkuIds: initialProductIds.length > 0 ? initialProductIds : (slotData?.slot?.products?.map((p: any) => p.id) || []), + vendorSnippetList: vendorSnippetsFromSlot, + } + + const { mutate: createSlot, isPending: isCreating } = trpc.admin.slots.createSlot.useMutation() + const { mutate: updateSlot, isPending: isUpdating } = trpc.admin.slots.updateSlot.useMutation() + + const isEditMode = !!slotId + const isPending = isCreating || isUpdating + + const { data: groupsData } = trpc.admin.product.getGroups.useQuery() + + const handleFormSubmit = (values: typeof initialValues) => { + if (!values.deliveryTime || !values.freezeTime) { + window.alert('Error: Please fill all fields') + return + } + + if (values.freezeTime > values.deliveryTime) { + window.alert('Error: Freeze time must be before or equal to delivery time') + return + } + + const slotInputData = { + deliveryTime: values.deliveryTime.toISOString(), + freezeTime: values.freezeTime.toISOString(), + isActive: initialIsActive, + groupIds: values.selectedGroupIds, + skuIds: values.selectedSkuIds, + vendorSnippets: values.vendorSnippetList.map((snippet: VendorSnippet) => ({ + name: snippet.name, + skuIds: snippet.skuIds, + validTill: snippet.validTill ?? undefined, + })), + } + + if (isEditMode && slotId) { + updateSlot( + { id: slotId, ...slotInputData }, + { + onSuccess: () => { + window.alert('Success: Slot updated successfully!') + onSlotAdded?.() + }, + onError: (error: any) => { + console.log({msg: JSON.stringify(error.message)}) + + window.alert(`Error: ${error.message || 'Failed to update slot'}`) + }, + } + ) + } else { + createSlot( + slotInputData, + { + onSuccess: () => { + window.alert('Success: Slot created successfully!') + onSlotAdded?.() + }, + onError: (error: any) => { + window.alert(`Error: ${error.message || 'Failed to create slot'}`) + }, + } + ) + } + } + + return ( + + {({ handleSubmit, values, setFieldValue }) => { + const mappedGroups = (groupsData?.groups || []).map(group => ({ + ...group, + products: group.products.map(product => ({ + ...product, + id: product.id, + })), + })) + + return ( +
+

+ {isEditMode ? 'Edit Slot' : 'Create New Slot'} +

+ +
+

Delivery Date & Time

+ setFieldValue('deliveryTime', value)} + /> +
+ +
+

Freeze Date & Time

+ setFieldValue('freezeTime', value)} + /> +
+ +
+ setFieldValue('selectedSkuIds', newSkuIds)} + groups={mappedGroups} + selectedGroupIds={values.selectedGroupIds} + onGroupChange={(newGroupIds) => setFieldValue('selectedGroupIds', newGroupIds)} + label="Select Products" + placeholder="Select products for this slot" + /> +
+ + {/* Vendor Snippets */} + + {({ push, remove }) => ( +
+

Vendor Snippets

+ {values.vendorSnippetList.map((snippet: VendorSnippet, index: number) => ( +
+
+ setFieldValue(`vendorSnippetList.${index}.name`, e.target.value)} + /> +
+ +
+ setFieldValue(`vendorSnippetList.${index}.skuIds`, newSkuIds)} + groups={mappedGroups.filter(group => + values.selectedGroupIds.includes(group.id) + ).map(group => ({ + ...group, + products: group.products.filter((prod: any) => values.selectedSkuIds.includes(prod.id)) + }))} + selectedGroupIds={snippet.groupIds || []} + onGroupChange={(newGroupIds) => setFieldValue(`vendorSnippetList.${index}.groupIds`, newGroupIds)} + label="Select Products" + placeholder="Select products for snippet" + isDisabled={(sku) => !values.selectedSkuIds.includes(sku.id)} + /> +
+ +
+ ))} + +
+ )} +
+ + +
+ )}} +
+ ) +} diff --git a/apps/admin-web/src/components/SnippetMenu.tsx b/apps/admin-web/src/components/SnippetMenu.tsx new file mode 100644 index 0000000..893f93d --- /dev/null +++ b/apps/admin-web/src/components/SnippetMenu.tsx @@ -0,0 +1,156 @@ +import { useState, type FC } from 'react' +import { p as P, BottomDialog } from 'web-components' +import { SuccessToast } from '@/services/toaster' +import type { VendorSnippet } from '@/types/vendor-snippets' +import { Eye, Pencil, Link, Trash2, MoreVertical } from 'lucide-react' +import type { CSSProperties } from 'react' + +export interface SnippetMenuOption { + title: string + icon: 'eye' | 'edit' | 'link' | 'trash' + onPress: () => void + disabled?: boolean +} + +export interface SnippetMenuProps { + snippet: VendorSnippet + onEdit: (snippet: VendorSnippet) => void + onDelete: (id: number) => void + onViewOrders: (snippetCode: string) => void + triggerStyle?: any + iconSize?: number + iconColor?: string +} + +const iconMap = { + eye: Eye, + edit: Pencil, + link: Link, + trash: Trash2, +} + +export const SnippetMenu: FC = ({ + snippet, + onEdit, + onDelete, + onViewOrders, + triggerStyle = 'p-2 rounded-full bg-gray-50', + iconSize = 16, + iconColor = '#6B7280', +}) => { + const [isOpen, setIsOpen] = useState(false) + + const handleOpenMenu = () => { + setIsOpen(true) + } + + const handleCloseMenu = () => { + setIsOpen(false) + } + + const handleViewOrders = () => { + setIsOpen(false) + onViewOrders(snippet.snippetCode) + } + + const handleEdit = () => { + setIsOpen(false) + onEdit(snippet) + } + + const handleDelete = () => { + setIsOpen(false) + const confirmed = window.confirm( + 'Delete Snippet? Are you sure you want to delete this vendor snippet?' + ) + if (confirmed) { + onDelete(snippet.id) + } + } + + const handleCopyUrl = async () => { + setIsOpen(false) + if (!snippet.accessUrl) { + window.alert('Error: No URL available to copy') + return + } + await navigator.clipboard.writeText(snippet.accessUrl) + SuccessToast('URL copied to clipboard') + } + + const options: SnippetMenuOption[] = [ + { + title: 'View Orders', + icon: 'eye', + onPress: handleViewOrders, + }, + { + title: 'Edit', + icon: 'edit', + onPress: handleEdit, + }, + { + title: 'Copy URL', + icon: 'link', + onPress: handleCopyUrl, + }, + { + title: 'Delete', + icon: 'trash', + onPress: handleDelete, + }, + ] + + const handleOptionPress = (option: SnippetMenuOption) => { + if (option.disabled) return + option.onPress() + } + + const triggerClassName = typeof triggerStyle === 'string' ? triggerStyle : 'p-2 rounded-full bg-gray-50' + const triggerStyleObj: CSSProperties | undefined = typeof triggerStyle === 'object' ? triggerStyle : undefined + + return ( + <> + {/* Menu Trigger */} + + + {/* Menu Dialog */} + +
+

+ Snippet Options +

+ + {options.map((option, index) => { + const Icon = iconMap[option.icon] + return ( + + ) + })} +
+
+ + ) +} diff --git a/apps/admin-web/src/components/SnippetOrdersView.tsx b/apps/admin-web/src/components/SnippetOrdersView.tsx new file mode 100644 index 0000000..6186aa2 --- /dev/null +++ b/apps/admin-web/src/components/SnippetOrdersView.tsx @@ -0,0 +1,156 @@ +import { Fragment, type FC } from 'react' +import { p as P, AppContainer } from 'web-components' +import { ShoppingCart } from 'lucide-react' +import type { + AdminVendorSnippetOrderProduct, + AdminVendorSnippetOrderSummary as SharedSnippetOrderSummary, +} from '@packages/shared' + +// Line item + order summary anchored to the shared vendor-order contract +// (string totalAmount + any[] sequence at this view layer) +type OrderProduct = Pick< + AdminVendorSnippetOrderProduct, + 'productId' | 'productName' | 'quantity' | 'price' | 'unit' | 'subtotal' +> + +type SnippetOrder = Omit & { + totalAmount: string + slotInfo: { + time: string + sequence: any[] + } | null + products: OrderProduct[] +} + +interface SnippetOrdersViewProps { + orders: SnippetOrder[] + snippetCode: string + onClose: () => void +} + +const OrderCard: FC<{ order: SnippetOrder; index: number }> = ({ order, index }) => { + const orderDate = new Date(order.orderDate) + const slotTime = order.slotInfo ? new Date(order.slotInfo.time) : null + + return ( +
+ {/* Order Header */} +
+
+

{order.orderId}

+

{order.customerName}

+
+
+

₹{order.totalAmount}

+

+ {orderDate.toLocaleDateString()} +

+
+
+ + {/* Slot Info */} + {slotTime && ( +
+

+ Delivery: {slotTime.toLocaleString()} +

+
+ )} + + {/* Products */} +
+

Products:

+ {order.products.map((product, index) => { + const isMatched = order.matchedProducts.includes(product.productId) + return ( +
+
+

+ {product.productName} + {isMatched && ' ⭐'} +

+

+ {product.quantity} {product.unit} × ₹{product.price} +

+
+

+ ₹{product.subtotal.toFixed(2)} +

+
+ ) + })} +
+ + {/* Matched Products Summary */} +
+

+ Matched {order.matchedProducts.length} product(s) from snippet "{order.snippetCode}" +

+
+
+ ) +} + +const SnippetOrdersView: FC = ({ + orders, + snippetCode, + onClose, +}) => { + const totalOrders = orders.length + const totalRevenue = orders.reduce((sum, order) => sum + parseFloat(order.totalAmount), 0) + + return ( + +
+ {/* Header */} +
+
+
+

Orders for "{snippetCode}"

+

+ {totalOrders} order{totalOrders !== 1 ? 's' : ''} • Total: ₹{totalRevenue.toFixed(2)} +

+
+ +
+
+ + {/* Orders List */} +
+ {orders.length === 0 ? ( +
+ +

No matching orders

+

+ No orders found that match this snippet's criteria +

+
+ ) : ( +
+ {orders.map((order, index) => ( + + + {index < orders.length - 1 && ( +
+ )} + + ))} +
+ )} +
+
+ + ) +} + +export default SnippetOrdersView diff --git a/apps/admin-web/src/components/StoreForm.tsx b/apps/admin-web/src/components/StoreForm.tsx new file mode 100644 index 0000000..e44870b --- /dev/null +++ b/apps/admin-web/src/components/StoreForm.tsx @@ -0,0 +1,197 @@ +import { useState, useEffect, useMemo, useRef, type ChangeEvent } from 'react' +import { Formik } from 'formik' +import * as Yup from 'yup' +import { pInput as PInput, Dropdown, p as P, ImageUploader } from 'web-components' +import ProductsSelector from './ProductsSelector' +import { trpc } from '@/lib/trpc-client' +import { useUploadToObjectStorage } from '@/hooks/useUploadToObjectStorage' +import type { CreateStoreInput } from '@packages/shared' + +// Store form values — required description + product selection on top of CreateStoreInput +export type StoreFormData = Omit & { + description: string + products: number[] +} + +interface StoreFormProps { + mode: 'create' | 'edit' + initialValues: StoreFormData + onSubmit: (values: StoreFormData) => void + isLoading: boolean + storeId?: number +} + +const validationSchema = Yup.object().shape({ + name: Yup.string().required('Name is required'), + description: Yup.string(), + imageUrl: Yup.string(), + owner: Yup.number().required('Owner is required'), + products: Yup.array().of(Yup.number()), +}) + +function StoreForm({ mode, initialValues, onSubmit, isLoading, storeId }: StoreFormProps) { + const { data: staffData } = trpc.admin.staffUser.getStaff.useQuery() + const { data: productsData } = trpc.admin.product.getProducts.useQuery() + + const [formInitialValues, setFormInitialValues] = useState(initialValues) + const [selectedImages, setSelectedImages] = useState<{ blob: Blob; mimeType: string }[]>([]) + const [displayImages, setDisplayImages] = useState<{ uri?: string }[]>([]) + const fileInputRef = useRef(null) + + // For edit mode, pre-select SKUs belonging to this store's products + const initialSelectedProducts = useMemo(() => { + if (mode !== 'edit' || !productsData?.products) return [] + return productsData.products + .filter(p => p.storeId === storeId) + .flatMap(p => (p.skus || []).map(sku => sku.id)) + }, [mode, productsData?.products, storeId]) + + useEffect(() => { + setFormInitialValues({ + ...initialValues, + products: initialSelectedProducts, + }) + }, [initialValues, initialSelectedProducts]) + + const existingImageUrls = useMemo( + () => (formInitialValues.imageUrl ? [formInitialValues.imageUrl] : []), + [formInitialValues.imageUrl] + ) + + const staffOptions = staffData?.staff.map((staff: { id: number; name: string }) => ({ + label: staff.name, + value: staff.id, + })) || [] + + const { uploadSingle, isUploading } = useUploadToObjectStorage() + + const handleImagePick = () => { + fileInputRef.current?.click() + } + + const handleFileChange = (e: ChangeEvent) => { + const files = Array.from(e.target.files || []) + if (files.length === 0) { + setSelectedImages([]) + setDisplayImages([]) + return + } + const file = files[0] + setSelectedImages([{ blob: file, mimeType: file.type || 'image/jpeg' }]) + setDisplayImages([{ uri: URL.createObjectURL(file) }]) + e.target.value = '' + } + + const handleRemoveImage = (uri: string) => { + const index = displayImages.findIndex(img => img.uri === uri) + if (index !== -1) { + const newDisplay = displayImages.filter((_, i) => i !== index) + const newFiles = selectedImages.filter((_, i) => i !== index) + setDisplayImages(newDisplay) + setSelectedImages(newFiles) + } + } + + return ( + + {({ handleChange, handleSubmit, values, setFieldValue, errors, touched }) => { + const submit = async () => { + try { + let imageUrl: string | undefined + + if (selectedImages.length > 0) { + const { blob, mimeType } = selectedImages[0] + const { presignedUrl } = await uploadSingle(blob, mimeType, 'store') + imageUrl = presignedUrl + } + + onSubmit({ ...values, imageUrl }) + } catch (error) { + console.error('Upload error:', error) + window.alert('Error: Failed to upload image') + } + } + + return ( +
+ + + +
+

Owner

+ setFieldValue('owner', Number(value))} + className="mb-4" + /> +
+ setFieldValue('products', value)} + multiple={true} + label="Products" + placeholder="Select products" + isDisabled={(sku) => sku.storeId !== null && sku.storeId !== storeId} + labelFormat={(sku) => `${sku.productName} - ₹${sku.price}`} + /> +
+

Store Image

+ + setFormInitialValues((prev) => ({ + ...prev, + imageUrl: undefined, + })) + } + allowMultiple={false} + /> +
+ +
+ ) + }} +
+ ) +} + +export default StoreForm diff --git a/apps/admin-web/src/components/TagForm.tsx b/apps/admin-web/src/components/TagForm.tsx new file mode 100644 index 0000000..356deb3 --- /dev/null +++ b/apps/admin-web/src/components/TagForm.tsx @@ -0,0 +1,345 @@ +import { useState, useEffect, forwardRef, useCallback, type CSSProperties } from 'react' +import { Formik } from 'formik' +import * as Yup from 'yup' +import { pInput as PInput, p as P, Checkbox, ImageUploaderNeo } from 'web-components' +import type { ImageUploaderNeoItem, ImageUploaderNeoPayload } from 'web-components' +import MultiSelect from './MultiSelect' +import { GripVertical, X, Package, Image as ImageIcon } from 'lucide-react' +import { DndContext, closestCenter, PointerSensor, useSensor, useSensors } from '@dnd-kit/core' +import type { DragEndEvent } from '@dnd-kit/core' +import { SortableContext, useSortable, verticalListSortingStrategy, arrayMove } from '@dnd-kit/sortable' +import { CSS } from '@dnd-kit/utilities' +import ProductsSelector from './ProductsSelector' +import { trpc } from '@/lib/trpc-client' +import useFocusCallback from '@/lib/refresh-context' +import type { IdName } from '@packages/shared' + +type StoreOption = IdName + +export interface TagFormData { + tagName: string + tagDescription: string + isDashboardTag: boolean + relatedStores: number[] + productIds: number[] +} + +interface TagFormProps { + mode: 'create' | 'edit' + initialValues: TagFormData + existingImageUrl?: string + onSubmit: (values: TagFormData, images: ImageUploaderNeoItem[], removedExisting: boolean) => void + isLoading: boolean + stores?: StoreOption[] +} + +interface SelectedProduct { + skuId: number + productId: number + label: string + imageUrl?: string | null +} + +const itemStyle: CSSProperties = { + backgroundColor: 'white', + borderRadius: 8, + borderWidth: 1, + borderColor: '#e5e7eb', + borderStyle: 'solid', + padding: 10, + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + boxShadow: '0 1px 2px rgba(0, 0, 0, 0.1)', + marginTop: 4, + marginBottom: 4, +} + +function SortableProductRow({ item, onRemove }: { item: SelectedProduct; onRemove: (productId: number) => void }) { + const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: item.productId }) + const style: CSSProperties = { + ...itemStyle, + transform: CSS.Transform.toString(transform), + transition, + ...(isDragging + ? { borderColor: '#3b82f6', boxShadow: '0 4px 8px rgba(59, 130, 246, 0.3)' } + : {}), + } + return ( +
+ + {item.imageUrl ? ( + {item.label} + ) : ( +
+ +
+ )} +

+ {item.label} +

+ +
+ ) +} + +const TagForm = forwardRef(({ + mode, + initialValues, + existingImageUrl: existingImageUrlRaw, + onSubmit, + isLoading, + stores: storesRaw, +}, ref) => { + const [images, setImages] = useState([]) + const [removedExisting, setRemovedExisting] = useState(false) + const [isDashboardTagChecked, setIsDashboardTagChecked] = useState(Boolean(initialValues.isDashboardTag)) + const [selectedProducts, setSelectedProducts] = useState([]) + const sensors = useSensors(useSensor(PointerSensor)) + + const existingImageUrl = existingImageUrlRaw || '' + const stores = storesRaw || [] + + const { data: skusData } = trpc.common.product.getAllSkusSummary.useQuery() + const allSkus: SelectedProduct[] = (skusData?.skus || []).map((sku: any) => ({ + skuId: sku.id, + productId: sku.productId, + label: sku.label, + imageUrl: sku.images?.[0] || null, + })) + + // Build the ordered list from initialValues.productIds (product ids, in sortOrder). + useEffect(() => { + const ordered: SelectedProduct[] = [] + const skuMap = new Map() + for (const sku of allSkus) { + skuMap.set(sku.productId, sku) + } + for (const productId of initialValues.productIds || []) { + const sku = skuMap.get(productId) + if (sku) ordered.push(sku) + else ordered.push({ skuId: 0, productId, label: `Product #${productId}`, imageUrl: null }) + } + setSelectedProducts(ordered) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [initialValues.productIds, skusData]) + + // Update checkbox when initial values change + useEffect(() => { + setIsDashboardTagChecked(Boolean(initialValues.isDashboardTag)) + if (existingImageUrl) { + setImages([{ imgUrl: existingImageUrl, mimeType: null }]) + } else { + setImages([]) + } + setRemovedExisting(false) + }, [existingImageUrlRaw, initialValues.isDashboardTag]) + + const validationSchema = Yup.object().shape({ + tagName: Yup.string() + .required('Tag name is required') + .min(1, 'Tag name must be at least 1 character') + .max(100, 'Tag name must be less than 100 characters'), + tagDescription: Yup.string() + .max(500, 'Description must be less than 500 characters'), + }) + + // When a product is picked in the selector, add it to the ordered list (if not already present). + const handleProductSelect = (value: number | number[]) => { + const skuIds = Array.isArray(value) ? value : [value] + setSelectedProducts((prev) => { + const next = [...prev] + for (const skuId of skuIds) { + if (next.some((prod) => prod.skuId === skuId)) continue + const sku = allSkus.find((s) => s.skuId === skuId) + if (sku) next.push(sku) + } + return next + }) + } + + const handleDragEnd = useCallback((event: DragEndEvent) => { + const { active, over } = event + if (!over || active.id === over.id) return + setSelectedProducts((prev) => { + const oldIndex = prev.findIndex((prod) => prod.productId === active.id) + const newIndex = prev.findIndex((prod) => prod.productId === over.id) + if (oldIndex === -1 || newIndex === -1) return prev + return arrayMove(prev, oldIndex, newIndex) + }) + }, []) + + const handleRemoveProduct = useCallback((productId: number) => { + setSelectedProducts((prev) => prev.filter((prod) => prod.productId !== productId)) + }, []) + + return ( + onSubmit({ ...values, productIds: selectedProducts.map((prod) => prod.productId) }, images, removedExisting)} + enableReinitialize + > + {({ handleChange, handleSubmit, values, setFieldValue, errors, touched, resetForm }) => { + // Clear form when screen comes into focus (create mode only — edit keeps its loaded products) + const clearForm = useCallback(() => { + setImages([]) + setRemovedExisting(false) + setIsDashboardTagChecked(false) + if (mode === 'create') { + setSelectedProducts([]) + } + resetForm() + }, [resetForm, mode]) + + useFocusCallback(clearForm) + + return ( +
+ + {errors.tagName && touched.tagName ? ( +

{errors.tagName}

+ ) : null} + + + {errors.tagDescription && touched.tagDescription ? ( +

{errors.tagDescription}

+ ) : null} + + {/* Image Upload Section */} +
+

+ Tag Image {mode === 'edit' ? '(Upload new to replace)' : '(Optional)'} +

+ + { + setImages((prev) => [...prev, ...payload.map((img) => ({ + imgUrl: img.url, + mimeType: img.mimeType, + }))]) + }} + onImageRemove={(payload) => { + if (payload.mimeType === null) { + setRemovedExisting(true) + } + setImages((prev) => prev.filter((item) => item.imgUrl !== payload.url)) + }} + allowMultiple={false} + /> +
+ + {/* Dashboard Tag Checkbox */} +
+ { + const newValue = !isDashboardTagChecked + setIsDashboardTagChecked(newValue) + setFieldValue('isDashboardTag', newValue) + }} + /> +

Mark as Dashboard Tag

+
+ + {/* Related Stores Dropdown */} +
+

+ Related Stores +

+ id.toString())} + options={stores.map(store => ({ + label: store.name, + value: store.id.toString(), + }))} + onValueChange={(selectedValues) => { + const numericValues = (selectedValues as string[]).map(v => parseInt(v)) + setFieldValue('relatedStores', numericValues) + }} + /> +
+ + {/* Products Section: selector + reorderable list */} +
+

+ Products +

+ +
+ {selectedProducts.length > 0 && ( +
+

+ Drag to reorder • {selectedProducts.length} items +

+
+ )} + {selectedProducts.length > 0 ? ( + + prod.productId)} strategy={verticalListSortingStrategy}> + {selectedProducts.map((prod) => ( + + ))} + + + ) : ( +
+ +

No products selected yet

+
+ )} +
+
+ + +
+ ) + }} +
+ ) +}) + +TagForm.displayName = 'TagForm' + +export default TagForm diff --git a/apps/admin-web/src/components/TagMenu.tsx b/apps/admin-web/src/components/TagMenu.tsx new file mode 100644 index 0000000..62c93fa --- /dev/null +++ b/apps/admin-web/src/components/TagMenu.tsx @@ -0,0 +1,122 @@ +import { useState, type FC } from 'react' +import { p as P, BottomDialog } from 'web-components' +import { useNavigate } from '@tanstack/react-router' +import { trpc } from '@/lib/trpc-client' +import { Pencil, Trash2, MoreVertical } from 'lucide-react' +import type { CSSProperties } from 'react' + +export interface TagMenuProps { + tagId: number + onDeleteSuccess?: () => void + triggerStyle?: any + iconSize?: number + iconColor?: string +} + +export const TagMenu: FC = ({ + tagId, + onDeleteSuccess, + triggerStyle = 'p-2 rounded-full bg-gray-50', + iconSize = 16, + iconColor = '#6B7280', +}) => { + const [isOpen, setIsOpen] = useState(false) + const navigate = useNavigate() + const deleteTag = trpc.admin.product.deleteProductTag.useMutation() + + const handleOpenMenu = () => { + setIsOpen(true) + } + + const handleCloseMenu = () => { + setIsOpen(false) + } + + const handleEditTag = () => { + setIsOpen(false) + navigate({ to: '/dashboard/product-tags/edit', search: { tagId: String(tagId) } }) + } + + const handleDeleteTag = () => { + setIsOpen(false) + const confirmed = window.confirm( + 'Delete Tag? Are you sure you want to delete this tag? This action cannot be undone.' + ) + if (confirmed) { + performDelete() + } + } + + const performDelete = () => { + deleteTag.mutate({ id: tagId }, { + onSuccess: () => { + window.alert('Success: Tag deleted successfully') + onDeleteSuccess?.() + }, + onError: (error: any) => { + const errorMessage = error.message || 'Failed to delete tag' + window.alert(`Error: ${errorMessage}`) + }, + }) + } + + const options = [ + { + title: 'Edit Tag', + icon: Pencil, + onPress: handleEditTag, + }, + { + title: 'Delete Tag', + icon: Trash2, + onPress: handleDeleteTag, + }, + ] + + const triggerClassName = typeof triggerStyle === 'string' ? triggerStyle : 'p-2 rounded-full bg-gray-50' + const triggerStyleObj: CSSProperties | undefined = typeof triggerStyle === 'object' ? triggerStyle : undefined + + return ( + <> + {/* Menu Trigger */} + + + {/* Menu Dialog */} + +
+

+ Tag Options +

+ + {options.map((option, index) => { + const Icon = option.icon + return ( + + ) + })} +
+
+ + ) +} diff --git a/apps/admin-web/src/components/UserIncidentsView.tsx b/apps/admin-web/src/components/UserIncidentsView.tsx new file mode 100644 index 0000000..1c60982 --- /dev/null +++ b/apps/admin-web/src/components/UserIncidentsView.tsx @@ -0,0 +1,207 @@ +import React, { useState } from 'react' +import { p as P, BottomDialog, pInput as PInput } from 'web-components' +import { trpc } from '@/lib/trpc-client' +import { TriangleAlert, Info, Plus, Calendar, User, ShoppingCart, CircleCheck } from 'lucide-react' +import dayjs from 'dayjs' + +function UserIncidentDialog({ + userId, + orderId, + open, + onClose, + onSuccess +}: { + userId: number + orderId: number | null + open: boolean + onClose: () => void + onSuccess?: () => void +}) { + const [adminComment, setAdminComment] = useState('') + const [negativityScore, setNegativityScore] = useState('') + + const addIncidentMutation = trpc.admin.user.addUserIncident.useMutation({ + onSuccess: () => { + window.alert('Success: Incident added successfully') + setAdminComment('') + setNegativityScore('') + onClose() + onSuccess?.() + }, + onError: (error: any) => { + window.alert(`Error: ${error.message || 'Failed to add incident'}`) + }, + }) + + const handleAddIncident = () => { + const score = negativityScore ? parseInt(negativityScore) : undefined + + if (!adminComment.trim() && !negativityScore) { + window.alert('Error: Please enter a comment or negativity score') + return + } + + addIncidentMutation.mutate({ + userId, + orderId: orderId || undefined, + adminComment: adminComment || undefined, + negativityScore: score, + }) + } + + return ( + +
+
+
+ +
+

+ Add User Incident +

+

+ Record an incident for this user. This will be visible in their profile. +

+
+ + setAdminComment(e.target.value)} + placeholder="Enter details about the incident..." + multiline + className="h-24" + /> + + setNegativityScore(e.target.value)} + placeholder="0" + type="number" + inputMode="numeric" + className="mt-4" + /> + +
+ +

+ Higher negativity scores indicate more serious incidents (e.g., repeated cancellations, abusive behavior). +

+
+ +
+ + +
+
+
+ ) +} + +export function UserIncidentsView({ userId, orderId }: { userId: number; orderId: number | null }) { + const [incidentDialogOpen, setIncidentDialogOpen] = useState(false) + + const { data: incidentsData, refetch: refetchIncidents } = trpc.admin.user.getUserIncidents.useQuery( + { userId }, + { enabled: !!userId } + ) + + return ( + <> +
+
+

+ User Incidents +

+ +
+ + {incidentsData?.incidents && incidentsData.incidents.length > 0 ? ( +
+ {incidentsData.incidents.map((incident: any, index: number) => ( +
+
+
+ +

+ {dayjs(incident.dateAdded).format('MMM DD, YYYY • h:mm A')} +

+
+ {incident.negativityScore && ( +
+

+ Score: {incident.negativityScore} +

+
+ )} +
+ + {incident.adminComment && ( +
+

+ {incident.adminComment} +

+
+ )} + +
+ +

+ Added by {incident.addedBy} +

+ {incident.orderId && ( + <> + +

+ Order #{incident.orderId} +

+ + )} +
+
+ ))} +
+ ) : ( +
+ +

+ No incidents recorded for this user +

+
+ )} +
+ + setIncidentDialogOpen(false)} + onSuccess={refetchIncidents} + /> + + ) +} diff --git a/apps/admin-web/src/components/VendorSnippetForm.tsx b/apps/admin-web/src/components/VendorSnippetForm.tsx new file mode 100644 index 0000000..fc0d73a --- /dev/null +++ b/apps/admin-web/src/components/VendorSnippetForm.tsx @@ -0,0 +1,225 @@ +import { useEffect, type FC } from 'react' +import { useFormik } from 'formik' +import { p as P, Dropdown, pInput as PInput, Checkbox } from 'web-components' +import ProductsSelector from './ProductsSelector' +import DateInput from './DateInput' +import { trpc } from '@/lib/trpc-client' +import type { VendorSnippetForm as VendorSnippetFormType } from '@/types/vendor-snippets' + +interface VendorSnippetFormProps { + snippet?: VendorSnippetFormType | null + onClose: () => void + onSuccess: () => void + showIsPermanentCheckbox?: boolean +} + +const VendorSnippetForm: FC = ({ + snippet, + onClose, + onSuccess, + showIsPermanentCheckbox = false, +}) => { + + // Fetch slots + const { data: slotsData } = trpc.user.slots.getSlots.useQuery() + + const createSnippet = trpc.admin.vendorSnippets.create.useMutation() + const updateSnippet = trpc.admin.vendorSnippets.update.useMutation() + + const isEditing = !!snippet + + const formik = useFormik({ + initialValues: { + snippetCode: snippet?.snippetCode || '', + slotId: snippet?.slotId?.toString() || '', + isPermanent: snippet?.isPermanent || false, + skuIds: snippet?.skuIds?.map(id => id.toString()) || [], + validTill: snippet?.validTill ? new Date(snippet.validTill) : null, + }, + validate: (values) => { + const errors: {[key: string]: string} = {} + + if (!values.snippetCode.trim()) { + errors.snippetCode = 'Snippet code is required' + } + + // Validate snippet code only contains alphanumeric characters and underscore + const snippetCodeRegex = /^[a-zA-Z0-9_]+$/ + if (values.snippetCode && !snippetCodeRegex.test(values.snippetCode)) { + errors.snippetCode = 'Snippet code can only contain letters, numbers, and underscores' + } + + // Only require slotId if isPermanent is false + if (!values.isPermanent && !values.slotId) { + errors.slotId = 'Slot selection is required' + } + + if (values.skuIds.length === 0) { + errors.skuIds = 'At least one product must be selected' + } + + return errors + }, + onSubmit: async (values) => { + try { + + const submitData = { + snippetCode: values.snippetCode, + slotId: values.isPermanent ? undefined : parseInt(values.slotId || '0'), + isPermanent: values.isPermanent, + skuIds: values.skuIds.map(id => parseInt(id)), + validTill: values.validTill ? values.validTill.toISOString() : undefined, + } + + if (isEditing && snippet) { + await updateSnippet.mutateAsync({ + id: snippet.id, + updates: submitData, + }) + window.alert('Success: Vendor snippet updated successfully') + } else { + await createSnippet.mutateAsync(submitData) + window.alert('Success: Vendor snippet created successfully') + } + + onSuccess() + onClose() + } catch (error: any) { + window.alert(`Error: ${error.message || 'Failed to save vendor snippet'}`) + } + }, + }) + + // Generate unique snippet code if creating new (only on mount) + useEffect(() => { + if (!isEditing && !formik.values.snippetCode) { + const timestamp = Date.now() + const random = Math.random().toString(36).substring(2, 8) + formik.setFieldValue('snippetCode', `VS_${timestamp}_${random}`) + } + }, [isEditing]) // Removed formik.values.snippetCode from deps + + const slotOptions = slotsData?.slots.map(slot => ({ + label: new Date(slot.deliveryTime).toLocaleString(), + value: slot.id.toString(), + })) || [] + + return ( +
+
+
+

+ {isEditing ? 'Edit Vendor Snippet' : 'Create Vendor Snippet'} +

+ +
+
+ +
+
+ {/* Snippet Code */} +
+ + {formik.errors.snippetCode && formik.touched.snippetCode && ( +

{formik.errors.snippetCode}

+ )} +
+ + {/* Is Permanent Checkbox */} +
+ +

+ Check if this snippet is permanent and not tied to a specific delivery slot +

+
+ + {/* Slot Selection - Only show if not permanent */} + {!formik.values.isPermanent && ( +
+

Delivery Slot

+ formik.setFieldValue('slotId', String(value))} + className="w-full" + /> + {formik.errors.slotId && formik.touched.slotId && ( +

{formik.errors.slotId}

+ )} +
+ )} + + {/* Product Selection */} +
+ parseInt(id))} + onChange={(selectedProductIds) => formik.setFieldValue('skuIds', (selectedProductIds as number[]).map(id => id.toString()))} + multiple={true} + label="Select Products" + placeholder="Select products" + labelFormat={(product) => product.label} + /> + {formik.errors.skuIds && formik.touched.skuIds && ( +

{formik.errors.skuIds}

+ )} +
+ + {/* Valid Till Date */} +
+

Valid Till (Optional)

+ formik.setFieldValue('validTill', date)} + placeholder="Select expiry date" + showLabel={false} + /> +

+ Leave empty for no expiry +

+
+
+
+ + {/* Submit Button */} +
+ +
+
+ ) +} + +export default VendorSnippetForm diff --git a/apps/admin-web/src/components/context/staff-auth-context.tsx b/apps/admin-web/src/components/context/staff-auth-context.tsx new file mode 100644 index 0000000..75b8413 --- /dev/null +++ b/apps/admin-web/src/components/context/staff-auth-context.tsx @@ -0,0 +1,112 @@ +import React, { createContext, useContext, useEffect, useState, type ReactNode } from 'react' +import { useNavigate, useLocation } from '@tanstack/react-router' +import queryClient from '../../lib/query-client' +import { EventBus, FORCE_LOGOUT_EVENT } from '../../lib/event-bus' +import { trpc } from '../../lib/trpc-client' +import { saveJWT, getJWT, deleteJWT } from '../../hooks/useJWT' +import type { IdName } from '@packages/shared' + +type Staff = IdName + +interface StaffAuthContextType { + isLoggedIn: boolean + isLoading: boolean + staff: Staff | null + login: (name: string, password: string) => Promise + logout: () => void + isLoggingIn: boolean + loginError: string | null +} + +const StaffAuthContext = createContext(undefined) + +export const StaffAuthProvider = ({ children }: { children: ReactNode }) => { + const [isLoggedIn, setIsLoggedIn] = useState(false) + const [isLoading, setIsLoading] = useState(true) + const [staff, setStaff] = useState(null) + const [loginError, setLoginError] = useState(null) + + const loginMutation = trpc.admin.staffUser.login.useMutation() + const navigate = useNavigate() + const location = useLocation() + + useEffect(() => { + const checkAuth = async () => { + const token = await getJWT() + if (token) { + setIsLoggedIn(true) + } else { + setIsLoggedIn(false) + if (!location.pathname.includes('login')) { + navigate({ to: '/login' }) + } + } + setIsLoading(false) + } + + checkAuth() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + const login = async (name: string, password: string) => { + setLoginError(null) + loginMutation.mutate( + { name, password }, + { + onSuccess: async (data) => { + await saveJWT(data.token) + setStaff(data.staff) + setIsLoggedIn(true) + navigate({ to: '/dashboard' }) + }, + onError: (error: any) => { + setLoginError(error.message || 'Login failed') + }, + }, + ) + } + + const logout = async () => { + await deleteJWT() + setIsLoggedIn(false) + setStaff(null) + queryClient.clear() + navigate({ to: '/login' }) + } + + useEffect(() => { + const subscription = EventBus.addListener(FORCE_LOGOUT_EVENT, () => { + console.log('force logout event received') + logout() + }) + + return () => { + subscription.remove() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + return ( + + {children} + + ) +} + +export const useStaffAuth = () => { + const context = useContext(StaffAuthContext) + if (!context) { + throw new Error('useStaffAuth must be used within a StaffAuthProvider') + } + return context +} diff --git a/apps/admin-web/src/hooks/useJWT.ts b/apps/admin-web/src/hooks/useJWT.ts new file mode 100644 index 0000000..9b5ab24 --- /dev/null +++ b/apps/admin-web/src/hooks/useJWT.ts @@ -0,0 +1,15 @@ +import { StorageService } from 'web-components' + +export const JWT_KEY = 'jwt_token' + +export async function saveJWT(token: string) { + await StorageService.setItem(JWT_KEY, token) +} + +export async function getJWT() { + return await StorageService.getItem(JWT_KEY) +} + +export async function deleteJWT() { + await StorageService.removeItem(JWT_KEY) +} diff --git a/apps/admin-web/src/hooks/useUploadToObjectStorage.ts b/apps/admin-web/src/hooks/useUploadToObjectStorage.ts new file mode 100644 index 0000000..a420b7c --- /dev/null +++ b/apps/admin-web/src/hooks/useUploadToObjectStorage.ts @@ -0,0 +1,105 @@ +import { useState } from 'react' +import { trpc } from '../lib/trpc-client' +import type { ContextString, UploadInput, UploadBatchInput, UploadResult } from '@packages/shared' + +// Verbatim port of admin-ui useUploadToObjectStore (trpc import path only). +export function useUploadToObjectStorage() { + const [isUploading, setIsUploading] = useState(false) + const [error, setError] = useState(null) + const [progress, setProgress] = useState<{ completed: number; total: number } | null>(null) + + const generateUploadUrls = trpc.common.generateUploadUrls.useMutation() + + const upload = async (input: UploadBatchInput): Promise => { + setIsUploading(true) + setError(null) + setProgress({ completed: 0, total: input.images.length }) + + try { + const { images, contextString } = input + + if (images.length === 0) { + return { keys: [], presignedUrls: [] } + } + + const mimeTypes = images.map((img) => img.mimeType) + const { uploadUrls } = await generateUploadUrls.mutateAsync({ + contextString, + mimeTypes, + }) + + if (uploadUrls.length !== images.length) { + throw new Error(`Expected ${images.length} URLs, got ${uploadUrls.length}`) + } + + const uploadPromises = images.map(async (image, index) => { + const presignedUrl = uploadUrls[index] + const { blob, mimeType } = image + + const response = await fetch(presignedUrl, { + method: 'PUT', + body: blob, + headers: { 'Content-Type': mimeType }, + }) + + if (!response.ok) { + throw new Error(`Upload ${index + 1} failed with status ${response.status}`) + } + + setProgress((prev) => (prev ? { ...prev, completed: prev.completed + 1 } : null)) + + return { + key: extractKeyFromPresignedUrl(presignedUrl), + presignedUrl, + } + }) + + const results = await Promise.all(uploadPromises) + + return { + keys: results.map((r) => r.key), + presignedUrls: results.map((r) => r.presignedUrl), + } + } catch (err) { + const uploadError = err instanceof Error ? err : new Error('Upload failed') + setError(uploadError) + throw uploadError + } finally { + setIsUploading(false) + setProgress(null) + } + } + + const uploadSingle = async ( + blob: Blob, + mimeType: string, + contextString: ContextString, + ): Promise<{ key: string; presignedUrl: string }> => { + const result = await upload({ + images: [{ blob, mimeType }], + contextString, + }) + return { + key: result.keys[0], + presignedUrl: result.presignedUrls[0], + } + } + + return { + upload, + uploadSingle, + isUploading, + error, + progress, + isPending: generateUploadUrls.isPending, + } +} + +function extractKeyFromPresignedUrl(url: string): string { + const u = new URL(url) + let rawKey = u.pathname.replace(/^\/+/, '') + rawKey = rawKey.split('/').slice(1).join('/') + return decodeURIComponent(rawKey) +} + +export type { UploadInput } diff --git a/apps/admin-web/src/lib/event-bus.ts b/apps/admin-web/src/lib/event-bus.ts new file mode 100644 index 0000000..775eae8 --- /dev/null +++ b/apps/admin-web/src/lib/event-bus.ts @@ -0,0 +1,33 @@ +// Web replacement for react-native's DeviceEventEmitter + shared event names. +// API-compatible subset: emit(event), addListener(event, cb) -> { remove() }. +export const REFRESH_EVENT = 'refresh_event' +export const FORCE_LOGOUT_EVENT = 'forceLogout' + +type Listener = (...args: any[]) => void + +const listeners = new Map>() + +export const EventBus = { + emit(event: string, ...args: any[]) { + listeners.get(event)?.forEach((cb) => { + try { + cb(...args) + } catch (e) { + console.error(`EventBus listener error for ${event}`, e) + } + }) + }, + addListener(event: string, cb: Listener) { + let set = listeners.get(event) + if (!set) { + set = new Set() + listeners.set(event, set) + } + set.add(cb) + return { + remove() { + listeners.get(event)?.delete(cb) + }, + } + }, +} diff --git a/apps/admin-web/src/lib/navigation-target.ts b/apps/admin-web/src/lib/navigation-target.ts new file mode 100644 index 0000000..508423b --- /dev/null +++ b/apps/admin-web/src/lib/navigation-target.ts @@ -0,0 +1,26 @@ +import { create } from 'zustand' + +// Verbatim port of common-ui useNavigationTarget (only dep: zustand). +interface NavigationTargetState { + navigationTarget: string | null + setNavigationTarget: (target: string | null) => void + getNavigationTarget: () => string | null +} + +const useNavigationTargetStore = create((set, get) => ({ + navigationTarget: null, + setNavigationTarget: (target: string | null) => { + set({ navigationTarget: target }) + }, + getNavigationTarget: () => { + const target = get().navigationTarget + if (target) { + set({ navigationTarget: null }) + } + return target + }, +})) + +export function useNavigationTarget() { + return useNavigationTargetStore() +} diff --git a/apps/admin-web/src/lib/query-client.ts b/apps/admin-web/src/lib/query-client.ts new file mode 100644 index 0000000..bade5e9 --- /dev/null +++ b/apps/admin-web/src/lib/query-client.ts @@ -0,0 +1,19 @@ +import { QueryClient } from '@tanstack/react-query' + +// Module-level singleton — same options as admin-ui (retry: 3). +let queryClient: QueryClient | undefined + +export function getQueryClient() { + if (!queryClient) { + queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: 3, + }, + }, + }) + } + return queryClient +} + +export default getQueryClient() diff --git a/apps/admin-web/src/lib/refresh-context.tsx b/apps/admin-web/src/lib/refresh-context.tsx new file mode 100644 index 0000000..45b94d6 --- /dev/null +++ b/apps/admin-web/src/lib/refresh-context.tsx @@ -0,0 +1,62 @@ +import React, { createContext, useContext, useEffect, useRef } from 'react' +import { useLocation } from '@tanstack/react-router' +import { EventBus, REFRESH_EVENT } from './event-bus' +import { getQueryClient } from './query-client' + +// Web port of packages/ui refresh-context + useManualRefresh + +// useMarkDataFetchers + useFocusCallback. Navigation focus (expo) is +// approximated with route-pathname changes; manual refresh uses the bus. + +const RefreshContext = createContext<{ refreshAll: () => void } | null>(null) + +export const RefreshProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const refreshAll = () => { + getQueryClient().invalidateQueries() + EventBus.emit(REFRESH_EVENT) + } + return {children} +} + +export const useRefresh = () => { + const context = useContext(RefreshContext) + if (!context) throw new Error('useRefresh must be used within RefreshProvider') + return context +} + +export function useManualRefresh(callback: () => void) { + const ref = useRef(callback) + ref.current = callback + useEffect(() => { + const sub = EventBus.addListener(REFRESH_EVENT, () => ref.current()) + return () => sub.remove() + }, []) +} + +// Refetch on 2nd+ visit to the current route (mirrors useMarkDataFetchers: +// skip first focus, refetch on subsequent focuses). +export function useMarkDataFetchers(callback: () => void) { + const location = useLocation() + const ref = useRef(callback) + ref.current = callback + const visitsRef = useRef>({}) + useEffect(() => { + const key = location.pathname + location.searchStr + const count = visitsRef.current[key] ?? 0 + visitsRef.current[key] = count + 1 + if (count >= 1) { + ref.current() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [location.pathname, location.searchStr]) +} + +// Run callback when the window regains focus (web analogue of screen focus). +export default function useFocusCallback(callback: () => void) { + const ref = useRef(callback) + ref.current = callback + useEffect(() => { + const onFocus = () => ref.current() + window.addEventListener('focus', onFocus) + return () => window.removeEventListener('focus', onFocus) + }, []) +} diff --git a/apps/admin-web/src/lib/theme.ts b/apps/admin-web/src/lib/theme.ts new file mode 100644 index 0000000..372fe1f --- /dev/null +++ b/apps/admin-web/src/lib/theme.ts @@ -0,0 +1,60 @@ +// Exact copy of theme.colors from packages/ui (theme-colors.ts), which the +// web bundle cannot import (RN code). Keeps admin-web visuals identical. +export const colors = { + brand25: '#F5FAFF', + brand50: '#EFF8FF', + brand100: '#D1E9FF', + brand200: '#B2DDFF', + brand300: '#84CAFF', + brand400: '#53B1FD', + brand500: '#2E90FA', + brand600: '#1570EF', + brand700: '#175CD3', + brand800: '#1849A9', + brand900: '#194185', + blue1: '#2E90FA', + blue2: '#fff0f6', + pink1: '#2E90FA', + pink2: '#fff0f6', + blue3: '#ECF4FF', + red1: '#D84343', + green1: '#4CAF50', + green2: '#C8F4D3', + black1: '#000000', + black2: '#1A1C1E', + white1: '#FFFFFF', + gray1: '#fdfdfd', + gray2: '#f2f2f2', + gray3: '#F5F5F5', + gray4: '#6C7278', + gray5: '#ced4da', + yellow1: '#FFB74D', + yellow2: '#FFE3AD', + purple25: '#FAFAFF', + purple50: '#F4F3FF', + purple100: '#EBE9FE', + purple200: '#D9D6FE', + purple300: '#BDB4FE', + purple400: '#9B8AFB', + purple500: '#7A5AF8', + purple600: '#6938EF', + purple700: '#5925DC', + purple800: '#4A1FB8', + purple900: '#3E1C96', + gray25: '#FDFDFD', + gray50: '#FAFAFA', + gray100: '#F5F5F5', + gray200: '#E9EAEB', + gray300: '#D5D7DA', + gray400: '#A4A7AE', + gray500: '#717680', + gray600: '#535862', + gray700: '#414651', + gray800: '#252B37', + gray900: '#101828', + secondaryPink: '#fff', +} + +export const theme = { colors } + +export type ThemeColor = keyof typeof colors diff --git a/apps/admin-web/src/lib/trpc-client.ts b/apps/admin-web/src/lib/trpc-client.ts new file mode 100644 index 0000000..5ad6025 --- /dev/null +++ b/apps/admin-web/src/lib/trpc-client.ts @@ -0,0 +1,39 @@ +import { createTRPCReact } from '@trpc/react-query' +import { createTRPCClient, httpBatchLink } from '@trpc/client' +import type { AppRouter } from '@backend/trpc/router' +import { getJWT } from '../hooks/useJWT' +import { EventBus, FORCE_LOGOUT_EVENT } from './event-bus' + +// Same backend as admin-ui (BASE_API_URL from common-ui); overridable via env. +export const BASE_API_URL = + (import.meta.env?.VITE_API_URL as string | undefined) || 'https://devapi.freshyo.in' + +export const trpc = createTRPCReact() + +export function getTrpcClient() { + return createTRPCClient({ + links: [ + httpBatchLink({ + url: `${BASE_API_URL}/api/trpc`, + headers: async () => { + const token = await getJWT() + return token ? { Authorization: `Bearer ${token}` } : {} + }, + fetch: async (url, options) => { + const response = await fetch(url, options) + if (response.status === 401) { + const data = await response.clone().json().catch(() => ({})) + let code = '' + if (data[0]?.error || data?.error) { + code = data[0]?.error?.message || data?.error?.message + } + if (code === 'UNAUTHORIZED') { + EventBus.emit(FORCE_LOGOUT_EVENT) + } + } + return response + }, + }), + ], + }) +} diff --git a/apps/admin-web/src/routeTree.gen.ts b/apps/admin-web/src/routeTree.gen.ts new file mode 100644 index 0000000..57b59d0 --- /dev/null +++ b/apps/admin-web/src/routeTree.gen.ts @@ -0,0 +1,1047 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as LoginRouteImport } from './routes/login' +import { Route as DashboardRouteImport } from './routes/dashboard' +import { Route as IndexRouteImport } from './routes/index' +import { Route as DashboardIndexRouteImport } from './routes/dashboard.index' +import { Route as DashboardVendorSnippetsRouteImport } from './routes/dashboard.vendor-snippets' +import { Route as DashboardUsersRouteImport } from './routes/dashboard.users' +import { Route as DashboardStoresRouteImport } from './routes/dashboard.stores' +import { Route as DashboardSlotsRouteImport } from './routes/dashboard.slots' +import { Route as DashboardRebalanceRouteImport } from './routes/dashboard.rebalance' +import { Route as DashboardProductsRouteImport } from './routes/dashboard.products' +import { Route as DashboardProductTagsRouteImport } from './routes/dashboard.product-tags' +import { Route as DashboardProductGroupingsRouteImport } from './routes/dashboard.product-groupings' +import { Route as DashboardPricesRouteImport } from './routes/dashboard.prices' +import { Route as DashboardOrdersRouteImport } from './routes/dashboard.orders' +import { Route as DashboardNotificationsRouteImport } from './routes/dashboard.notifications' +import { Route as DashboardCustomizeAppRouteImport } from './routes/dashboard.customize-app' +import { Route as DashboardCouponsRouteImport } from './routes/dashboard.coupons' +import { Route as DashboardComplaintsRouteImport } from './routes/dashboard.complaints' +import { Route as DashboardBannersRouteImport } from './routes/dashboard.banners' +import { Route as DashboardUsersIdRouteImport } from './routes/dashboard.users.$id' +import { Route as DashboardStoresNewRouteImport } from './routes/dashboard.stores.new' +import { Route as DashboardStoresEditRouteImport } from './routes/dashboard.stores.edit' +import { Route as DashboardSlotsNewRouteImport } from './routes/dashboard.slots.new' +import { Route as DashboardSlotsDetailRouteImport } from './routes/dashboard.slots.detail' +import { Route as DashboardProductsNewRouteImport } from './routes/dashboard.products.new' +import { Route as DashboardProductsEditRouteImport } from './routes/dashboard.products.edit' +import { Route as DashboardProductsIdRouteImport } from './routes/dashboard.products.$id' +import { Route as DashboardProductTagsOrderRouteImport } from './routes/dashboard.product-tags.order' +import { Route as DashboardProductTagsNewRouteImport } from './routes/dashboard.product-tags.new' +import { Route as DashboardProductTagsEditRouteImport } from './routes/dashboard.product-tags.edit' +import { Route as DashboardProductGroupingsNewRouteImport } from './routes/dashboard.product-groupings.new' +import { Route as DashboardOrdersSequenceRouteImport } from './routes/dashboard.orders.sequence' +import { Route as DashboardOrdersListRouteImport } from './routes/dashboard.orders.list' +import { Route as DashboardOrdersIdRouteImport } from './routes/dashboard.orders.$id' +import { Route as DashboardCustomizeAppPopularRouteImport } from './routes/dashboard.customize-app.popular' +import { Route as DashboardCustomizeAppOrderingRouteImport } from './routes/dashboard.customize-app.ordering' +import { Route as DashboardCouponsNewRouteImport } from './routes/dashboard.coupons.new' +import { Route as DashboardBannersNewRouteImport } from './routes/dashboard.banners.new' +import { Route as DashboardSlotsIdEditRouteImport } from './routes/dashboard.slots.$id.edit' +import { Route as DashboardProductGroupingsIdEditRouteImport } from './routes/dashboard.product-groupings.$id.edit' +import { Route as DashboardCouponsIdEditRouteImport } from './routes/dashboard.coupons.$id.edit' +import { Route as DashboardBannersIdEditRouteImport } from './routes/dashboard.banners.$id.edit' + +const LoginRoute = LoginRouteImport.update({ + id: '/login', + path: '/login', + getParentRoute: () => rootRouteImport, +} as any) +const DashboardRoute = DashboardRouteImport.update({ + id: '/dashboard', + path: '/dashboard', + getParentRoute: () => rootRouteImport, +} as any) +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) +const DashboardIndexRoute = DashboardIndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardVendorSnippetsRoute = DashboardVendorSnippetsRouteImport.update({ + id: '/vendor-snippets', + path: '/vendor-snippets', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardUsersRoute = DashboardUsersRouteImport.update({ + id: '/users', + path: '/users', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardStoresRoute = DashboardStoresRouteImport.update({ + id: '/stores', + path: '/stores', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardSlotsRoute = DashboardSlotsRouteImport.update({ + id: '/slots', + path: '/slots', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardRebalanceRoute = DashboardRebalanceRouteImport.update({ + id: '/rebalance', + path: '/rebalance', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardProductsRoute = DashboardProductsRouteImport.update({ + id: '/products', + path: '/products', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardProductTagsRoute = DashboardProductTagsRouteImport.update({ + id: '/product-tags', + path: '/product-tags', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardProductGroupingsRoute = + DashboardProductGroupingsRouteImport.update({ + id: '/product-groupings', + path: '/product-groupings', + getParentRoute: () => DashboardRoute, + } as any) +const DashboardPricesRoute = DashboardPricesRouteImport.update({ + id: '/prices', + path: '/prices', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardOrdersRoute = DashboardOrdersRouteImport.update({ + id: '/orders', + path: '/orders', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardNotificationsRoute = DashboardNotificationsRouteImport.update({ + id: '/notifications', + path: '/notifications', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardCustomizeAppRoute = DashboardCustomizeAppRouteImport.update({ + id: '/customize-app', + path: '/customize-app', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardCouponsRoute = DashboardCouponsRouteImport.update({ + id: '/coupons', + path: '/coupons', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardComplaintsRoute = DashboardComplaintsRouteImport.update({ + id: '/complaints', + path: '/complaints', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardBannersRoute = DashboardBannersRouteImport.update({ + id: '/banners', + path: '/banners', + getParentRoute: () => DashboardRoute, +} as any) +const DashboardUsersIdRoute = DashboardUsersIdRouteImport.update({ + id: '/$id', + path: '/$id', + getParentRoute: () => DashboardUsersRoute, +} as any) +const DashboardStoresNewRoute = DashboardStoresNewRouteImport.update({ + id: '/new', + path: '/new', + getParentRoute: () => DashboardStoresRoute, +} as any) +const DashboardStoresEditRoute = DashboardStoresEditRouteImport.update({ + id: '/edit', + path: '/edit', + getParentRoute: () => DashboardStoresRoute, +} as any) +const DashboardSlotsNewRoute = DashboardSlotsNewRouteImport.update({ + id: '/new', + path: '/new', + getParentRoute: () => DashboardSlotsRoute, +} as any) +const DashboardSlotsDetailRoute = DashboardSlotsDetailRouteImport.update({ + id: '/detail', + path: '/detail', + getParentRoute: () => DashboardSlotsRoute, +} as any) +const DashboardProductsNewRoute = DashboardProductsNewRouteImport.update({ + id: '/new', + path: '/new', + getParentRoute: () => DashboardProductsRoute, +} as any) +const DashboardProductsEditRoute = DashboardProductsEditRouteImport.update({ + id: '/edit', + path: '/edit', + getParentRoute: () => DashboardProductsRoute, +} as any) +const DashboardProductsIdRoute = DashboardProductsIdRouteImport.update({ + id: '/$id', + path: '/$id', + getParentRoute: () => DashboardProductsRoute, +} as any) +const DashboardProductTagsOrderRoute = + DashboardProductTagsOrderRouteImport.update({ + id: '/order', + path: '/order', + getParentRoute: () => DashboardProductTagsRoute, + } as any) +const DashboardProductTagsNewRoute = DashboardProductTagsNewRouteImport.update({ + id: '/new', + path: '/new', + getParentRoute: () => DashboardProductTagsRoute, +} as any) +const DashboardProductTagsEditRoute = + DashboardProductTagsEditRouteImport.update({ + id: '/edit', + path: '/edit', + getParentRoute: () => DashboardProductTagsRoute, + } as any) +const DashboardProductGroupingsNewRoute = + DashboardProductGroupingsNewRouteImport.update({ + id: '/new', + path: '/new', + getParentRoute: () => DashboardProductGroupingsRoute, + } as any) +const DashboardOrdersSequenceRoute = DashboardOrdersSequenceRouteImport.update({ + id: '/sequence', + path: '/sequence', + getParentRoute: () => DashboardOrdersRoute, +} as any) +const DashboardOrdersListRoute = DashboardOrdersListRouteImport.update({ + id: '/list', + path: '/list', + getParentRoute: () => DashboardOrdersRoute, +} as any) +const DashboardOrdersIdRoute = DashboardOrdersIdRouteImport.update({ + id: '/$id', + path: '/$id', + getParentRoute: () => DashboardOrdersRoute, +} as any) +const DashboardCustomizeAppPopularRoute = + DashboardCustomizeAppPopularRouteImport.update({ + id: '/popular', + path: '/popular', + getParentRoute: () => DashboardCustomizeAppRoute, + } as any) +const DashboardCustomizeAppOrderingRoute = + DashboardCustomizeAppOrderingRouteImport.update({ + id: '/ordering', + path: '/ordering', + getParentRoute: () => DashboardCustomizeAppRoute, + } as any) +const DashboardCouponsNewRoute = DashboardCouponsNewRouteImport.update({ + id: '/new', + path: '/new', + getParentRoute: () => DashboardCouponsRoute, +} as any) +const DashboardBannersNewRoute = DashboardBannersNewRouteImport.update({ + id: '/new', + path: '/new', + getParentRoute: () => DashboardBannersRoute, +} as any) +const DashboardSlotsIdEditRoute = DashboardSlotsIdEditRouteImport.update({ + id: '/$id/edit', + path: '/$id/edit', + getParentRoute: () => DashboardSlotsRoute, +} as any) +const DashboardProductGroupingsIdEditRoute = + DashboardProductGroupingsIdEditRouteImport.update({ + id: '/$id/edit', + path: '/$id/edit', + getParentRoute: () => DashboardProductGroupingsRoute, + } as any) +const DashboardCouponsIdEditRoute = DashboardCouponsIdEditRouteImport.update({ + id: '/$id/edit', + path: '/$id/edit', + getParentRoute: () => DashboardCouponsRoute, +} as any) +const DashboardBannersIdEditRoute = DashboardBannersIdEditRouteImport.update({ + id: '/$id/edit', + path: '/$id/edit', + getParentRoute: () => DashboardBannersRoute, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute + '/dashboard': typeof DashboardRouteWithChildren + '/login': typeof LoginRoute + '/dashboard/banners': typeof DashboardBannersRouteWithChildren + '/dashboard/complaints': typeof DashboardComplaintsRoute + '/dashboard/coupons': typeof DashboardCouponsRouteWithChildren + '/dashboard/customize-app': typeof DashboardCustomizeAppRouteWithChildren + '/dashboard/notifications': typeof DashboardNotificationsRoute + '/dashboard/orders': typeof DashboardOrdersRouteWithChildren + '/dashboard/prices': typeof DashboardPricesRoute + '/dashboard/product-groupings': typeof DashboardProductGroupingsRouteWithChildren + '/dashboard/product-tags': typeof DashboardProductTagsRouteWithChildren + '/dashboard/products': typeof DashboardProductsRouteWithChildren + '/dashboard/rebalance': typeof DashboardRebalanceRoute + '/dashboard/slots': typeof DashboardSlotsRouteWithChildren + '/dashboard/stores': typeof DashboardStoresRouteWithChildren + '/dashboard/users': typeof DashboardUsersRouteWithChildren + '/dashboard/vendor-snippets': typeof DashboardVendorSnippetsRoute + '/dashboard/': typeof DashboardIndexRoute + '/dashboard/banners/new': typeof DashboardBannersNewRoute + '/dashboard/coupons/new': typeof DashboardCouponsNewRoute + '/dashboard/customize-app/ordering': typeof DashboardCustomizeAppOrderingRoute + '/dashboard/customize-app/popular': typeof DashboardCustomizeAppPopularRoute + '/dashboard/orders/$id': typeof DashboardOrdersIdRoute + '/dashboard/orders/list': typeof DashboardOrdersListRoute + '/dashboard/orders/sequence': typeof DashboardOrdersSequenceRoute + '/dashboard/product-groupings/new': typeof DashboardProductGroupingsNewRoute + '/dashboard/product-tags/edit': typeof DashboardProductTagsEditRoute + '/dashboard/product-tags/new': typeof DashboardProductTagsNewRoute + '/dashboard/product-tags/order': typeof DashboardProductTagsOrderRoute + '/dashboard/products/$id': typeof DashboardProductsIdRoute + '/dashboard/products/edit': typeof DashboardProductsEditRoute + '/dashboard/products/new': typeof DashboardProductsNewRoute + '/dashboard/slots/detail': typeof DashboardSlotsDetailRoute + '/dashboard/slots/new': typeof DashboardSlotsNewRoute + '/dashboard/stores/edit': typeof DashboardStoresEditRoute + '/dashboard/stores/new': typeof DashboardStoresNewRoute + '/dashboard/users/$id': typeof DashboardUsersIdRoute + '/dashboard/banners/$id/edit': typeof DashboardBannersIdEditRoute + '/dashboard/coupons/$id/edit': typeof DashboardCouponsIdEditRoute + '/dashboard/product-groupings/$id/edit': typeof DashboardProductGroupingsIdEditRoute + '/dashboard/slots/$id/edit': typeof DashboardSlotsIdEditRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute + '/login': typeof LoginRoute + '/dashboard/banners': typeof DashboardBannersRouteWithChildren + '/dashboard/complaints': typeof DashboardComplaintsRoute + '/dashboard/coupons': typeof DashboardCouponsRouteWithChildren + '/dashboard/customize-app': typeof DashboardCustomizeAppRouteWithChildren + '/dashboard/notifications': typeof DashboardNotificationsRoute + '/dashboard/orders': typeof DashboardOrdersRouteWithChildren + '/dashboard/prices': typeof DashboardPricesRoute + '/dashboard/product-groupings': typeof DashboardProductGroupingsRouteWithChildren + '/dashboard/product-tags': typeof DashboardProductTagsRouteWithChildren + '/dashboard/products': typeof DashboardProductsRouteWithChildren + '/dashboard/rebalance': typeof DashboardRebalanceRoute + '/dashboard/slots': typeof DashboardSlotsRouteWithChildren + '/dashboard/stores': typeof DashboardStoresRouteWithChildren + '/dashboard/users': typeof DashboardUsersRouteWithChildren + '/dashboard/vendor-snippets': typeof DashboardVendorSnippetsRoute + '/dashboard': typeof DashboardIndexRoute + '/dashboard/banners/new': typeof DashboardBannersNewRoute + '/dashboard/coupons/new': typeof DashboardCouponsNewRoute + '/dashboard/customize-app/ordering': typeof DashboardCustomizeAppOrderingRoute + '/dashboard/customize-app/popular': typeof DashboardCustomizeAppPopularRoute + '/dashboard/orders/$id': typeof DashboardOrdersIdRoute + '/dashboard/orders/list': typeof DashboardOrdersListRoute + '/dashboard/orders/sequence': typeof DashboardOrdersSequenceRoute + '/dashboard/product-groupings/new': typeof DashboardProductGroupingsNewRoute + '/dashboard/product-tags/edit': typeof DashboardProductTagsEditRoute + '/dashboard/product-tags/new': typeof DashboardProductTagsNewRoute + '/dashboard/product-tags/order': typeof DashboardProductTagsOrderRoute + '/dashboard/products/$id': typeof DashboardProductsIdRoute + '/dashboard/products/edit': typeof DashboardProductsEditRoute + '/dashboard/products/new': typeof DashboardProductsNewRoute + '/dashboard/slots/detail': typeof DashboardSlotsDetailRoute + '/dashboard/slots/new': typeof DashboardSlotsNewRoute + '/dashboard/stores/edit': typeof DashboardStoresEditRoute + '/dashboard/stores/new': typeof DashboardStoresNewRoute + '/dashboard/users/$id': typeof DashboardUsersIdRoute + '/dashboard/banners/$id/edit': typeof DashboardBannersIdEditRoute + '/dashboard/coupons/$id/edit': typeof DashboardCouponsIdEditRoute + '/dashboard/product-groupings/$id/edit': typeof DashboardProductGroupingsIdEditRoute + '/dashboard/slots/$id/edit': typeof DashboardSlotsIdEditRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute + '/dashboard': typeof DashboardRouteWithChildren + '/login': typeof LoginRoute + '/dashboard/banners': typeof DashboardBannersRouteWithChildren + '/dashboard/complaints': typeof DashboardComplaintsRoute + '/dashboard/coupons': typeof DashboardCouponsRouteWithChildren + '/dashboard/customize-app': typeof DashboardCustomizeAppRouteWithChildren + '/dashboard/notifications': typeof DashboardNotificationsRoute + '/dashboard/orders': typeof DashboardOrdersRouteWithChildren + '/dashboard/prices': typeof DashboardPricesRoute + '/dashboard/product-groupings': typeof DashboardProductGroupingsRouteWithChildren + '/dashboard/product-tags': typeof DashboardProductTagsRouteWithChildren + '/dashboard/products': typeof DashboardProductsRouteWithChildren + '/dashboard/rebalance': typeof DashboardRebalanceRoute + '/dashboard/slots': typeof DashboardSlotsRouteWithChildren + '/dashboard/stores': typeof DashboardStoresRouteWithChildren + '/dashboard/users': typeof DashboardUsersRouteWithChildren + '/dashboard/vendor-snippets': typeof DashboardVendorSnippetsRoute + '/dashboard/': typeof DashboardIndexRoute + '/dashboard/banners/new': typeof DashboardBannersNewRoute + '/dashboard/coupons/new': typeof DashboardCouponsNewRoute + '/dashboard/customize-app/ordering': typeof DashboardCustomizeAppOrderingRoute + '/dashboard/customize-app/popular': typeof DashboardCustomizeAppPopularRoute + '/dashboard/orders/$id': typeof DashboardOrdersIdRoute + '/dashboard/orders/list': typeof DashboardOrdersListRoute + '/dashboard/orders/sequence': typeof DashboardOrdersSequenceRoute + '/dashboard/product-groupings/new': typeof DashboardProductGroupingsNewRoute + '/dashboard/product-tags/edit': typeof DashboardProductTagsEditRoute + '/dashboard/product-tags/new': typeof DashboardProductTagsNewRoute + '/dashboard/product-tags/order': typeof DashboardProductTagsOrderRoute + '/dashboard/products/$id': typeof DashboardProductsIdRoute + '/dashboard/products/edit': typeof DashboardProductsEditRoute + '/dashboard/products/new': typeof DashboardProductsNewRoute + '/dashboard/slots/detail': typeof DashboardSlotsDetailRoute + '/dashboard/slots/new': typeof DashboardSlotsNewRoute + '/dashboard/stores/edit': typeof DashboardStoresEditRoute + '/dashboard/stores/new': typeof DashboardStoresNewRoute + '/dashboard/users/$id': typeof DashboardUsersIdRoute + '/dashboard/banners/$id/edit': typeof DashboardBannersIdEditRoute + '/dashboard/coupons/$id/edit': typeof DashboardCouponsIdEditRoute + '/dashboard/product-groupings/$id/edit': typeof DashboardProductGroupingsIdEditRoute + '/dashboard/slots/$id/edit': typeof DashboardSlotsIdEditRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: + | '/' + | '/dashboard' + | '/login' + | '/dashboard/banners' + | '/dashboard/complaints' + | '/dashboard/coupons' + | '/dashboard/customize-app' + | '/dashboard/notifications' + | '/dashboard/orders' + | '/dashboard/prices' + | '/dashboard/product-groupings' + | '/dashboard/product-tags' + | '/dashboard/products' + | '/dashboard/rebalance' + | '/dashboard/slots' + | '/dashboard/stores' + | '/dashboard/users' + | '/dashboard/vendor-snippets' + | '/dashboard/' + | '/dashboard/banners/new' + | '/dashboard/coupons/new' + | '/dashboard/customize-app/ordering' + | '/dashboard/customize-app/popular' + | '/dashboard/orders/$id' + | '/dashboard/orders/list' + | '/dashboard/orders/sequence' + | '/dashboard/product-groupings/new' + | '/dashboard/product-tags/edit' + | '/dashboard/product-tags/new' + | '/dashboard/product-tags/order' + | '/dashboard/products/$id' + | '/dashboard/products/edit' + | '/dashboard/products/new' + | '/dashboard/slots/detail' + | '/dashboard/slots/new' + | '/dashboard/stores/edit' + | '/dashboard/stores/new' + | '/dashboard/users/$id' + | '/dashboard/banners/$id/edit' + | '/dashboard/coupons/$id/edit' + | '/dashboard/product-groupings/$id/edit' + | '/dashboard/slots/$id/edit' + fileRoutesByTo: FileRoutesByTo + to: + | '/' + | '/login' + | '/dashboard/banners' + | '/dashboard/complaints' + | '/dashboard/coupons' + | '/dashboard/customize-app' + | '/dashboard/notifications' + | '/dashboard/orders' + | '/dashboard/prices' + | '/dashboard/product-groupings' + | '/dashboard/product-tags' + | '/dashboard/products' + | '/dashboard/rebalance' + | '/dashboard/slots' + | '/dashboard/stores' + | '/dashboard/users' + | '/dashboard/vendor-snippets' + | '/dashboard' + | '/dashboard/banners/new' + | '/dashboard/coupons/new' + | '/dashboard/customize-app/ordering' + | '/dashboard/customize-app/popular' + | '/dashboard/orders/$id' + | '/dashboard/orders/list' + | '/dashboard/orders/sequence' + | '/dashboard/product-groupings/new' + | '/dashboard/product-tags/edit' + | '/dashboard/product-tags/new' + | '/dashboard/product-tags/order' + | '/dashboard/products/$id' + | '/dashboard/products/edit' + | '/dashboard/products/new' + | '/dashboard/slots/detail' + | '/dashboard/slots/new' + | '/dashboard/stores/edit' + | '/dashboard/stores/new' + | '/dashboard/users/$id' + | '/dashboard/banners/$id/edit' + | '/dashboard/coupons/$id/edit' + | '/dashboard/product-groupings/$id/edit' + | '/dashboard/slots/$id/edit' + id: + | '__root__' + | '/' + | '/dashboard' + | '/login' + | '/dashboard/banners' + | '/dashboard/complaints' + | '/dashboard/coupons' + | '/dashboard/customize-app' + | '/dashboard/notifications' + | '/dashboard/orders' + | '/dashboard/prices' + | '/dashboard/product-groupings' + | '/dashboard/product-tags' + | '/dashboard/products' + | '/dashboard/rebalance' + | '/dashboard/slots' + | '/dashboard/stores' + | '/dashboard/users' + | '/dashboard/vendor-snippets' + | '/dashboard/' + | '/dashboard/banners/new' + | '/dashboard/coupons/new' + | '/dashboard/customize-app/ordering' + | '/dashboard/customize-app/popular' + | '/dashboard/orders/$id' + | '/dashboard/orders/list' + | '/dashboard/orders/sequence' + | '/dashboard/product-groupings/new' + | '/dashboard/product-tags/edit' + | '/dashboard/product-tags/new' + | '/dashboard/product-tags/order' + | '/dashboard/products/$id' + | '/dashboard/products/edit' + | '/dashboard/products/new' + | '/dashboard/slots/detail' + | '/dashboard/slots/new' + | '/dashboard/stores/edit' + | '/dashboard/stores/new' + | '/dashboard/users/$id' + | '/dashboard/banners/$id/edit' + | '/dashboard/coupons/$id/edit' + | '/dashboard/product-groupings/$id/edit' + | '/dashboard/slots/$id/edit' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute + DashboardRoute: typeof DashboardRouteWithChildren + LoginRoute: typeof LoginRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/login': { + id: '/login' + path: '/login' + fullPath: '/login' + preLoaderRoute: typeof LoginRouteImport + parentRoute: typeof rootRouteImport + } + '/dashboard': { + id: '/dashboard' + path: '/dashboard' + fullPath: '/dashboard' + preLoaderRoute: typeof DashboardRouteImport + parentRoute: typeof rootRouteImport + } + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + '/dashboard/': { + id: '/dashboard/' + path: '/' + fullPath: '/dashboard/' + preLoaderRoute: typeof DashboardIndexRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/vendor-snippets': { + id: '/dashboard/vendor-snippets' + path: '/vendor-snippets' + fullPath: '/dashboard/vendor-snippets' + preLoaderRoute: typeof DashboardVendorSnippetsRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/users': { + id: '/dashboard/users' + path: '/users' + fullPath: '/dashboard/users' + preLoaderRoute: typeof DashboardUsersRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/stores': { + id: '/dashboard/stores' + path: '/stores' + fullPath: '/dashboard/stores' + preLoaderRoute: typeof DashboardStoresRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/slots': { + id: '/dashboard/slots' + path: '/slots' + fullPath: '/dashboard/slots' + preLoaderRoute: typeof DashboardSlotsRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/rebalance': { + id: '/dashboard/rebalance' + path: '/rebalance' + fullPath: '/dashboard/rebalance' + preLoaderRoute: typeof DashboardRebalanceRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/products': { + id: '/dashboard/products' + path: '/products' + fullPath: '/dashboard/products' + preLoaderRoute: typeof DashboardProductsRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/product-tags': { + id: '/dashboard/product-tags' + path: '/product-tags' + fullPath: '/dashboard/product-tags' + preLoaderRoute: typeof DashboardProductTagsRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/product-groupings': { + id: '/dashboard/product-groupings' + path: '/product-groupings' + fullPath: '/dashboard/product-groupings' + preLoaderRoute: typeof DashboardProductGroupingsRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/prices': { + id: '/dashboard/prices' + path: '/prices' + fullPath: '/dashboard/prices' + preLoaderRoute: typeof DashboardPricesRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/orders': { + id: '/dashboard/orders' + path: '/orders' + fullPath: '/dashboard/orders' + preLoaderRoute: typeof DashboardOrdersRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/notifications': { + id: '/dashboard/notifications' + path: '/notifications' + fullPath: '/dashboard/notifications' + preLoaderRoute: typeof DashboardNotificationsRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/customize-app': { + id: '/dashboard/customize-app' + path: '/customize-app' + fullPath: '/dashboard/customize-app' + preLoaderRoute: typeof DashboardCustomizeAppRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/coupons': { + id: '/dashboard/coupons' + path: '/coupons' + fullPath: '/dashboard/coupons' + preLoaderRoute: typeof DashboardCouponsRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/complaints': { + id: '/dashboard/complaints' + path: '/complaints' + fullPath: '/dashboard/complaints' + preLoaderRoute: typeof DashboardComplaintsRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/banners': { + id: '/dashboard/banners' + path: '/banners' + fullPath: '/dashboard/banners' + preLoaderRoute: typeof DashboardBannersRouteImport + parentRoute: typeof DashboardRoute + } + '/dashboard/users/$id': { + id: '/dashboard/users/$id' + path: '/$id' + fullPath: '/dashboard/users/$id' + preLoaderRoute: typeof DashboardUsersIdRouteImport + parentRoute: typeof DashboardUsersRoute + } + '/dashboard/stores/new': { + id: '/dashboard/stores/new' + path: '/new' + fullPath: '/dashboard/stores/new' + preLoaderRoute: typeof DashboardStoresNewRouteImport + parentRoute: typeof DashboardStoresRoute + } + '/dashboard/stores/edit': { + id: '/dashboard/stores/edit' + path: '/edit' + fullPath: '/dashboard/stores/edit' + preLoaderRoute: typeof DashboardStoresEditRouteImport + parentRoute: typeof DashboardStoresRoute + } + '/dashboard/slots/new': { + id: '/dashboard/slots/new' + path: '/new' + fullPath: '/dashboard/slots/new' + preLoaderRoute: typeof DashboardSlotsNewRouteImport + parentRoute: typeof DashboardSlotsRoute + } + '/dashboard/slots/detail': { + id: '/dashboard/slots/detail' + path: '/detail' + fullPath: '/dashboard/slots/detail' + preLoaderRoute: typeof DashboardSlotsDetailRouteImport + parentRoute: typeof DashboardSlotsRoute + } + '/dashboard/products/new': { + id: '/dashboard/products/new' + path: '/new' + fullPath: '/dashboard/products/new' + preLoaderRoute: typeof DashboardProductsNewRouteImport + parentRoute: typeof DashboardProductsRoute + } + '/dashboard/products/edit': { + id: '/dashboard/products/edit' + path: '/edit' + fullPath: '/dashboard/products/edit' + preLoaderRoute: typeof DashboardProductsEditRouteImport + parentRoute: typeof DashboardProductsRoute + } + '/dashboard/products/$id': { + id: '/dashboard/products/$id' + path: '/$id' + fullPath: '/dashboard/products/$id' + preLoaderRoute: typeof DashboardProductsIdRouteImport + parentRoute: typeof DashboardProductsRoute + } + '/dashboard/product-tags/order': { + id: '/dashboard/product-tags/order' + path: '/order' + fullPath: '/dashboard/product-tags/order' + preLoaderRoute: typeof DashboardProductTagsOrderRouteImport + parentRoute: typeof DashboardProductTagsRoute + } + '/dashboard/product-tags/new': { + id: '/dashboard/product-tags/new' + path: '/new' + fullPath: '/dashboard/product-tags/new' + preLoaderRoute: typeof DashboardProductTagsNewRouteImport + parentRoute: typeof DashboardProductTagsRoute + } + '/dashboard/product-tags/edit': { + id: '/dashboard/product-tags/edit' + path: '/edit' + fullPath: '/dashboard/product-tags/edit' + preLoaderRoute: typeof DashboardProductTagsEditRouteImport + parentRoute: typeof DashboardProductTagsRoute + } + '/dashboard/product-groupings/new': { + id: '/dashboard/product-groupings/new' + path: '/new' + fullPath: '/dashboard/product-groupings/new' + preLoaderRoute: typeof DashboardProductGroupingsNewRouteImport + parentRoute: typeof DashboardProductGroupingsRoute + } + '/dashboard/orders/sequence': { + id: '/dashboard/orders/sequence' + path: '/sequence' + fullPath: '/dashboard/orders/sequence' + preLoaderRoute: typeof DashboardOrdersSequenceRouteImport + parentRoute: typeof DashboardOrdersRoute + } + '/dashboard/orders/list': { + id: '/dashboard/orders/list' + path: '/list' + fullPath: '/dashboard/orders/list' + preLoaderRoute: typeof DashboardOrdersListRouteImport + parentRoute: typeof DashboardOrdersRoute + } + '/dashboard/orders/$id': { + id: '/dashboard/orders/$id' + path: '/$id' + fullPath: '/dashboard/orders/$id' + preLoaderRoute: typeof DashboardOrdersIdRouteImport + parentRoute: typeof DashboardOrdersRoute + } + '/dashboard/customize-app/popular': { + id: '/dashboard/customize-app/popular' + path: '/popular' + fullPath: '/dashboard/customize-app/popular' + preLoaderRoute: typeof DashboardCustomizeAppPopularRouteImport + parentRoute: typeof DashboardCustomizeAppRoute + } + '/dashboard/customize-app/ordering': { + id: '/dashboard/customize-app/ordering' + path: '/ordering' + fullPath: '/dashboard/customize-app/ordering' + preLoaderRoute: typeof DashboardCustomizeAppOrderingRouteImport + parentRoute: typeof DashboardCustomizeAppRoute + } + '/dashboard/coupons/new': { + id: '/dashboard/coupons/new' + path: '/new' + fullPath: '/dashboard/coupons/new' + preLoaderRoute: typeof DashboardCouponsNewRouteImport + parentRoute: typeof DashboardCouponsRoute + } + '/dashboard/banners/new': { + id: '/dashboard/banners/new' + path: '/new' + fullPath: '/dashboard/banners/new' + preLoaderRoute: typeof DashboardBannersNewRouteImport + parentRoute: typeof DashboardBannersRoute + } + '/dashboard/slots/$id/edit': { + id: '/dashboard/slots/$id/edit' + path: '/$id/edit' + fullPath: '/dashboard/slots/$id/edit' + preLoaderRoute: typeof DashboardSlotsIdEditRouteImport + parentRoute: typeof DashboardSlotsRoute + } + '/dashboard/product-groupings/$id/edit': { + id: '/dashboard/product-groupings/$id/edit' + path: '/$id/edit' + fullPath: '/dashboard/product-groupings/$id/edit' + preLoaderRoute: typeof DashboardProductGroupingsIdEditRouteImport + parentRoute: typeof DashboardProductGroupingsRoute + } + '/dashboard/coupons/$id/edit': { + id: '/dashboard/coupons/$id/edit' + path: '/$id/edit' + fullPath: '/dashboard/coupons/$id/edit' + preLoaderRoute: typeof DashboardCouponsIdEditRouteImport + parentRoute: typeof DashboardCouponsRoute + } + '/dashboard/banners/$id/edit': { + id: '/dashboard/banners/$id/edit' + path: '/$id/edit' + fullPath: '/dashboard/banners/$id/edit' + preLoaderRoute: typeof DashboardBannersIdEditRouteImport + parentRoute: typeof DashboardBannersRoute + } + } +} + +interface DashboardBannersRouteChildren { + DashboardBannersNewRoute: typeof DashboardBannersNewRoute + DashboardBannersIdEditRoute: typeof DashboardBannersIdEditRoute +} + +const DashboardBannersRouteChildren: DashboardBannersRouteChildren = { + DashboardBannersNewRoute: DashboardBannersNewRoute, + DashboardBannersIdEditRoute: DashboardBannersIdEditRoute, +} + +const DashboardBannersRouteWithChildren = + DashboardBannersRoute._addFileChildren(DashboardBannersRouteChildren) + +interface DashboardCouponsRouteChildren { + DashboardCouponsNewRoute: typeof DashboardCouponsNewRoute + DashboardCouponsIdEditRoute: typeof DashboardCouponsIdEditRoute +} + +const DashboardCouponsRouteChildren: DashboardCouponsRouteChildren = { + DashboardCouponsNewRoute: DashboardCouponsNewRoute, + DashboardCouponsIdEditRoute: DashboardCouponsIdEditRoute, +} + +const DashboardCouponsRouteWithChildren = + DashboardCouponsRoute._addFileChildren(DashboardCouponsRouteChildren) + +interface DashboardCustomizeAppRouteChildren { + DashboardCustomizeAppOrderingRoute: typeof DashboardCustomizeAppOrderingRoute + DashboardCustomizeAppPopularRoute: typeof DashboardCustomizeAppPopularRoute +} + +const DashboardCustomizeAppRouteChildren: DashboardCustomizeAppRouteChildren = { + DashboardCustomizeAppOrderingRoute: DashboardCustomizeAppOrderingRoute, + DashboardCustomizeAppPopularRoute: DashboardCustomizeAppPopularRoute, +} + +const DashboardCustomizeAppRouteWithChildren = + DashboardCustomizeAppRoute._addFileChildren( + DashboardCustomizeAppRouteChildren, + ) + +interface DashboardOrdersRouteChildren { + DashboardOrdersIdRoute: typeof DashboardOrdersIdRoute + DashboardOrdersListRoute: typeof DashboardOrdersListRoute + DashboardOrdersSequenceRoute: typeof DashboardOrdersSequenceRoute +} + +const DashboardOrdersRouteChildren: DashboardOrdersRouteChildren = { + DashboardOrdersIdRoute: DashboardOrdersIdRoute, + DashboardOrdersListRoute: DashboardOrdersListRoute, + DashboardOrdersSequenceRoute: DashboardOrdersSequenceRoute, +} + +const DashboardOrdersRouteWithChildren = DashboardOrdersRoute._addFileChildren( + DashboardOrdersRouteChildren, +) + +interface DashboardProductGroupingsRouteChildren { + DashboardProductGroupingsNewRoute: typeof DashboardProductGroupingsNewRoute + DashboardProductGroupingsIdEditRoute: typeof DashboardProductGroupingsIdEditRoute +} + +const DashboardProductGroupingsRouteChildren: DashboardProductGroupingsRouteChildren = + { + DashboardProductGroupingsNewRoute: DashboardProductGroupingsNewRoute, + DashboardProductGroupingsIdEditRoute: DashboardProductGroupingsIdEditRoute, + } + +const DashboardProductGroupingsRouteWithChildren = + DashboardProductGroupingsRoute._addFileChildren( + DashboardProductGroupingsRouteChildren, + ) + +interface DashboardProductTagsRouteChildren { + DashboardProductTagsEditRoute: typeof DashboardProductTagsEditRoute + DashboardProductTagsNewRoute: typeof DashboardProductTagsNewRoute + DashboardProductTagsOrderRoute: typeof DashboardProductTagsOrderRoute +} + +const DashboardProductTagsRouteChildren: DashboardProductTagsRouteChildren = { + DashboardProductTagsEditRoute: DashboardProductTagsEditRoute, + DashboardProductTagsNewRoute: DashboardProductTagsNewRoute, + DashboardProductTagsOrderRoute: DashboardProductTagsOrderRoute, +} + +const DashboardProductTagsRouteWithChildren = + DashboardProductTagsRoute._addFileChildren(DashboardProductTagsRouteChildren) + +interface DashboardProductsRouteChildren { + DashboardProductsIdRoute: typeof DashboardProductsIdRoute + DashboardProductsEditRoute: typeof DashboardProductsEditRoute + DashboardProductsNewRoute: typeof DashboardProductsNewRoute +} + +const DashboardProductsRouteChildren: DashboardProductsRouteChildren = { + DashboardProductsIdRoute: DashboardProductsIdRoute, + DashboardProductsEditRoute: DashboardProductsEditRoute, + DashboardProductsNewRoute: DashboardProductsNewRoute, +} + +const DashboardProductsRouteWithChildren = + DashboardProductsRoute._addFileChildren(DashboardProductsRouteChildren) + +interface DashboardSlotsRouteChildren { + DashboardSlotsDetailRoute: typeof DashboardSlotsDetailRoute + DashboardSlotsNewRoute: typeof DashboardSlotsNewRoute + DashboardSlotsIdEditRoute: typeof DashboardSlotsIdEditRoute +} + +const DashboardSlotsRouteChildren: DashboardSlotsRouteChildren = { + DashboardSlotsDetailRoute: DashboardSlotsDetailRoute, + DashboardSlotsNewRoute: DashboardSlotsNewRoute, + DashboardSlotsIdEditRoute: DashboardSlotsIdEditRoute, +} + +const DashboardSlotsRouteWithChildren = DashboardSlotsRoute._addFileChildren( + DashboardSlotsRouteChildren, +) + +interface DashboardStoresRouteChildren { + DashboardStoresEditRoute: typeof DashboardStoresEditRoute + DashboardStoresNewRoute: typeof DashboardStoresNewRoute +} + +const DashboardStoresRouteChildren: DashboardStoresRouteChildren = { + DashboardStoresEditRoute: DashboardStoresEditRoute, + DashboardStoresNewRoute: DashboardStoresNewRoute, +} + +const DashboardStoresRouteWithChildren = DashboardStoresRoute._addFileChildren( + DashboardStoresRouteChildren, +) + +interface DashboardUsersRouteChildren { + DashboardUsersIdRoute: typeof DashboardUsersIdRoute +} + +const DashboardUsersRouteChildren: DashboardUsersRouteChildren = { + DashboardUsersIdRoute: DashboardUsersIdRoute, +} + +const DashboardUsersRouteWithChildren = DashboardUsersRoute._addFileChildren( + DashboardUsersRouteChildren, +) + +interface DashboardRouteChildren { + DashboardBannersRoute: typeof DashboardBannersRouteWithChildren + DashboardComplaintsRoute: typeof DashboardComplaintsRoute + DashboardCouponsRoute: typeof DashboardCouponsRouteWithChildren + DashboardCustomizeAppRoute: typeof DashboardCustomizeAppRouteWithChildren + DashboardNotificationsRoute: typeof DashboardNotificationsRoute + DashboardOrdersRoute: typeof DashboardOrdersRouteWithChildren + DashboardPricesRoute: typeof DashboardPricesRoute + DashboardProductGroupingsRoute: typeof DashboardProductGroupingsRouteWithChildren + DashboardProductTagsRoute: typeof DashboardProductTagsRouteWithChildren + DashboardProductsRoute: typeof DashboardProductsRouteWithChildren + DashboardRebalanceRoute: typeof DashboardRebalanceRoute + DashboardSlotsRoute: typeof DashboardSlotsRouteWithChildren + DashboardStoresRoute: typeof DashboardStoresRouteWithChildren + DashboardUsersRoute: typeof DashboardUsersRouteWithChildren + DashboardVendorSnippetsRoute: typeof DashboardVendorSnippetsRoute + DashboardIndexRoute: typeof DashboardIndexRoute +} + +const DashboardRouteChildren: DashboardRouteChildren = { + DashboardBannersRoute: DashboardBannersRouteWithChildren, + DashboardComplaintsRoute: DashboardComplaintsRoute, + DashboardCouponsRoute: DashboardCouponsRouteWithChildren, + DashboardCustomizeAppRoute: DashboardCustomizeAppRouteWithChildren, + DashboardNotificationsRoute: DashboardNotificationsRoute, + DashboardOrdersRoute: DashboardOrdersRouteWithChildren, + DashboardPricesRoute: DashboardPricesRoute, + DashboardProductGroupingsRoute: DashboardProductGroupingsRouteWithChildren, + DashboardProductTagsRoute: DashboardProductTagsRouteWithChildren, + DashboardProductsRoute: DashboardProductsRouteWithChildren, + DashboardRebalanceRoute: DashboardRebalanceRoute, + DashboardSlotsRoute: DashboardSlotsRouteWithChildren, + DashboardStoresRoute: DashboardStoresRouteWithChildren, + DashboardUsersRoute: DashboardUsersRouteWithChildren, + DashboardVendorSnippetsRoute: DashboardVendorSnippetsRoute, + DashboardIndexRoute: DashboardIndexRoute, +} + +const DashboardRouteWithChildren = DashboardRoute._addFileChildren( + DashboardRouteChildren, +) + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + DashboardRoute: DashboardRouteWithChildren, + LoginRoute: LoginRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() + +import type { getRouter } from './router.tsx' +import type { createStart } from '@tanstack/react-start' +declare module '@tanstack/react-start' { + interface Register { + ssr: true + router: Awaited> + } +} diff --git a/apps/admin-web/src/router.tsx b/apps/admin-web/src/router.tsx new file mode 100644 index 0000000..e7b1c4d --- /dev/null +++ b/apps/admin-web/src/router.tsx @@ -0,0 +1,19 @@ +import { createRouter as createTanStackRouter } from '@tanstack/react-router' +import { routeTree } from './routeTree.gen' + +export function getRouter() { + const router = createTanStackRouter({ + routeTree, + scrollRestoration: true, + defaultPreload: 'intent', + defaultPreloadStaleTime: 0, + }) + + return router +} + +declare module '@tanstack/react-router' { + interface Register { + router: ReturnType + } +} diff --git a/apps/admin-web/src/routes/__root.tsx b/apps/admin-web/src/routes/__root.tsx new file mode 100644 index 0000000..0598760 --- /dev/null +++ b/apps/admin-web/src/routes/__root.tsx @@ -0,0 +1,64 @@ +import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router' +import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools' +import { TanStackDevtools } from '@tanstack/react-devtools' +import { QueryClientProvider } from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import { Toaster } from 'sonner' +import { trpc, getTrpcClient } from '../lib/trpc-client' +import queryClient from '../lib/query-client' +import { StaffAuthProvider } from '../components/context/staff-auth-context' +import { RefreshProvider } from '../lib/refresh-context' +import appCss from '../styles.css?url' + +const trpcClient = getTrpcClient() + +export const Route = createRootRoute({ + head: () => ({ + meta: [ + { charSet: 'utf-8' }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + { title: 'Freshyo Admin' }, + ], + links: [ + { rel: 'stylesheet', href: appCss }, + { rel: 'icon', type: 'image/png', href: '/favicon.png' }, + ], + }), + shellComponent: RootDocument, +}) + +function RootDocument({ children }: { children: React.ReactNode }) { + return ( + + + + + + + + + +
{children}
+ + +
+
+
+
+ , + }, + ]} + /> + + + + ) +} diff --git a/apps/admin-web/src/routes/dashboard.banners.$id.edit.tsx b/apps/admin-web/src/routes/dashboard.banners.$id.edit.tsx new file mode 100644 index 0000000..9db67d1 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.banners.$id.edit.tsx @@ -0,0 +1,152 @@ +import React, { useState, useEffect } from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { AppContainer, p as MyText } from 'web-components' +import { ArrowLeft } from 'lucide-react' +import BannerForm, { type BannerFormData } from '../components/BannerForm' +import { trpc } from '@/lib/trpc-client' +import { ErrorToast } from '@/services/toaster' + +export const Route = createFileRoute('/dashboard/banners/$id/edit')({ + component: EditBanner, +}) + +function EditBanner() { + const { id } = Route.useParams() + const bannerId = id as string + + const [isLoading, setIsLoading] = useState(true) + const [isSubmitting, setIsSubmitting] = useState(false) + // Load real banner data from API + const { data: bannerData } = trpc.admin.banner.getBanner.useQuery({ + id: parseInt(bannerId) + }) + const { refetch: refetchBanners } = trpc.admin.banner.getBanners.useQuery(undefined, { + enabled: false, + }) + const [banner, setBanner] = useState(undefined) + + + useEffect(() => { + const loadBanner = async () => { + try { + setIsLoading(true) + + + + if (bannerData) { + // Handle data format compatibility (productId -> skuIds migration) + const processedBanner = { + ...bannerData, + skuIds: Array.isArray(bannerData.skuIds) + ? bannerData.skuIds + : (bannerData.skuIds ? [bannerData.skuIds] : []) + } + + setBanner(processedBanner) + } else { + ErrorToast('Banner not found') + window.history.back() + } + } catch (err) { + console.error('Failed to load banner:', err) + ErrorToast('Failed to load banner data') + window.history.back() + } finally { + setIsLoading(false) + } + } + + loadBanner() + }, [bannerId, bannerData]) + + const initialValues: BannerFormData = banner ? { + name: banner.name, + imageUrl: banner.imageUrl, + description: banner.description || '', + skuIds: banner.skuIds || [], + redirectUrl: banner.redirectUrl || '', + // serialNum removed - handled automatically by backend + } : { + name: '', + imageUrl: '', + description: '', + skuIds: [], + redirectUrl: '', + // serialNum removed - handled automatically by backend + } + + const updateBannerMutation = trpc.admin.banner.updateBanner.useMutation() + + const handleSubmit = async (values: BannerFormData, imageUrl?: string) => { + if (!banner) return + + setIsSubmitting(true) + + try { + await updateBannerMutation.mutateAsync({ + id: banner.id, + name: values.name, + imageUrl: imageUrl || banner.imageUrl, + description: values.description || undefined, + skuIds: values.skuIds.length > 0 ? values.skuIds : [], + redirectUrl: values.redirectUrl || undefined, + }) + + await refetchBanners() + window.alert('Success: Banner updated successfully') + window.history.back() + } catch (err) { + ErrorToast('Failed to update banner. Please try again.') + } finally { + setIsSubmitting(false) + } + } + + const handleCancel = () => { + window.history.back() + } + + if (isLoading) { + return ( + +
+ Loading banner... +
+
+ ) + } + + if (!banner) { + return ( + +
+ Banner not found +
+
+ ) + } + + return ( + +
+ {/* Header */} +
+ + Edit Banner +
+
+ + +
+ + ) +} diff --git a/apps/admin-web/src/routes/dashboard.banners.new.tsx b/apps/admin-web/src/routes/dashboard.banners.new.tsx new file mode 100644 index 0000000..136bc55 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.banners.new.tsx @@ -0,0 +1,83 @@ +import React, { useState } from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { AppContainer, p as MyText } from 'web-components' +import { ArrowLeft } from 'lucide-react' +import BannerForm, { type BannerFormData } from '../components/BannerForm' +import { trpc } from '@/lib/trpc-client' +import { ErrorToast } from '@/services/toaster' + +export const Route = createFileRoute('/dashboard/banners/new')({ + component: CreateBanner, +}) + +function CreateBanner() { + const [isSubmitting, setIsSubmitting] = useState(false) + + const initialValues: BannerFormData = { + name: '', + imageUrl: '', + description: '', + skuIds: [], + redirectUrl: '', + // serialNum removed - assigned automatically by backend + } + + const createBannerMutation = trpc.admin.banner.createBanner.useMutation() + const { refetch: refetchBanners } = trpc.admin.banner.getBanners.useQuery(undefined, { + enabled: false, + }) + + const handleSubmit = async (values: BannerFormData, imageUrl?: string) => { + if (!imageUrl) { + ErrorToast('Image is required') + return + } + + setIsSubmitting(true) + + try { + await createBannerMutation.mutateAsync({ + name: values.name, + imageUrl, + description: values.description || undefined, + skuIds: values.skuIds.length > 0 ? values.skuIds : [], + redirectUrl: values.redirectUrl || undefined, + }) + + await refetchBanners() + window.alert('Success: Banner created successfully') + window.history.back() + } catch (err) { + ErrorToast('Failed to create banner. Please try again.') + } finally { + setIsSubmitting(false) + } + } + + const handleCancel = () => { + window.history.back() + } + + return ( + +
+ {/* Header */} +
+ + Create Banner +
+
+ + +
+ + ) +} diff --git a/apps/admin-web/src/routes/dashboard.banners.tsx b/apps/admin-web/src/routes/dashboard.banners.tsx new file mode 100644 index 0000000..3f173c2 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.banners.tsx @@ -0,0 +1,432 @@ +import React, { useState } from 'react' +import { createFileRoute, Outlet, useLocation, useNavigate } from '@tanstack/react-router' +import { AppContainer, p as MyText } from 'web-components' +import { trpc } from '@/lib/trpc-client' +import { ErrorToast } from '@/services/toaster' +import { useManualRefresh } from '@/lib/refresh-context' +import { Image as ImageIcon, Plus, Pencil, Trash2, CircleCheck, CircleDot, Hourglass, X } from 'lucide-react' +import type { Banner as SharedBanner } from '@packages/shared' + +export const Route = createFileRoute('/dashboard/banners')({ + component: DashboardBanners, +}) + +// Serialized banner row (API JSON carries string dates) anchored to the shared shape +type Banner = Omit & { + createdAt: string, + lastUpdated: string +} + +function DashboardBanners() { + const location = useLocation() + const navigate = useNavigate() + const [refreshing, setRefreshing] = useState(false) + + // Edit mode state + const [editMode, setEditMode] = useState(false) + const [selectedSlot, setSelectedSlot] = useState(null) + const [slotAssignments, setSlotAssignments] = useState<{ [slot: number]: number | null }>({}) + const [originalAssignments, setOriginalAssignments] = useState<{ [slot: number]: number | null }>({}) + const [saving, setSaving] = useState(false) + + // Real API calls + const { data: bannersData, isLoading, error, refetch } = trpc.admin.banner.getBanners.useQuery() + + const deleteBannerMutation = trpc.admin.banner.deleteBanner.useMutation() + const updateBannerMutation = trpc.admin.banner.updateBanner.useMutation() + const emptySlotMutation = trpc.admin.banner.updateBanner.useMutation() + + const banners = bannersData?.banners || [] + + // Initialize slot assignments when banners load + React.useEffect(() => { + const assignments: { [slot: number]: number | null } = { 1: null, 2: null, 3: null, 4: null } + banners.forEach((banner) => { + if (banner.serialNum && banner.serialNum >= 1 && banner.serialNum <= 4) { + assignments[banner.serialNum] = banner.id + } + }) + setSlotAssignments(assignments) + setOriginalAssignments({ ...assignments }) + }, [bannersData]) + + const onRefresh = async () => { + setRefreshing(true) + await refetch() + setRefreshing(false) + } + + useManualRefresh(() => { + onRefresh() + }) + + if (location.pathname !== '/dashboard/banners') { + return + } + + // Slot and edit mode handlers + const handleSlotClick = (slotNumber: number) => { + setSelectedSlot(slotNumber) + setEditMode(true) + } + + const handleBannerSelect = (bannerId: number) => { + if (!editMode || selectedSlot === null) return + + // Remove banner from any existing slot + const newAssignments = { ...slotAssignments } + Object.keys(newAssignments).forEach((slot) => { + if (newAssignments[parseInt(slot)] === bannerId) { + newAssignments[parseInt(slot)] = null + } + }) + + // Assign banner to selected slot + newAssignments[selectedSlot] = bannerId + setSlotAssignments(newAssignments) + } + + const handleSave = async () => { + setSaving(true) + try { + // Get banners that need to be updated + const bannersToUpdate: { id: number, serialNum: number | null }[] = [] + + // Clear serial numbers for banners no longer in slots + banners.forEach((banner) => { + const currentSlot = banner.serialNum + const assignedSlot = Object.keys(slotAssignments).find((slot) => + slotAssignments[parseInt(slot)] === banner.id + ) + + if (currentSlot !== (assignedSlot ? parseInt(assignedSlot) : null)) { + bannersToUpdate.push({ + id: banner.id, + serialNum: assignedSlot ? parseInt(assignedSlot) : null + }) + } + }) + + // Update banners that gained slots + Object.keys(slotAssignments).forEach((slot) => { + const slotNum = parseInt(slot) + const bannerId = slotAssignments[slotNum] + if (bannerId) { + const banner = banners.find((b) => b.id === bannerId) + if (banner && banner.serialNum !== slotNum) { + bannersToUpdate.push({ + id: bannerId, + serialNum: slotNum + }) + } + } + }) + + // Execute updates + await Promise.all( + bannersToUpdate.map(({ id, serialNum }) => + updateBannerMutation.mutateAsync({ id, serialNum }) + ) + ) + + setOriginalAssignments({ ...slotAssignments }) + setEditMode(false) + setSelectedSlot(null) + await refetch() + window.alert('Success: Slot assignments saved successfully') + } catch (err) { + ErrorToast('Failed to save slot assignments') + } finally { + setSaving(false) + } + } + + const handleCancel = () => { + setSlotAssignments({ ...originalAssignments }) + setEditMode(false) + setSelectedSlot(null) + } + + const handleEmptySlot = async () => { + if (!selectedSlot || !slotAssignments[selectedSlot]) return + + const bannerId = slotAssignments[selectedSlot] + const banner = banners.find((b) => b.id === bannerId) + + if (!banner) return + + try { + // Update banner's serialNum to null to empty the slot + await emptySlotMutation.mutateAsync({ + id: banner.id, + serialNum: null + }) + + // Update local state + setSlotAssignments((prev) => ({ + ...prev, + [selectedSlot]: null + })) + + // Update original assignments for cancel functionality + setOriginalAssignments((prev) => ({ + ...prev, + [selectedSlot]: null + })) + + window.alert(`Success: Slot ${selectedSlot} has been emptied`) + } catch (err) { + ErrorToast('Failed to empty slot') + } + } + + // Helper function to get banner name by ID + const getBannerNameById = (id: number | null) => { + if (!id) return null + const banner = banners.find((b) => b.id === id) + return banner ? banner.name : null + } + + const handleEdit = (banner: Banner) => { + navigate({ to: '/dashboard/banners/$id/edit', params: { id: String(banner.id) } }) + } + + const handleDelete = (id: number) => { + if (!window.confirm('Delete Banner: Are you sure you want to delete this banner?')) return + ;(async () => { + try { + await deleteBannerMutation.mutateAsync({ id }) + refetch() + window.alert('Success: Banner deleted') + } catch (err) { + ErrorToast('Failed to delete banner') + } + })() + } + + const handleCreate = () => { + navigate({ to: '/dashboard/banners/new' }) + } + + if (isLoading) { + return ( + +
+ Loading banners... +
+
+ ) + } + + if (error) { + return ( + +
+ Error loading banners +
+
+ ) + } + + return ( + +
+
+ {/* Slots Row */} +
+ + {editMode ? `Select banner for Slot ${selectedSlot}` : 'Banner Slots'} + +
+ {[1, 2, 3, 4].map((slotNum) => { + const assignedBannerId = slotAssignments[slotNum] + const bannerName = getBannerNameById(assignedBannerId) + const isSelected = editMode && selectedSlot === slotNum + + return ( + + ) + })} +
+ + {/* Action buttons in edit mode */} + {editMode && ( +
+ {/* Save/Cancel buttons */} +
+ + +
+ + {/* Empty Slot button */} + +
+ )} +
+ + {/* Banners List */} +
+ {editMode && ( +
+ + Tap a banner below to assign it to Slot {selectedSlot} + +
+ )} + + {banners.length === 0 ? ( +
+ + + + No Banners Yet + + Start by creating your first banner using the button above. + +
+ ) : ( + banners.map((banner) => { + const isAssignedToSlot = Object.values(slotAssignments).includes(banner.id) + const isAssignedToSelectedSlot = slotAssignments[selectedSlot || 0] === banner.id + const canInteract = editMode + + return ( +
handleBannerSelect(banner.id) : undefined} + role={canInteract ? 'button' : undefined} + tabIndex={canInteract ? 0 : undefined} + onKeyDown={canInteract ? (e) => { if (e.key === 'Enter') handleBannerSelect(banner.id) } : undefined} + className={`mb-3 w-full rounded-xl border bg-white p-4 text-left shadow-sm ${canInteract ? 'cursor-pointer' : ''} ${canInteract && isAssignedToSelectedSlot + ? 'border-blue-500 bg-blue-50' + : canInteract && isAssignedToSlot + ? 'border-green-300 bg-green-50' + : canInteract + ? 'border-gray-200' + : 'border-gray-100' + }`} + > + + {banner.name} + + + + {banner.name} + + + {canInteract && isAssignedToSelectedSlot && ( + + + + )} + {canInteract && isAssignedToSlot && !isAssignedToSelectedSlot && ( + + + + )} + + {!editMode && ( + <> + + + + )} + + + {banner.description && ( + + {banner.description} + + )} + + + Created: {new Date(banner.createdAt).toLocaleDateString()} + + {banner.serialNum && banner.serialNum >= 1 && banner.serialNum <= 4 && ( + + Slot {banner.serialNum} + + )} + + + +
+ ) + }) + )} +
+
+ + {/* Floating Action Button */} + +
+
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.complaints.tsx b/apps/admin-web/src/routes/dashboard.complaints.tsx new file mode 100644 index 0000000..13acd4f --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.complaints.tsx @@ -0,0 +1,314 @@ +import React, { useState, useCallback, useMemo } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { CircleAlert, Reply, User as UserIcon, ShoppingBag, Inbox } from 'lucide-react' +import { p as MyText, MyFlatList, MyButton, ConfirmationDialog } from 'web-components' +import { useMarkDataFetchers } from '@/lib/refresh-context' +import { trpc } from '@/lib/trpc-client' + +export const Route = createFileRoute('/dashboard/complaints')({ + component: Complaints, +}) + +function Complaints() { + const navigate = useNavigate() + const [dialogOpen, setDialogOpen] = useState(false) + const [selectedComplaintId, setSelectedComplaintId] = useState(null) + const [viewerOpen, setViewerOpen] = useState(false) + const [viewerImages, setViewerImages] = useState([]) + const [viewerIndex, setViewerIndex] = useState(0) + + const { + data, + isLoading, + isError, + error, + fetchNextPage, + hasNextPage, + isFetchingNextPage, + refetch, + } = trpc.admin.complaint.getAll.useInfiniteQuery( + { limit: 20 }, + { + getNextPageParam: (lastPage) => lastPage.nextCursor, + } + ) + + useMarkDataFetchers(() => { + refetch() + }) + + const resolveComplaint = trpc.admin.complaint.resolve.useMutation() + + const complaints = useMemo(() => { + const allComplaints = data?.pages.flatMap((page) => page.complaints) || [] + return allComplaints.filter( + (complaint, index, self) => + index === self.findIndex((c) => c.id === complaint.id) + ) + }, [data]) + + const handleLoadMore = useCallback(() => { + if (hasNextPage && !isFetchingNextPage) { + fetchNextPage() + } + }, [hasNextPage, isFetchingNextPage, fetchNextPage]) + + const handleUserPress = useCallback((userId: number) => { + navigate({ to: '/dashboard/users/$id', params: { id: String(userId) } }) + }, [navigate]) + + const handleOrderPress = useCallback((orderId: number) => { + navigate({ to: '/dashboard/orders/$id', params: { id: String(orderId) } }) + }, [navigate]) + + const handleMarkResolved = (id: number) => { + setSelectedComplaintId(id) + setDialogOpen(true) + } + + const handleConfirmResolve = (response?: string) => { + if (!selectedComplaintId) return + + resolveComplaint.mutate( + { id: String(selectedComplaintId), response: response ?? '' }, + { + onSuccess: () => { + window.alert('Success: Complaint marked as resolved') + refetch() + setDialogOpen(false) + setSelectedComplaintId(null) + }, + onError: (error: any) => { + window.alert(`Error: ${error.message || 'Failed to resolve complaint'}`) + setDialogOpen(false) + setSelectedComplaintId(null) + }, + } + ) + } + + const openImageViewer = (images: string[], index: number) => { + setViewerImages(images) + setViewerIndex(index) + setViewerOpen(true) + } + + if (isLoading) { + return ( +
+
+ Loading complaints... +
+ ) + } + + if (isError) { + return ( +
+ + Error + + {error?.message || 'Failed to load complaints'} + + +
+ ) + } + + return ( +
+
+ item.id.toString()} + renderItem={(item) => ( +
+
+ + Complaint #{item.id} + + + + {item.status === 'resolved' ? 'Resolved' : 'Pending'} + + +
+ + + {item.text} + + + {item.response && ( +
+
+ + + Admin Reply + +
+ + {item.response} + +
+ )} + + {item.images && item.images.length > 0 && ( +
+ + Attached Images: + +
+ {item.images.map((imageUri: string, index: number) => ( + {`Complaint openImageViewer(item.images as string[], index)} + className="h-16 w-16 cursor-pointer rounded-lg border border-gray-200 object-cover" + /> + ))} +
+
+ )} + +
+ + + {item.orderId && ( + <> + | + + + + )} +
+ + {item.status === 'pending' && ( + + )} +
+ )} + ListEmptyComponent={ +
+
+ +
+ + No complaints + + + All complaints will appear here + +
+ } + ListFooterComponent={ + isFetchingNextPage ? ( +
+
+ Loading more... +
+ ) : hasNextPage ? ( +
+ +
+ ) : null + } + /> +
+ { + setDialogOpen(false) + setSelectedComplaintId(null) + }} + title="Resolve Complaint" + message="Add admin notes for this resolution:" + confirmText="Resolve" + cancelText="Cancel" + isLoading={resolveComplaint.isPending} + /> + {viewerOpen && viewerImages.length > 0 && ( +
setViewerOpen(false)}> + + {viewerImages.length > 1 && ( + + )} + Complaint attachment viewer e.stopPropagation()} + /> + {viewerImages.length > 1 && ( + + )} +
+ {viewerIndex + 1} / {viewerImages.length} +
+
+ )} +
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.coupons.$id.edit.tsx b/apps/admin-web/src/routes/dashboard.coupons.$id.edit.tsx new file mode 100644 index 0000000..8f61633 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.coupons.$id.edit.tsx @@ -0,0 +1,126 @@ +import React from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { AppContainer, p as MyText } from 'web-components' +import CouponForm from '../components/CouponForm' +import { trpc } from '@/lib/trpc-client' +import { ErrorToast } from '@/services/toaster' +import dayjs from 'dayjs' + +// Ported from common-ui/shared-types (CreateCouponPayload) — @packages/shared +// does not export it, so the shape is copied here to keep behavior identical. +interface CreateCouponPayload { + couponCodes: string[], + discountPercent?: number, + flatDiscount?: number, + minOrder?: number, + maxValue?: number, + validTill?: string, + maxLimitForUser?: number, + isApplyForAll: boolean, + isUserBased: boolean, + targetUsers?: number[], + productIds?: number[], + skuIds?: number[], + applicableUsers?: number[], + applicableProducts?: number[], + exclusiveApply?: boolean +} + +export const Route = createFileRoute('/dashboard/coupons/$id/edit')({ + component: EditCoupon, +}) + +function EditCoupon() { + const { id } = Route.useParams() + const couponId = parseInt(id as string) + + const { data: coupon, isLoading, refetch } = trpc.admin.coupon.getById.useQuery({ id: couponId }) + const { refetch: refetchCoupons } = trpc.admin.coupon.getAll.useInfiniteQuery( + { limit: 20, search: '' }, + { + enabled: false, + getNextPageParam: (lastPage) => lastPage.nextCursor, + } + ) + const { refetch: refetchReservedCoupons } = trpc.admin.coupon.getReservedCoupons.useInfiniteQuery( + { limit: 20, search: '' }, + { + enabled: false, + getNextPageParam: (lastPage) => lastPage.nextCursor, + } + ) + const updateCoupon = trpc.admin.coupon.update.useMutation() + + const handleUpdateCoupon = (values: CreateCouponPayload & { isReservedCoupon?: boolean }) => { + // Transform targetUsers array to targetUser for backend compatibility + const { targetUsers, ...rest } = values + const updates = { + ...rest, + targetUser: targetUsers?.[0] || undefined, + } + + // For flat discounts, send the discount value as maxValue too + if (updates.flatDiscount !== undefined) { + updates.maxValue = updates.flatDiscount + } + + updateCoupon.mutate({ id: couponId, updates }, { + onSuccess: async () => { + await refetch() + await refetchCoupons() + await refetchReservedCoupons() + window.alert('Success: Coupon updated successfully') + window.history.back() + }, + onError: (error: any) => { + ErrorToast(error.message || 'Failed to update coupon') + }, + }) + } + + if (isLoading) { + return ( + +
+ Loading... +
+
+ ) + } + + if (!coupon) { + return ( + +
+ Coupon not found +
+
+ ) + } + + // Transform coupon data for form (targetUser to targetUsers array) + const initialValues: Partial = { + couponCodes: coupon.couponCode ? [coupon.couponCode] : [''], + isUserBased: coupon.isUserBased, + isApplyForAll: coupon.isApplyForAll, + targetUsers: coupon.targetUser ? [coupon.targetUser.id] : [], + discountPercent: coupon.discountPercent ? parseFloat(coupon.discountPercent) : undefined, + flatDiscount: coupon.flatDiscount ? parseFloat(coupon.flatDiscount) : undefined, + minOrder: coupon.minOrder ? parseFloat(coupon.minOrder) : undefined, + maxValue: coupon.maxValue ? parseFloat(coupon.maxValue) : undefined, + validTill: coupon.validTill ? dayjs(coupon.validTill).format('YYYY-MM-DD') : undefined, + maxLimitForUser: coupon.maxLimitForUser || undefined, + skuIds: coupon.skuIds, + isReservedCoupon: false, // Normal coupons + } + + return ( + + + + ) +} diff --git a/apps/admin-web/src/routes/dashboard.coupons.new.tsx b/apps/admin-web/src/routes/dashboard.coupons.new.tsx new file mode 100644 index 0000000..3fe7347 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.coupons.new.tsx @@ -0,0 +1,70 @@ +import React from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { AppContainer } from 'web-components' +import CouponForm from '../components/CouponForm' +import { trpc } from '@/lib/trpc-client' +import { ErrorToast } from '@/services/toaster' + +export const Route = createFileRoute('/dashboard/coupons/new')({ + component: CreateCoupon, +}) + +function CreateCoupon() { + const createCoupon = trpc.admin.coupon.create.useMutation() + const createReservedCoupon = trpc.admin.coupon.createReservedCoupon.useMutation() + const { refetch: refetchCoupons } = trpc.admin.coupon.getAll.useInfiniteQuery( + { limit: 20, search: '' }, + { + enabled: false, + getNextPageParam: (lastPage) => lastPage.nextCursor, + } + ) + const { refetch: refetchReservedCoupons } = trpc.admin.coupon.getReservedCoupons.useInfiniteQuery( + { limit: 20, search: '' }, + { + enabled: false, + getNextPageParam: (lastPage) => lastPage.nextCursor, + } + ) + + const handleCreateCoupon = async (values: any) => { + const { isReservedCoupon, couponCodes, ...rest } = values + // Transform targetUsers array to targetUser for backend compatibility + const payload = { + ...rest, + targetUser: rest.targetUsers?.[0] || undefined, + } + delete payload.targetUsers + + // For flat discounts, send the discount value as maxValue too + if (payload.flatDiscount !== undefined) { + payload.maxValue = payload.flatDiscount + } + + const codes = (couponCodes || []).map((c: string) => c.trim()).filter(Boolean) + if (codes.length === 0) { + ErrorToast('At least one coupon code is required') + return + } + + const mutation = isReservedCoupon ? createReservedCoupon : createCoupon + try { + await mutation.mutateAsync({ ...payload, couponCodes: codes }) + await refetchCoupons() + await refetchReservedCoupons() + window.alert(`Success: ${codes.length} coupon${codes.length > 1 ? 's' : ''} created successfully`) + window.history.back() + } catch (error: any) { + ErrorToast(error.message || 'Failed to create coupons') + } + } + + return ( + + + + ) +} diff --git a/apps/admin-web/src/routes/dashboard.coupons.tsx b/apps/admin-web/src/routes/dashboard.coupons.tsx new file mode 100644 index 0000000..53966ef --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.coupons.tsx @@ -0,0 +1,509 @@ +import React, { useState, useCallback, useMemo } from 'react' +import { createFileRoute, Outlet, useLocation, useNavigate } from '@tanstack/react-router' +import { Percent, IndianRupee, Pencil, Trash2, TicketPercent, CircleAlert, Loader2, Users, Package, UserCheck, User, ListFilter, Plus } from 'lucide-react' +import { p as MyText, MyButton, SearchBar, MyFlatList } from 'web-components' +import { useManualRefresh, useMarkDataFetchers } from '@/lib/refresh-context' +import { trpc } from '@/lib/trpc-client' +import { ErrorToast } from '@/services/toaster' +import { MultiSelect } from '@/components/MultiSelect' + +export const Route = createFileRoute('/dashboard/coupons')({ + component: Coupons, +}) + +const CouponItem = ({ item, onDelete }: { item: any, onDelete: (id: number) => void }) => { + const navigate = useNavigate() + + const getCouponStatus = (coupon: any) => { + if (coupon.isInvalidated) return 'inactive' + if (coupon.validTill && new Date(coupon.validTill) <= new Date()) return 'expired' + return 'active' + } + + const status = getCouponStatus(item) + + const getBorderColor = () => { + if (status === 'active') return 'border-green-500' + if (status === 'expired') return 'border-yellow-500' + return 'border-red-500' + } + + const getBgColor = () => { + if (status === 'active') return 'bg-green-100' + if (status === 'expired') return 'bg-yellow-100' + return 'bg-red-100' + } + + const getTextColor = () => { + if (status === 'active') return 'text-green-600' + if (status === 'expired') return 'text-yellow-600' + return 'text-red-600' + } + + const getIconColor = () => { + if (status === 'active') return '#10b981' + if (status === 'expired') return '#f59e0b' + return '#ef4444' + } + + return ( +
+
+ + {item.discountPercent ? ( + + ) : ( + + )} + +
+ {item.couponCode} + ID: {item.id} +
+ + + {status === 'active' ? 'Active' : status === 'expired' ? 'Expired' : 'Inactive'} + + +
+ +
+ + Discount: {item.discountPercent ? `${item.discountPercent}% off` : item.flatDiscount ? `₹${item.flatDiscount} off` : 'N/A'} + +
+ Min Order: {item.minOrder ? `₹${item.minOrder}` : 'None'} + Max: {item.maxValue ? `₹${item.maxValue}` : 'None'} +
+ + Valid Till: {item.validTill ? new Date(item.validTill).toLocaleDateString() : 'No expiry'} + +
+ +
+ + Target: {item.isApplyForAll ? 'All Users' : item.applicableUsers?.length > 0 ? `${item.applicableUsers.length} Users` : 'All Users'} + + {item.applicableProducts && item.applicableProducts.length > 0 && ( + + Products: {item.applicableProducts.length} selected + + )} +
+ +
+ + +
+
+ ) +} + +const ReservedCouponItem = ({ item }: { item: any }) => { + const getStatus = () => { + if (item.isRedeemed) return 'redeemed' + if (item.validTill && new Date(item.validTill) <= new Date()) return 'expired' + return 'active' + } + + const status = getStatus() + + const getBorderColor = () => { + if (status === 'active') return 'border-green-500' + if (status === 'expired') return 'border-yellow-500' + return 'border-blue-500' + } + + const getBgColor = () => { + if (status === 'active') return 'bg-green-100' + if (status === 'expired') return 'bg-yellow-100' + return 'bg-blue-100' + } + + const getTextColor = () => { + if (status === 'active') return 'text-green-600' + if (status === 'expired') return 'text-yellow-600' + return 'text-blue-600' + } + + const getIconColor = () => { + if (status === 'active') return '#10b981' + if (status === 'expired') return '#f59e0b' + return '#3b82f6' + } + + return ( +
+
+ + {item.discountPercent ? ( + + ) : ( + + )} + +
+ {item.secretCode} + Coupon: {item.couponCode} +
+ + + {status === 'active' ? 'Active' : status === 'expired' ? 'Expired' : 'Redeemed'} + + +
+ +
+ + Discount: {item.discountPercent ? `${item.discountPercent}% off` : item.flatDiscount ? `₹${item.flatDiscount} off` : 'N/A'} + +
+ Min Order: {item.minOrder ? `₹${item.minOrder}` : 'None'} + Max: {item.maxValue ? `₹${item.maxValue}` : 'None'} +
+ + Valid Till: {item.validTill ? new Date(item.validTill).toLocaleDateString() : 'No expiry'} + +
+ + {item.isRedeemed && item.redeemedUser && ( +
+ + Redeemed by: {item.redeemedUser.name || 'Unknown'} ({item.redeemedUser.mobile}) + + + Redeemed on: {item.redeemedAt ? new Date(item.redeemedAt).toLocaleDateString() : 'N/A'} + +
+ )} + +
+ + Created by: {item.creator?.name || 'Unknown'} + +
+
+ ) +} + +const GeneralTab = () => { + const [refreshing, setRefreshing] = useState(false) + const [searchQuery, setSearchQuery] = useState('') + const [statusFilters, setStatusFilters] = useState([]) + const { + data, + fetchNextPage, + hasNextPage, + isLoading, + isFetchingNextPage, + error, + refetch, + } = trpc.admin.coupon.getAll.useInfiniteQuery( + { limit: 20, search: searchQuery }, + { getNextPageParam: (lastPage) => lastPage.nextCursor } + ) + + const coupons = useMemo(() => data?.pages.flatMap((page) => page.coupons) || [], [data]) + + const getCouponStatus = (coupon: any) => { + if (coupon.isInvalidated) return 'inactive' + if (coupon.validTill && new Date(coupon.validTill) <= new Date()) return 'expired' + return 'active' + } + + const filteredCoupons = useMemo(() => { + let filtered = coupons + if (statusFilters.length > 0) { + filtered = filtered.filter((coupon) => statusFilters.includes(getCouponStatus(coupon))) + } + return filtered + }, [coupons, statusFilters]) + + const handleRefresh = useCallback(async () => { + setRefreshing(true) + await refetch() + setRefreshing(false) + }, [refetch]) + + useManualRefresh(() => { refetch() }) + + useMarkDataFetchers(() => { + refetch() + }) + + const deleteCoupon = trpc.admin.coupon.delete.useMutation() + + const handleDeleteCoupon = (id: number) => { + if (!window.confirm('Delete Coupon: Are you sure you want to delete this coupon?')) return + deleteCoupon.mutate({ id }, { + onSuccess: () => { + window.alert('Success: Coupon deleted successfully') + refetch() + }, + onError: (error: any) => { + ErrorToast(error.message || 'Failed to delete coupon') + }, + }) + } + + if (isLoading) { + return ( +
+ + Loading Coupons... +
+ ) + } + + if (error) { + return ( +
+ + Failed to load coupons + refetch()} variant="red"> + Retry + +
+ ) + } + + return ( +
+
+
+ +
+ setStatusFilters(value as string[])} + multiple={true} + triggerComponent={({ onClick }: any) => ( + + )} + /> +
+ item.id.toString()} + renderItem={(item) => } + onRefresh={handleRefresh} + refreshing={refreshing} + className="px-4 pb-4" + ListFooterComponent={ +
+ {isFetchingNextPage ? ( + Loading more... + ) : hasNextPage ? ( + fetchNextPage()}> + Load more + + ) : null} +
+ } + ListEmptyComponent={ +
+ + No Coupons Found + {searchQuery ? ( + setSearchQuery('')} variant="blue" className="mt-4 bg-gray-500"> + Clear Search + + ) : null} +
+ } + /> +
+ ) +} + +const ReservedTab = () => { + const [refreshing, setRefreshing] = useState(false) + const [searchQuery, setSearchQuery] = useState('') + const [statusFilters, setStatusFilters] = useState([]) + + const { + data, + isLoading, + isFetchingNextPage, + hasNextPage, + fetchNextPage, + error, + refetch + } = trpc.admin.coupon.getReservedCoupons.useInfiniteQuery( + { limit: 20, search: searchQuery }, + { getNextPageParam: (lastPage) => lastPage.nextCursor } + ) + + const coupons = useMemo(() => data?.pages.flatMap((page) => page.coupons) || [], [data]) + + const getStatus = (coupon: any) => { + if (coupon.isRedeemed) return 'redeemed' + if (coupon.validTill && new Date(coupon.validTill) <= new Date()) return 'expired' + return 'active' + } + + const filteredCoupons = useMemo(() => { + let filtered = coupons + if (statusFilters.length > 0) { + filtered = filtered.filter((coupon) => statusFilters.includes(getStatus(coupon))) + } + return filtered + }, [coupons, statusFilters]) + + const handleRefresh = useCallback(async () => { + setRefreshing(true) + await refetch() + setRefreshing(false) + }, [refetch]) + + useManualRefresh(() => { refetch() }) + + useMarkDataFetchers(() => { + refetch() + }) + + if (isLoading) { + return ( +
+ + Loading Reserved Coupons... +
+ ) + } + + if (error) { + return ( +
+ + Failed to load reserved coupons + refetch()} variant="red"> + Retry + +
+ ) + } + + return ( +
+
+
+ +
+ setStatusFilters(value as string[])} + multiple={true} + triggerComponent={({ onClick }: any) => ( + + )} + /> +
+ item.id.toString()} + renderItem={(item) => } + onRefresh={handleRefresh} + refreshing={refreshing} + className="px-4 pb-4" + ListFooterComponent={ +
+ {isFetchingNextPage ? ( + Loading more... + ) : hasNextPage ? ( + fetchNextPage()}> + Load more + + ) : null} +
+ } + ListEmptyComponent={ +
+ + No Reserved Coupons Found + {searchQuery ? ( + setSearchQuery('')} variant="blue" className="mt-4 bg-gray-500"> + Clear Search + + ) : null} +
+ } + /> +
+ ) +} + +function Coupons() { + const location = useLocation() + const navigate = useNavigate() + const [tab, setTab] = useState<'general' | 'reserved'>('general') + + if (location.pathname !== '/dashboard/coupons') { + return + } + + return ( +
+
+ {([ + { key: 'general', title: 'General' }, + { key: 'reserved', title: 'Reserved' }, + ] as const).map((r) => ( + + ))} +
+
+ {tab === 'general' ? : } +
+ +
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.customize-app.ordering.tsx b/apps/admin-web/src/routes/dashboard.customize-app.ordering.tsx new file mode 100644 index 0000000..c153e41 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.customize-app.ordering.tsx @@ -0,0 +1,301 @@ +import React, { useState, useEffect, useCallback } from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { useQueryClient } from '@tanstack/react-query' +import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, type DragEndEvent } from '@dnd-kit/core' +import { SortableContext, useSortable, arrayMove, verticalListSortingStrategy } from '@dnd-kit/sortable' +import { CSS } from '@dnd-kit/utilities' +import { GripVertical, Image as ImageIcon, XCircle, ChevronLeft, CircleAlert, Package } from 'lucide-react' +import { AppContainer, p as MyText } from 'web-components' +import { trpc } from '@/lib/trpc-client' +import type { StoreProductCard } from '@packages/shared' +import type { DragOrderItemProps } from '@/types/drag-order-item' + +export const Route = createFileRoute('/dashboard/customize-app/ordering')({ + component: AllItemsOrder, +}) + +type Product = Pick + +const itemStyle: React.CSSProperties = { + width: '100%', + height: 60, + backgroundColor: 'white', + borderRadius: 8, + borderWidth: 1, + borderStyle: 'solid', + borderColor: '#e5e7eb', + padding: 10, + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + boxShadow: '0 1px 2px rgba(0,0,0,0.1)', + marginTop: 4, + marginBottom: 4, +} + +const activeItemStyle: React.CSSProperties = { + ...itemStyle, + borderColor: '#3b82f6', + boxShadow: '0 4px 8px rgba(59,130,246,0.3)', +} + +const ProductItem: React.FC> = ({ + item, + isActive, +}) => { + const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: item.id }) + const active = isActive || isDragging + + return ( +
+
+ +
+ + {item.images?.[0] ? ( + {item.name} + ) : ( +
+ +
+ )} + +
+ + {item.name.length > 30 ? item.name.substring(0, 30) + '...' : item.name} + + + {item.isOutOfStock && ( + + )} +
+
+ ) +} + +function AllItemsOrder() { + const queryClient = useQueryClient() + const [products, setProducts] = useState([]) + const [hasChanges, setHasChanges] = useState(false) + + const { data: constants, isLoading: isLoadingConstants, error: constantsError } = trpc.admin.const.getConstants.useQuery() + const { data: allProducts, isLoading: isLoadingProducts, error: productsError } = trpc.common.product.getAllProductsSummary.useQuery() + const updateConstants = trpc.admin.const.updateConstants.useMutation() + + const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } })) + + useEffect(() => { + if (allProducts?.products) { + const allItemsOrderConstant = constants?.find((c) => c.key === 'allItemsOrder') + + let orderedIds: number[] = [] + + if (allItemsOrderConstant) { + const value = allItemsOrderConstant.value + + if (Array.isArray(value)) { + orderedIds = value.map((id: any) => parseInt(id)) + } else if (typeof value === 'string') { + orderedIds = value.split(',').map((id: string) => parseInt(id.trim())).filter((id) => !isNaN(id)) + } + } + + const productMap = new Map(allProducts.products.map((p) => [p.id, p])) + + const sortedProducts: Product[] = [] + + for (const id of orderedIds) { + const product = productMap.get(id) + if (product) { + sortedProducts.push({ + id: product.id, + name: product.name, + images: product.images || [], + isOutOfStock: product.isOutOfStock || false, + }) + productMap.delete(id) + } + } + + for (const product of productMap.values()) { + sortedProducts.push({ + id: product.id, + name: product.name, + images: product.images || [], + isOutOfStock: product.isOutOfStock || false, + }) + } + + setProducts(sortedProducts) + } + }, [constants, allProducts]) + + const handleDragEnd = useCallback((event: DragEndEvent) => { + const { active, over } = event + if (over && active.id !== over.id) { + setProducts((prev) => { + const oldIndex = prev.findIndex((p) => p.id === active.id) + const newIndex = prev.findIndex((p) => p.id === over.id) + return arrayMove(prev, oldIndex, newIndex) + }) + setHasChanges(true) + } + }, []) + + const handleSave = () => { + const productIds = products.map((p) => p.id) + + updateConstants.mutate( + { + constants: [{ + key: 'allItemsOrder', + value: productIds, + }], + }, + { + onSuccess: () => { + setHasChanges(false) + window.alert('All items order updated successfully!') + queryClient.invalidateQueries({ queryKey: ['const.getConstants'] }) + }, + onError: (error) => { + window.alert('Failed to update items order. Please try again.') + console.error('Update all items order error:', error) + }, + } + ) + } + + if (isLoadingConstants || isLoadingProducts) { + return ( + +
+
+ + All Items Order +
+
+
+
+ + {isLoadingConstants ? 'Loading order...' : 'Loading products...'} + +
+
+ + ) + } + + if (constantsError || productsError) { + return ( + +
+
+ + All Items Order +
+
+
+ + Error + + {constantsError ? 'Failed to load order' : 'Failed to load products'} + + +
+
+ + ) + } + + return ( +
+
+ + + All Items Order + + +
+ + {products.length === 0 ? ( +
+ + + No products available + +
+ ) : ( +
+
+ + Long press and drag to reorder • {products.length} items + +
+ +
+ + p.id)} strategy={verticalListSortingStrategy}> + {products.map((product) => ( + {}} isActive={false} /> + ))} + + +
+
+ )} +
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.customize-app.popular.tsx b/apps/admin-web/src/routes/dashboard.customize-app.popular.tsx new file mode 100644 index 0000000..0d4cad8 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.customize-app.popular.tsx @@ -0,0 +1,413 @@ +import React, { useState, useEffect } from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { useQueryClient } from '@tanstack/react-query' +import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, type DragEndEvent } from '@dnd-kit/core' +import { SortableContext, useSortable, arrayMove, verticalListSortingStrategy } from '@dnd-kit/sortable' +import { CSS } from '@dnd-kit/utilities' +import { GripVertical, Image as ImageIcon, Trash2, ChevronLeft, CircleAlert, Package, Plus } from 'lucide-react' +import { AppContainer, p as MyText, BottomDialog } from 'web-components' +import ProductsSelector from '../components/ProductsSelector' +import { trpc } from '@/lib/trpc-client' +import type { StoreProductCard } from '@packages/shared' +import type { DragOrderItemProps } from '@/types/drag-order-item' + +export const Route = createFileRoute('/dashboard/customize-app/popular')({ + component: CustomizePopularItems, +}) + +type PopularProduct = Omit< + StoreProductCard, + 'price' | 'marketPrice' | 'unitNotation' | 'images' +> & { + price: number + marketPrice: number | null + images: string[] | null + storeId: number | null + nextDeliveryDate: string | null +} + +interface ProductItemProps extends DragOrderItemProps { + onDelete: (id: number) => void +} + +const ProductItem: React.FC = ({ + item, + isActive, + onDelete, +}) => { + const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: item.id }) + const active = isActive || isDragging + + return ( +
+
+
+
+ +
+ + {item.images?.[0] ? ( + {item.name} + ) : ( +
+ +
+ )} + +
+ + {item.name} + + + ₹{item.price} + +
+ + +
+
+
+ ) +} + +function CustomizePopularItems() { + const queryClient = useQueryClient() + const [popularProducts, setPopularProducts] = useState([]) + const [hasChanges, setHasChanges] = useState(false) + const [showAddDialog, setShowAddDialog] = useState(false) + const [selectedProductIds, setSelectedProductIds] = useState([]) + + const { data: constants, isLoading: isLoadingConstants, error: constantsError } = trpc.admin.const.getConstants.useQuery() + const { data: allProducts, isLoading: isLoadingProducts, error: productsError } = trpc.common.product.getAllProductsSummary.useQuery() + const updateConstants = trpc.admin.const.updateConstants.useMutation() + + const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } })) + + useEffect(() => { + if (constants && allProducts?.products) { + const popularItemsConstant = constants.find((c) => c.key === 'popularItems') + + let popularIds: number[] = [] + + if (popularItemsConstant) { + const value = popularItemsConstant.value + + if (Array.isArray(value)) { + popularIds = value.map((id: any) => parseInt(id)) + } else if (typeof value === 'string') { + popularIds = value.split(',').map((id: string) => parseInt(id.trim())).filter((id) => !isNaN(id)) + } + + const popularProds: PopularProduct[] = [] + + for (const id of popularIds) { + const product = allProducts.products.find((p) => p.id === id) + if (product) { + popularProds.push(product as PopularProduct) + } + } + + setPopularProducts(popularProds) + } + } + }, [constants, allProducts]) + + const handleDragEnd = (event: DragEndEvent) => { + const { active, over } = event + if (over && active.id !== over.id) { + setPopularProducts((prev) => { + const oldIndex = prev.findIndex((p) => p.id === active.id) + const newIndex = prev.findIndex((p) => p.id === over.id) + return arrayMove(prev, oldIndex, newIndex) + }) + setHasChanges(true) + } + } + + const handleDelete = (productId: number) => { + if (window.confirm('Are you sure you want to remove this product from popular items?')) { + setPopularProducts((prev) => prev.filter((p) => p.id !== productId)) + setHasChanges(true) + } + } + + const handleAddProduct = () => { + if (selectedProductIds.length > 0) { + const newProducts = selectedProductIds + .map((id) => allProducts?.products.find((p) => p.id === id)) + .filter((product): product is NonNullable => + product !== undefined && !popularProducts.find((p) => p.id === product.id) + ) + + if (newProducts.length > 0) { + setPopularProducts((prev) => [...prev, ...newProducts as PopularProduct[]]) + setHasChanges(true) + } + + setSelectedProductIds([]) + setShowAddDialog(false) + } + } + + const handleSave = () => { + const popularIds = popularProducts.map((p) => p.id) + + updateConstants.mutate( + { + constants: [{ + key: 'popularItems', + value: popularIds, + }], + }, + { + onSuccess: () => { + setHasChanges(false) + window.alert('Popular items updated successfully!') + queryClient.invalidateQueries({ queryKey: ['const.getConstants'] }) + }, + onError: (error) => { + window.alert('Failed to update popular items. Please try again.') + console.error('Update popular items error:', error) + }, + } + ) + } + + const availableProducts = (allProducts?.products || []).filter( + (product) => !popularProducts.find((p) => p.id === product.id) + ) + + if (isLoadingConstants || isLoadingProducts) { + return ( + +
+
+ + + Popular Items + +
+
+ +
+
+ + {isLoadingConstants ? 'Loading constants...' : 'Loading products...'} + +
+
+ + ) + } + + if (constantsError || productsError) { + return ( + +
+
+ + + Popular Items + +
+
+ +
+ + Error + + {constantsError ? 'Failed to load constants' : 'Failed to load products'} + + +
+
+ + ) + } + + return ( +
+
+ + + Popular Items + + +
+ + {popularProducts.length === 0 ? ( +
+ + + No popular items configured + + + Add products to display as popular items + +
+ ) : ( +
+
+ + Long press an item to drag and reorder + +
+ + + p.id)} strategy={verticalListSortingStrategy}> + {popularProducts.map((product) => ( + {}} + isActive={false} + onDelete={handleDelete} + /> + ))} + + +
+ )} + +
+ +
+ + { + setShowAddDialog(false) + setSelectedProductIds([]) + }} + > +
+
+
+ + Add Popular Items + + + Select products to add to popular items + +
+ + {availableProducts.length === 0 ? ( +
+ + + All products are already in popular items + +
+ ) : ( + <> + setSelectedProductIds(val as number[])} + multiple={true} + label="Select Products" + placeholder="Choose products..." + labelFormat={(product) => `${product.productName} - ₹${product.price}`} + /> + +
+ + + +
+ + )} +
+ +
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.customize-app.tsx b/apps/admin-web/src/routes/dashboard.customize-app.tsx new file mode 100644 index 0000000..ef9a36b --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.customize-app.tsx @@ -0,0 +1,271 @@ +import React from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { Formik } from 'formik' +import { Pencil, ChevronRight, ArrowDownUp } from 'lucide-react' +import { p as MyText, pInput as MyTextInput, AppContainer, Checkbox } from 'web-components' +import { trpc } from '@/lib/trpc-client' + +export const Route = createFileRoute('/dashboard/customize-app')({ + component: CustomizeApp, +}) + +type ConstantFormData = Record + +const CONST_LABELS: Record = { + minRegularOrderValue: 'Minimum Regular Order Value', + freeDeliveryThreshold: 'Free Delivery Threshold', + deliveryCharge: 'Delivery Charge', + flashFreeDeliveryThreshold: 'Flash Free Delivery Threshold', + flashDeliveryCharge: 'Flash Delivery Charge', + platformFeePercent: 'Platform Fee Percent', + taxRate: 'Tax Rate', + minOrderAmountForCoupon: 'Minimum Order Amount for Coupon', + maxCouponDiscount: 'Maximum Coupon Discount', + flashDeliverySlotId: 'Flash Delivery Slot ID', + readableOrderId: 'Readable Order ID', + versionNum: 'Version Number', + playStoreUrl: 'Play Store URL', + appStoreUrl: 'App Store URL', + popularItems: 'Popular Items', + allItemsOrder: 'All Items Order', + isFlashDeliveryEnabled: 'Enable Flash Delivery', + supportMobile: 'Support Mobile', + supportEmail: 'Support Email', +} + +const CONST_VISIBILITY: Record = { + minRegularOrderValue: true, + freeDeliveryThreshold: true, + deliveryCharge: true, + flashFreeDeliveryThreshold: true, + flashDeliveryCharge: true, + platformFeePercent: true, + taxRate: false, + minOrderAmountForCoupon: true, + maxCouponDiscount: false, + flashDeliverySlotId: true, + readableOrderId: false, + versionNum: true, + playStoreUrl: true, + appStoreUrl: true, + popularItems: true, + allItemsOrder: true, + isFlashDeliveryEnabled: true, + supportMobile: true, + supportEmail: true, + tester: false, +} + +interface ConstantInputProps { + constantKey: string + value: any + setFieldValue: (field: string, value: any) => void + router: any +} + +const ConstantInput: React.FC = ({ constantKey, value, setFieldValue, router }) => { + const fieldName = constantKey + + if (constantKey === 'popularItems') { + return ( +
+ + {CONST_LABELS[constantKey] || constantKey} + + +
+ ) + } + + if (constantKey === 'allItemsOrder') { + return ( +
+ + {CONST_LABELS[constantKey] || constantKey} + + +
+ ) + } + + if (typeof value === 'boolean') { + return ( +
+ + {CONST_LABELS[constantKey] || constantKey} + +
+ setFieldValue(fieldName, !value)} + size={28} + /> + + {value ? 'Enabled' : 'Disabled'} + +
+
+ ) + } + + if (typeof value === 'number') { + return ( + { + const numValue = parseFloat(e.target.value) + setFieldValue(fieldName, isNaN(numValue) ? 0 : numValue) + }} + type="number" + placeholder="Enter number" + /> + ) + } + + if (Array.isArray(value)) { + return ( + { + const arrayValue = e.target.value.split(',').map((s) => s.trim()).filter((s) => s.length > 0) + setFieldValue(fieldName, arrayValue) + }} + placeholder="Enter comma separated values" + /> + ) + } + + return ( + { + setFieldValue(fieldName, e.target.value) + }} + placeholder="Enter value" + /> + ) +} + +function CustomizeApp() { + const navigate = useNavigate() + const router = { + push: (to: string) => navigate({ to: to as any }), + } + const { data: constants, isLoading: isLoadingConstants, refetch } = trpc.admin.const.getConstants.useQuery() + const { mutate: updateConstants, isPending: isUpdating } = trpc.admin.const.updateConstants.useMutation() + + const handleSubmit = (values: ConstantFormData) => { + const changedConstants = (constants || []).filter((constant) => { + const nextValue = values[constant.key] + return JSON.stringify(nextValue) !== JSON.stringify(constant.value) + }).map((constant) => ({ + key: constant.key, + value: values[constant.key], + })) + + if (changedConstants.length === 0) { + window.alert('No constants were modified.') + return + } + + updateConstants( + { constants: changedConstants }, + { + onSuccess: (response) => { + window.alert(`Updated ${response.updatedCount} constants successfully.`) + refetch() + }, + onError: (error) => { + window.alert('Failed to update constants. Please try again.') + console.error('Update constants error:', error) + }, + } + ) + } + + if (isLoadingConstants) { + return ( +
+ Loading constants... +
+ ) + } + + if (!constants) { + return ( +
+ Failed to load constants +
+ ) + } + + const initialValues: ConstantFormData = constants.reduce((acc, constant) => { + acc[constant.key] = constant.value ?? '' + return acc + }, {} as ConstantFormData) + + return ( + +
+ Customize App Constants + + Modify application constants. Changes will take effect immediately. + + + + {({ handleSubmit, values, setFieldValue }) => ( +
+ {constants.map((constant) => { + if (!CONST_VISIBILITY[constant.key]) { + return null + } + + return ( +
+ +
+ ) + })} + + +
+ )} +
+
+
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.index.tsx b/apps/admin-web/src/routes/dashboard.index.tsx new file mode 100644 index 0000000..a5c1535 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.index.tsx @@ -0,0 +1,305 @@ +import React from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { + ShoppingBag, + Route as RouteIcon, + CalendarClock, + CirclePlus, + TriangleAlert, + Package, + DollarSign, + Tag, + Shapes, + Store, + TicketPercent, + Settings, + Users, + Megaphone, + ReceiptText, + ChevronRight, +} from 'lucide-react' +import { p as MyText } from 'web-components' +import { trpc } from '../lib/trpc-client' +import { useNavigationTarget } from '../lib/navigation-target' +import { theme } from '../lib/theme' + +export const Route = createFileRoute('/dashboard/')({ + component: Dashboard, +}) + +interface MenuItem { + title: string + icon: React.ReactNode + description?: string + route: string + category: 'quick' | 'products' | 'orders' | 'marketing' | 'settings' | 'users' + iconColor?: string + iconBg?: string + badgeCount?: number + onPress?: () => void + testID?: string +} + +const MenuItemComponent: React.FC<{ item: MenuItem; go: (item: MenuItem) => void }> = ({ + item, + go, +}) => { + return ( + + ) +} + +function Dashboard() { + const navigate = useNavigate() + const { setNavigationTarget } = useNavigationTarget() + + const { data: essentialsData } = trpc.admin.user.getEssentials.useQuery() + + const go = (item: MenuItem) => { + if (item.onPress) { + item.onPress() + } else { + navigate({ to: item.route as any }) + } + } + + const handleManageOrdersPress = () => { + setNavigationTarget('/dashboard/orders/list') + navigate({ to: '/dashboard/orders' }) + } + + const handleDeliverySequencesPress = () => { + setNavigationTarget('/dashboard/orders/sequence') + navigate({ to: '/dashboard/orders' }) + } + + const menuItems: MenuItem[] = [ + { + title: 'Manage Orders', + icon: , + description: 'View and manage customer orders', + route: '/dashboard/orders', + category: 'orders', + iconColor: '#10B981', + iconBg: '#D1FAE5', + onPress: handleManageOrdersPress, + }, + { + title: 'Delivery Sequences', + icon: , + description: 'Plan and optimize delivery routes', + route: '/dashboard/orders/sequence', + category: 'orders', + iconColor: '#8B5CF6', + iconBg: '#EDE9FE', + onPress: handleDeliverySequencesPress, + }, + { + title: 'Delivery Slots', + icon: , + description: 'Configure delivery times', + route: '/dashboard/slots', + category: 'quick', + iconColor: '#06B6D4', + iconBg: '#CFFAFE', + testID: 'delivery-slots-menu-item', + }, + { + title: 'Add Product', + icon: , + description: 'Create a new product listing', + route: '/dashboard/products/new', + category: 'quick', + iconColor: theme.colors.brand500, + iconBg: theme.colors.brand50, + }, + { + title: 'Complaints', + icon: , + description: 'Handle customer complaints', + route: '/dashboard/complaints', + category: 'quick', + iconColor: '#F59E0B', + iconBg: '#FEF3C7', + badgeCount: essentialsData?.unresolvedComplaints, + }, + { + title: 'Products', + icon: , + description: 'Manage product catalog', + route: '/dashboard/products', + category: 'products', + iconColor: '#6366F1', + iconBg: '#E0E7FF', + }, + { + title: 'Prices Overview', + icon: , + description: 'Update product pricing', + route: '/dashboard/prices', + category: 'products', + iconColor: '#059669', + iconBg: '#ECFDF5', + }, + { + title: 'Product Tags', + icon: , + description: 'Organize with tags', + route: '/dashboard/product-tags', + category: 'products', + iconColor: '#EC4899', + iconBg: '#FCE7F3', + }, + { + title: 'Product Groupings', + icon: , + description: 'Group products together', + route: '/dashboard/product-groupings', + category: 'products', + iconColor: '#8B5CF6', + iconBg: '#F3E8FF', + }, + { + title: 'Stores', + icon: , + description: 'Manage store locations', + route: '/dashboard/stores', + category: 'settings', + iconColor: '#14B8A6', + iconBg: '#CCFBF1', + }, + { + title: 'Coupons', + icon: , + description: 'Create discount coupons', + route: '/dashboard/coupons', + category: 'marketing', + iconColor: '#F97316', + iconBg: '#FFEDD5', + }, + { + title: 'App Constants', + icon: , + description: 'Customize app settings', + route: '/dashboard/customize-app', + category: 'settings', + iconColor: '#7C3AED', + iconBg: '#F3E8FF', + }, + { + title: 'User Management', + icon: , + description: 'View and manage all users', + route: '/dashboard/users', + category: 'users', + iconColor: '#0EA5E9', + iconBg: '#E0F2FE', + }, + { + title: 'Send Notifications', + icon: , + description: 'Send push notifications to users', + route: '/dashboard/notifications', + category: 'users', + iconColor: '#8B5CF6', + iconBg: '#F3E8FF', + }, + ] + + const quickActions = menuItems.filter((item) => item.category === 'quick') + + const categories = [ + { key: 'orders', title: 'Orders', icon: }, + { + key: 'products', + title: 'Products & Inventory', + icon: , + }, + { + key: 'marketing', + title: 'Marketing & Promotions', + icon: , + }, + { key: 'users', title: 'User Management', icon: }, + { + key: 'settings', + title: 'Settings & Configuration', + icon: , + }, + ] + + return ( +
+ {/* Quick Actions */} +
+ Quick Actions +
+ {quickActions.map((item) => ( + + ))} +
+
+ + {/* Categorized Menu Items */} +
+ {categories.map((category) => { + const categoryItems = menuItems.filter((item) => item.category === category.key) + if (categoryItems.length === 0) return null + + return ( +
+
+ + {category.icon} + + {category.title} +
+ {categoryItems.map((item) => ( + + ))} +
+ ) + })} +
+
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.notifications.tsx b/apps/admin-web/src/routes/dashboard.notifications.tsx new file mode 100644 index 0000000..4193039 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.notifications.tsx @@ -0,0 +1,168 @@ +import React, { useState } from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { ChevronLeft } from 'lucide-react' +import { AppContainer, p as MyText, pInput as MyTextInput } from 'web-components' +import { trpc } from '@/lib/trpc-client' +import type { UserMiniInfo } from '@packages/shared' +import { MultiSelect } from '../components/MultiSelect' + +export const Route = createFileRoute('/dashboard/notifications')({ + component: SendNotifications, +}) + +type User = Omit & { + name: string | null + isEligibleForNotif: boolean +} + +function SendNotifications() { + const [selectedUserIds, setSelectedUserIds] = useState([]) + const [title, setTitle] = useState('') + const [message, setMessage] = useState('') + const [searchQuery, setSearchQuery] = useState('') + + const { data: usersData, isLoading: isLoadingUsers } = trpc.admin.user.getUsersForNotification.useQuery({ + search: searchQuery, + }) + + const sendNotification = trpc.admin.user.sendNotification.useMutation({ + onSuccess: () => { + window.alert('Success: Notification sent successfully!') + setSelectedUserIds([]) + setTitle('') + setMessage('') + }, + onError: (error: any) => { + window.alert(`Error: ${error.message || 'Failed to send notification'}`) + }, + }) + + const eligibleUsers = usersData?.users.filter((u: User) => u.isEligibleForNotif) || [] + + const dropdownOptions = eligibleUsers.map((user: User) => ({ + label: `${user.mobile || 'No Mobile'}${user.name ? ` - ${user.name}` : ''}`, + value: user.id, + })) + + const handleSend = async () => { + if (title.trim().length === 0) { + window.alert('Error: Please enter a title') + return + } + + if (message.trim().length === 0) { + window.alert('Error: Please enter a message') + return + } + + const isSendingToAll = selectedUserIds.length === 0 + if (isSendingToAll) { + const confirmed = window.confirm( + 'Send to All Users? This will send the notification to all users with push tokens. Continue?' + ) + if (!confirmed) return + } + + try { + await sendNotification.mutateAsync({ + userIds: selectedUserIds, + title: title.trim(), + text: message.trim(), + }) + } catch (error: any) { + window.alert(`Error: ${error.message || 'Failed to send notification'}`) + } + } + + const getDisplayText = () => { + if (selectedUserIds.length === 0) return 'All Users' + if (selectedUserIds.length === 1) { + const user = eligibleUsers.find((u: User) => u.id === selectedUserIds[0]) + return user ? `${user.mobile}${user.name ? ` - ${user.name}` : ''}` : '1 user selected' + } + return `${selectedUserIds.length} users selected` + } + + if (isLoadingUsers) { + return ( + +
+
+ Loading users... +
+ + ) + } + + const isSendDisabled = sendNotification.isPending || title.trim().length === 0 || message.trim().length === 0 + + return ( + +
+
+ + Send Notifications +
+ +
+
+ Title + setTitle(e.target.value)} + placeholder="Enter notification title..." + className="text-gray-900" + /> +
+ +
+ Message + setMessage(e.target.value)} + placeholder="Enter notification message..." + multiline + numberOfLines={4} + className="text-gray-900" + /> +
+ +
+ Select Users (Optional) + setSelectedUserIds(value as number[])} + onSearch={(query: string) => setSearchQuery(query)} + /> + + {getDisplayText()} + + + Leave empty to send to all users + +
+ + +
+
+
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.orders.$id.tsx b/apps/admin-web/src/routes/dashboard.orders.$id.tsx new file mode 100644 index 0000000..2f02e01 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.orders.$id.tsx @@ -0,0 +1,824 @@ +import React, { useState } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { AppContainer, p as MyText, BottomDialog, pInput as MyInput } from 'web-components' +import { trpc } from '@/lib/trpc-client' +import { ErrorToast } from '@/services/toaster' +import { theme } from '@/lib/theme' +import { + Clock, + Zap, + CircleAlert, + Check, + Package, + Truck, + ChevronRight, + User, + Phone, + Mail, + MapPin, + CircleX, + TicketPercent, + StickyNote, + Info, + Percent, + Banknote +} from 'lucide-react' +import dayjs from 'dayjs' +import CancelOrderDialog from '../components/CancelOrderDialog' +import { UserIncidentsView } from '../components/UserIncidentsView' + +export const Route = createFileRoute('/dashboard/orders/$id')({ + component: OrderDetails, +}) + +function OrderDetails() { + const { id } = Route.useParams() + const navigate = useNavigate() + const [generateCouponDialogOpen, setGenerateCouponDialogOpen] = + useState(false) + const [initiateRefundDialogOpen, setInitiateRefundDialogOpen] = + useState(false) + const [cancelDialogOpen, setCancelDialogOpen] = useState(false) + const [refundType, setRefundType] = useState<'percent' | 'amount'>('percent') + const [refundValue, setRefundValue] = useState('100') + const [updatingItems, setUpdatingItems] = useState>(new Set()) + + const { + data: orderData, + isLoading, + error, + refetch, + } = trpc.admin.order.getOrderDetails.useQuery( + { orderId: id ? parseInt(id) : 0 }, + { enabled: !!id } + ) + + const generateCouponMutation = + trpc.admin.coupon.generateCancellationCoupon.useMutation({ + onSuccess: (coupon) => { + window.alert( + `Success: Refund coupon generated successfully!\n\nCode: ${coupon.couponCode + }\nValue: ₹${coupon.flatDiscount}\nExpires: ${coupon.validTill + ? new Date(coupon.validTill).toLocaleDateString() + : 'N/A' + }` + ) + setGenerateCouponDialogOpen(false) + }, + onError: (error: any) => { + ErrorToast( + error.message || 'Failed to generate refund coupon' + ) + }, + }) + + const initiateRefundMutation = trpc.admin.payments.initiateRefund.useMutation( + { + onSuccess: () => { + window.alert( + 'Success: Refund initiated successfully!\n\nAmount: ' + // `Refund initiated successfully!\n\nAmount: ₹${result.amount}\nStatus: ${result.status}` + ) + setInitiateRefundDialogOpen(false) + }, + onError: (error: any) => { + ErrorToast(error.message || 'Failed to initiate refund') + }, + } + ) + + const updateItemPackagingMutation = trpc.admin.order.updateOrderItemPackaging.useMutation({ + onSuccess: () => { + // Refetch order details to get updated packaging status + refetch() + }, + onError: (error: any) => { + ErrorToast(error.message || 'Failed to update packaging status') + }, + }) + + const removeDeliveryChargeMutation = trpc.admin.order.removeDeliveryCharge.useMutation({ + onSuccess: () => { + window.alert('Success: Delivery charge has been removed') + refetch() + }, + onError: (error: any) => { + ErrorToast(error.message || 'Failed to remove delivery charge') + }, + }) + + if (isLoading) { + return ( +
+ + Loading order details... + +
+ ) + } + + if (error || !orderData) { + return ( +
+
+ + + Oops! + + + {error?.message || 'Failed to load order details'} + + +
+
+ ) + } + + const order = orderData + + // Calculate subtotal and discount for order summary + const subtotal = order.items.reduce((sum, item) => sum + item.amount, 0) + const discountAmount = order.discountAmount || 0 + + const handleGenerateCoupon = () => { + generateCouponMutation.mutate({ orderId: order.id }) + } + + const handleInitiateRefund = () => { + const value = parseFloat(refundValue) + if (isNaN(value) || value <= 0) { + ErrorToast('Please enter a valid refund value') + return + } + + const mutationData: any = { + orderId: order.id, + } + + if (refundType === 'percent') { + if (value > 100) { + ErrorToast('Refund percentage cannot exceed 100%') + return + } + mutationData.refundPercent = value + } else { + mutationData.refundAmount = value + } + + initiateRefundMutation.mutate(mutationData) + setInitiateRefundDialogOpen(false) + } + + const handlePackagingToggle = (itemId: number, field: 'isPackaged' | 'isPackageVerified', value: boolean) => { + // Add item to updating set to disable UI + setUpdatingItems((prev) => new Set(prev).add(itemId)) + + updateItemPackagingMutation.mutate( + { + orderItemId: itemId, + [field]: value, + }, + { + onSettled: () => { + // Remove item from updating set + setUpdatingItems((prev) => { + const newSet = new Set(prev) + newSet.delete(itemId) + return newSet + }) + }, + } + ) + } + + const getStatusColor = (status: string) => { + switch (status) { + case 'delivered': + return 'text-green-600 bg-green-50 border-green-100' + case 'cancelled': + return 'text-red-600 bg-red-50 border-red-100' + default: + return 'text-yellow-600 bg-yellow-50 border-yellow-100' + } + } + + const statusStyle = getStatusColor(order.status) + + return ( + + +
+ {/* Order ID & Status Card */} +
+
+
+ Order ID + + #{order.readableId} + +
+
+ + + {order.status} + + + {order.isFlashDelivery && ( + + + + )} +
+
+ +
+ + + {order.isFlashDelivery ? '1 Hr Delivery:' : 'Delivery at:'} {order.isFlashDelivery + ? dayjs(order.createdAt).add(30, 'minutes').format('MMM DD, YYYY • h:mm A') + : order.slotInfo?.time ? dayjs(order.slotInfo.time).format('MMM DD, YYYY • h:mm A') : 'Not scheduled'} + +
+ {order.isFlashDelivery && ( +
+ + + ⚡ 1 Hr Delivery • High Priority + +
+ )} +
+ + + Placed on {dayjs(order.createdAt).format('MMM DD, YYYY • h:mm A')} + +
+
+ + {/* Cancellation Reason */} + {order.status === 'cancelled' && order.cancelReason && ( +
+
+ + + Cancellation Reason + +
+ + {order.cancelReason} + +
+ )} + + {/* Order Progress (Simplified Timeline) */} + {order.status !== 'cancelled' && ( +
+ + Order Status + +
+ {/* Placed */} +
+ + + + + Placed + +
+
+ + {/* Packaged */} +
+ + + + + Packaged + +
+
+ + {/* Delivered */} +
+ + {order.isFlashDelivery && order.isDelivered ? ( + + ) : ( + + )} + +
+ + {order.isFlashDelivery && order.isDelivered ? 'Flash Delivered' : 'Delivered'} + + {order.isFlashDelivery && ( + + ⚡ 30-Min + + )} +
+
+
+
+ )} + + {/* Customer Details */} + + + {/* Order Items */} +
+ + Items Ordered + + {order.items.map((item, index) => ( +
+ + + +
+ + {item.name} + + + {Number(item.quantity)} x {item.unit} × ₹{item.price} + +
+ + +
+
+ + ₹{item.amount} + +
+ ))} + +
+
+ + Subtotal ({order.items.length} items) + + + ₹{subtotal} + +
+ {discountAmount > 0 && ( +
+ + Discount + + + -₹{discountAmount} + +
+ )} + {order.deliveryCharge > 0 && ( +
+
+ + Delivery Charge + + +
+ + ₹{order.deliveryCharge} + +
+ )} +
+
+ + Total Amount + + {order.isFlashDelivery && ( + + ⚡ FLASH + + )} +
+ + ₹{order.totalAmount} + +
+
+
+ + {/* 1 Hr Delivery Priority Notice */} + {order.isFlashDelivery && ( +
+
+ + + 1 Hr Delivery Order + +
+ + ⚡ This is a high-priority flash delivery order that must be delivered within 1 hr of placement. + +
+ + Expected Delivery: {dayjs(order.createdAt).add(30, 'minutes').format('MMM DD, YYYY • h:mm A')} + +
+
+ )} + + {/* Admin Notes */} + {order.adminNotes && ( +
+
+ + + Admin Notes + +
+ + {order.adminNotes} + +
+ )} + + {/* User Incidents Section */} + {order.userId && ( + + )} + + {/* Coupon Applied Section */} + {order.couponCode && ( +
+ + Coupon Applied + +
+
+ + + {order.couponCode} + +
+ + {order.couponDescription} + +
+ + Discount Applied: + + + -₹{order.discountAmount} + +
+
+
+ )} + + {/* Refund Coupon Section */} + {order.orderStatus?.refundCouponId && ( +
+ + Refund Coupon + +
+
+ + + {order.couponCode} + +
+ + Generated refund coupon for order cancellation + +
+ + Value: + + + ₹{order.couponData?.discountAmount} + +
+
+
+ )} + + {/* TEMPORARILY HIDDEN: Refund Details Section */} + {/* WARNING: This section contains functional refund and cancellation management features */} + {/* DO NOT REMOVE - This is temporarily commented out for UI simplification */} + {/* When ready to re-enable, simply uncomment the entire block below */} +
+
+ + {/* Bottom Action Bar */} +
+ {order.status !== 'cancelled' && ( + + )} + +
+ + {/* Generate Coupon Dialog */} + setGenerateCouponDialogOpen(false)} + > +
+
+ + + + + Generate Refund Coupon + + + Create a one-time use coupon for the customer equal to the order amount. Valid for 30 days. + +
+ +
+ + + This only works for online payment orders. COD orders cannot generate refund coupons. + +
+ +
+ + +
+
+
+ + {/* Initiate Refund Dialog */} + setInitiateRefundDialogOpen(false)} + > +
+
+ + + + + Initiate Refund + + + Process a refund directly to the customer's source account via Razorpay. + +
+ + {/* Refund Type Selection */} +
+ + Refund Type + +
+ + + +
+
+ + {/* Refund Value Input */} +
+ setRefundValue(e.target.value)} + type="number" + placeholder={refundType === 'percent' ? '100' : '0.00'} + className="bg-white" + /> +
+ +
+ + + For COD orders, refunds are processed immediately upon delivery confirmation. + +
+ +
+ + +
+
+
+ + {/* Cancel Order Dialog */} + setCancelDialogOpen(false)} + onSuccess={refetch} + /> + + ) +} diff --git a/apps/admin-web/src/routes/dashboard.orders.list.tsx b/apps/admin-web/src/routes/dashboard.orders.list.tsx new file mode 100644 index 0000000..0c1076b --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.orders.list.tsx @@ -0,0 +1,818 @@ +import React, { useState, useEffect } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { + p as MyText, + pInput as MyInput, + MyButton, + AppContainer, + BottomDialog, + Checkbox, + Dropdown, + SearchBar, + MyFlatList +} from 'web-components' +import { trpc } from '@/lib/trpc-client' +import { ErrorToast } from '@/services/toaster' +import dayjs from 'dayjs' +import { + Zap, + Clock, + TriangleAlert, + MapPin, + CalendarDays, + ShoppingCart, + StickyNote, + ShieldCheck, + EllipsisVertical, + ListFilter, + Loader2 +} from 'lucide-react' +import CancelOrderDialog from '../components/CancelOrderDialog' +import { OrderOptionsMenu } from '../components/OrderOptionsMenu' +import type { AdminOrderListItem, AdminOrderListItemProduct } from '@packages/shared' + +export const Route = createFileRoute('/dashboard/orders/list')({ + validateSearch: (s: Record) => ({ + filter: (s.filter as string) ?? '', + slotId: (s.slotId as string) ?? '' + }), + component: Orders, +}) + +const AdminNotesForm = ({ orderId, existingNotes, onClose, refetch }: { orderId: string, existingNotes?: string | null, onClose: () => void, refetch: () => void }) => { + const [notesText, setNotesText] = useState(existingNotes || '') + const updateNotesMutation = trpc.admin.order.updateNotes.useMutation() + + return ( +
+ Admin Notes + setNotesText(e.target.value)} + placeholder="Enter admin notes..." + className="min-h-24" + /> +
+ { + updateNotesMutation.mutate( + { orderId: parseInt(orderId), adminNotes: notesText }, + { + onSuccess: () => { + onClose() + window.alert('Success: Notes updated successfully') + refetch() + }, + onError: (error: any) => { + ErrorToast(error.message || 'Failed to update notes') + }, + } + ) + }} + > + Save + +
+
+ ) +} + +// Order list row — derived from shared AdminOrderListItem (serialized dates, +// coupon display fields, optional flags) +type OrderItemRow = Omit< + AdminOrderListItemProduct, + 'id' | 'skuName' | 'features' | 'isPackaged' | 'isPackageVerified' +> & { + id?: number, + isPackaged?: boolean, + isPackageVerified?: boolean +} + +type OrderType = Omit< + AdminOrderListItem, + 'customerName' | 'customerMobile' | 'items' | 'createdAt' | 'adminNotes' | 'userNotes' | 'userNegativityScore' +> & { + customerName: string | null, + customerMobile?: string | null, + items: OrderItemRow[], + createdAt: string, + adminNotes?: string | null, + userNotes?: string | null, + userNegativityScore?: number, + couponCode?: string, + couponDescription?: string, + discountAmount?: number +} + +const OrderItem = ({ order, refetch }: { order: OrderType, refetch: () => void }) => { + const navigate = useNavigate() + const [menuOpen, setMenuOpen] = useState(false) + const [itemsDialogOpen, setItemsDialogOpen] = useState(false) + const [notesDialogOpen, setNotesDialogOpen] = useState(false) + const [cancelDialogOpen, setCancelDialogOpen] = useState(false) + const [userNotesDialogOpen, setUserNotesDialogOpen] = useState(false) + const [adminNotesDialogOpen, setAdminNotesDialogOpen] = useState(false) + const [updatingItems, setUpdatingItems] = useState>(new Set()) + + const updatePackagedMutation = trpc.admin.order.updatePackaged.useMutation() + const updateDeliveredMutation = trpc.admin.order.updateDelivered.useMutation() + const updateItemPackagingMutation = trpc.admin.order.updateOrderItemPackaging.useMutation() + + const handleOrderPress = () => { + navigate({ to: '/dashboard/orders/$id', params: { id: String(order.orderId) } }) + } + + const handleMenuOption = () => { + setMenuOpen(false) + navigate({ to: '/dashboard/orders/$id', params: { id: String(order.orderId) } }) + } + + const handleMarkPackaged = (isPackaged: boolean) => { + updatePackagedMutation.mutate( + { orderId: order.orderId.toString(), isPackaged }, + { + onSuccess: () => { + refetch() + }, + } + ) + } + + const handleMarkDelivered = (isDelivered: boolean) => { + updateDeliveredMutation.mutate( + { orderId: order.orderId.toString(), isDelivered }, + { + onSuccess: () => { + refetch() + }, + } + ) + } + + const handleItemPackagingToggle = (itemId: number, field: 'isPackaged' | 'isPackageVerified', value: boolean) => { + setUpdatingItems((prev) => new Set(prev).add(itemId)) + + updateItemPackagingMutation.mutate( + { orderItemId: itemId, [field]: value }, + { + onSuccess: () => { + setUpdatingItems((prev) => { + const newSet = new Set(prev) + newSet.delete(itemId) + return newSet + }) + refetch() + }, + onError: (error: any) => { + setUpdatingItems((prev) => { + const newSet = new Set(prev) + newSet.delete(itemId) + return newSet + }) + ErrorToast(error.message || 'Failed to update packaging status') + }, + } + ) + } + + return ( + <> +
{ if (e.key === 'Enter') handleOrderPress() }} + className="mx-4 mb-4 flex w-[calc(100%-2rem)] cursor-pointer flex-col overflow-hidden rounded-xl border border-gray-100 bg-white text-left shadow-sm" + > + {/* Header Section */} +
+
+
+
+ 0 ? 'text-yellow-600' : 'text-gray-900')}`}> + {order.customerName || order.customerMobile || 'Unknown Customer'} + + + #{order.readableId} + + {order.isFlashDelivery && ( + + + FLASH + + )} +
+
+ + + {dayjs(order.createdAt).format('MMM D, h:mm A')} + + {order.userNegativityScore && order.userNegativityScore > 0 && ( + + + Negative Customer + + )} +
+
+ + +
+
+ + {/* Main Content */} +
+ {/* Status Badges */} +
+ + Packaged + {}} + size={18} + fillColor="#6B7280" + checkColor="#FFFFFF" + /> + + e.stopPropagation()} + > + Delivered + handleMarkDelivered(!order.isDelivered)} + size={18} + fillColor="#10B981" + checkColor="#FFFFFF" + /> + + {order.status === 'cancelled' && ( + + CANCELLED + + )} +
+ + {/* Delivery Info */} +
+ +
+ Delivery Address + + {order.address} + +
+ + + {order.isFlashDelivery ? '1 Hr Delivery:' : 'Slot:'} {order.isFlashDelivery ? dayjs(order.createdAt).add(30, 'minutes').format('MMM D, h:mm A') : order.deliveryTime ? dayjs(order.deliveryTime).format('ddd, MMM D • h:mm A') : 'Not scheduled'} + +
+ {order.isFlashDelivery && ( +
+ + + 1 Hour Delivery • High Priority + +
+ )} +
+
+ + {/* Items Summary & Total */} +
+
+
+ + + Total: + {`₹${order.totalAmount}`} + +
+
+
+ + {/* Coupons */} + {order.couponCode && ( +
+ Applied Coupons +
+ + {order.couponCode} + + {order.couponDescription && ( + + {order.couponDescription} + + )} + {order.discountAmount && ( + + {`Discount: ₹${order.discountAmount}`} + + )} +
+
+ )} + + {/* Notes Section */} +
+ {order.userNotes && ( + + )} + {order.adminNotes && ( + + )} +
+ + {/* Footer / Delivery Charge */} + {order.deliveryCharge > 0 && ( +
+
+ Delivery Charge + {`₹${order.deliveryCharge}`} +
+
+ )} +
+
+ + setMenuOpen(false)} + order={{ + id: order.id, + readableId: order.readableId, + isPackaged: order.isPackaged, + isDelivered: order.isDelivered, + isFlashDelivery: order.isFlashDelivery, + address: order.address, + addressId: order.addressId, + adminNotes: order.adminNotes, + userNotes: order.userNotes, + latitude: order.latitude, + longitude: order.longitude, + status: order.status, + }} + onViewDetails={handleMenuOption} + onTogglePackaged={() => handleMarkPackaged(!order.isPackaged)} + onToggleDelivered={() => handleMarkDelivered(!order.isDelivered)} + onOpenAdminNotes={() => { + setMenuOpen(false) + setNotesDialogOpen(true) + }} + onCancelOrder={() => { + setMenuOpen(false) + setCancelDialogOpen(true) + }} + onAttachLocation={() => refetch()} + onWhatsApp={() => {}} + onDial={() => {}} + /> + + setItemsDialogOpen(false)}> +
+
+ + Order Items + + {order.isFlashDelivery && ( + + + FLASH + + )} +
+ + {`Total: ₹${order.totalAmount}`} + + {order.items.map((item, idx) => ( +
+
+ + {`${item.quantity} x ${item.unit}`} + + + {item.name.length > 30 ? `${item.name.substring(0, 30)}...` : item.name} + + {item.isPackaged !== undefined && item.isPackageVerified !== undefined && ( + <> + + pkg + handleItemPackagingToggle(item.id!, 'isPackaged', !item.isPackaged)} + size={18} + fillColor={updatingItems.has(item.id!) ? '#F59E0B' : '#10B981'} + checkColor="#FFFFFF" + /> + + + verf + handleItemPackagingToggle(item.id!, 'isPackageVerified', !item.isPackageVerified)} + size={18} + fillColor={updatingItems.has(item.id!) ? '#F59E0B' : '#10B981'} + checkColor="#FFFFFF" + /> + + {updatingItems.has(item.id!) && ( + + )} + + )} +
+
+ ))} +
+
+ + setNotesDialogOpen(false)}> + setNotesDialogOpen(false)} refetch={refetch} /> + + + setCancelDialogOpen(false)} + onSuccess={refetch} + /> + + setUserNotesDialogOpen(false)}> +
+ + User Notes + +
+ + {order.userNotes} + +
+
+
+ + setAdminNotesDialogOpen(false)}> +
+ + Admin Notes + +
+ + {order.adminNotes} + +
+
+
+ + ) +} + +function Orders() { + const { filter, slotId } = Route.useSearch() + const [selectedSlot, setSelectedSlot] = useState(null) + const [selectedSlotType, setSelectedSlotType] = useState<'slot' | 'flash' | null>(null) + const [packagedFilter, setPackagedFilter] = useState<'all' | 'packaged' | 'not_packaged'>('all') + const [packagedChecked, setPackagedChecked] = useState(false) + const [notPackagedChecked, setNotPackagedChecked] = useState(false) + const [deliveredFilter, setDeliveredFilter] = useState<'all' | 'delivered' | 'not_delivered'>('all') + const [deliveredChecked, setDeliveredChecked] = useState(false) + const [notDeliveredChecked, setNotDeliveredChecked] = useState(false) + const [cancellationFilter, setCancellationFilter] = useState<'all' | 'cancelled' | 'not_cancelled'>('all') + const [cancelledChecked, setCancelledChecked] = useState(false) + const [notCancelledChecked, setNotCancelledChecked] = useState(false) + const [flashDeliveryFilter, setFlashDeliveryFilter] = useState<'all' | 'flash' | 'regular'>('all') + const [flashChecked, setFlashChecked] = useState(false) + const [regularChecked, setRegularChecked] = useState(false) + const [filterDialogOpen, setFilterDialogOpen] = useState(false) + + // Handle initial filter from URL params + useEffect(() => { + if (filter === 'flash' || slotId === 'flash') { + setSelectedSlotType('flash') + setFlashDeliveryFilter('flash') + setFlashChecked(true) + setRegularChecked(false) + } else if (slotId && !Number.isNaN(Number(slotId))) { + setSelectedSlotType('slot') + setSelectedSlot(Number(slotId)) + } + }, [filter, slotId]) + const { data: slotsData } = trpc.admin.slots.getAll.useQuery() + const { data, isLoading, isFetchingNextPage, fetchNextPage, hasNextPage, refetch } = trpc.admin.order.getAll.useInfiniteQuery( + { + limit: 20, + slotId: selectedSlotType === 'slot' ? selectedSlot : null, + packagedFilter, + deliveredFilter, + cancellationFilter, + flashDeliveryFilter: selectedSlotType === 'flash' ? 'flash' : flashDeliveryFilter + }, + { + getNextPageParam: (lastPage) => lastPage?.nextCursor, + } + ) + + const orders = data?.pages.flatMap((page) => page?.orders) || [] + + if (isLoading) { + return ( +
+
+ Loading orders... +
+ ) + } + + const slotOptions = [ + { label: '⚡ Flash Deliveries', value: 'flash' }, + ...(slotsData?.slots?.map((slot) => ({ + label: dayjs(slot.deliveryTime).format('ddd DD MMM, h:mm a'), + value: slot.id.toString(), + })) || []) + ] + + return ( + <> + String(item?.orderId ?? index)} + renderItem={(item) => item ? : null} + onRefresh={() => refetch()} + ListHeaderComponent={ + <> +
+
+ { + if (val === 'flash') { + setSelectedSlotType('flash') + setSelectedSlot(null) + setFlashDeliveryFilter('flash') + // Reset other filters when switching to flash + setPackagedFilter('all') + setPackagedChecked(false) + setNotPackagedChecked(false) + setDeliveredFilter('all') + setDeliveredChecked(false) + setNotDeliveredChecked(false) + setCancellationFilter('all') + setCancelledChecked(false) + setNotCancelledChecked(false) + } else { + setSelectedSlotType('slot') + setSelectedSlot(val ? Number(val) : null) + setFlashDeliveryFilter('all') + } + }} + /> +
+ +
+ {!isLoading && selectedSlotType && ( +
+ + {selectedSlotType === 'flash' + ? `${orders.length} Flash delivery orders` + : `${orders.length} Orders in slot` + } + +
+ )} + + } + ListFooterComponent={ +
+ {isFetchingNextPage ? ( +
+
+ Loading more... +
+ ) : hasNextPage ? ( + fetchNextPage()}> + Load more + + ) : null} +
+ } + /> + + setFilterDialogOpen(false)}> + +
+ Packaged Status +
+ { + const newValue = !packagedChecked + setPackagedChecked(newValue) + if (newValue && notPackagedChecked) { + setPackagedFilter('all') + } else if (newValue) { + setPackagedFilter('packaged') + } else if (notPackagedChecked) { + setPackagedFilter('not_packaged') + } else { + setPackagedFilter('all') + } + }} + /> + Packaged +
+
+ { + const newValue = !notPackagedChecked + setNotPackagedChecked(newValue) + if (packagedChecked && newValue) { + setPackagedFilter('all') + } else if (newValue) { + setPackagedFilter('not_packaged') + } else if (packagedChecked) { + setPackagedFilter('packaged') + } else { + setPackagedFilter('all') + } + }} + /> + Not Packaged +
+
+
+ Delivered Status +
+ { + const newValue = !deliveredChecked + setDeliveredChecked(newValue) + if (newValue && notDeliveredChecked) { + setDeliveredFilter('all') + } else if (newValue) { + setDeliveredFilter('delivered') + } else if (notDeliveredChecked) { + setDeliveredFilter('not_delivered') + } else { + setDeliveredFilter('all') + } + }} + /> + Delivered +
+
+ { + const newValue = !notDeliveredChecked + setNotDeliveredChecked(newValue) + if (deliveredChecked && newValue) { + setDeliveredFilter('all') + } else if (newValue) { + setDeliveredFilter('not_delivered') + } else if (deliveredChecked) { + setDeliveredFilter('delivered') + } else { + setDeliveredFilter('all') + } + }} + /> + Not Delivered +
+
+
+ Cancellation Status +
+ { + const newValue = !cancelledChecked + setCancelledChecked(newValue) + if (newValue && notCancelledChecked) { + setCancellationFilter('all') + } else if (newValue) { + setCancellationFilter('cancelled') + } else if (notCancelledChecked) { + setCancellationFilter('not_cancelled') + } else { + setCancellationFilter('all') + } + }} + /> + Cancelled +
+
+ { + const newValue = !notCancelledChecked + setNotCancelledChecked(newValue) + if (cancelledChecked && newValue) { + setCancellationFilter('all') + } else if (newValue) { + setCancellationFilter('not_cancelled') + } else if (cancelledChecked) { + setCancellationFilter('cancelled') + } else { + setCancellationFilter('all') + } + }} + /> + Not Cancelled +
+
+
+ Delivery Type +
+ { + const newValue = !flashChecked + setFlashChecked(newValue) + if (newValue && regularChecked) { + setFlashDeliveryFilter('all') + } else if (newValue) { + setFlashDeliveryFilter('flash') + } else if (regularChecked) { + setFlashDeliveryFilter('regular') + } else { + setFlashDeliveryFilter('all') + } + }} + /> + ⚡ 1 Hr Delivery +
+
+ { + const newValue = !regularChecked + setRegularChecked(newValue) + if (flashChecked && newValue) { + setFlashDeliveryFilter('all') + } else if (newValue) { + setFlashDeliveryFilter('regular') + } else if (flashChecked) { + setFlashDeliveryFilter('flash') + } else { + setFlashDeliveryFilter('all') + } + }} + /> + Regular Delivery +
+
+
+
+ + ) +} diff --git a/apps/admin-web/src/routes/dashboard.orders.sequence.tsx b/apps/admin-web/src/routes/dashboard.orders.sequence.tsx new file mode 100644 index 0000000..5f7c378 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.orders.sequence.tsx @@ -0,0 +1,798 @@ +import React, { useState, useEffect, useMemo } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { + DndContext, + closestCenter, + PointerSensor, + useSensor, + useSensors +} from '@dnd-kit/core' +import type { DragEndEvent } from '@dnd-kit/core' +import { + SortableContext, + useSortable, + verticalListSortingStrategy, + arrayMove +} from '@dnd-kit/sortable' +import { CSS } from '@dnd-kit/utilities' +import { + p as MyText, + BottomDialog, + Checkbox, + Dropdown +} from 'web-components' +import dayjs from 'dayjs' +import { trpc } from '@/lib/trpc-client' +import { ErrorToast } from '@/services/toaster' +import { useManualRefresh, useMarkDataFetchers } from '@/lib/refresh-context' +import { + MapPin, + Map as MapIcon, + EllipsisVertical, + GripVertical, + Save, + ChevronLeft, + CalendarX, + ClipboardList +} from 'lucide-react' +import { OrderOptionsMenu } from '../components/OrderOptionsMenu' +import CancelOrderDialog from '../components/CancelOrderDialog' +import { OrderNotesForm } from '../components/OrderNotesForm' +import { SearchableSelect } from '@/components/SearchableSelect' + +export const Route = createFileRoute('/dashboard/orders/sequence')({ + validateSearch: (s: Record) => ({ + slotId: (s.slotId as string) ?? '' + }), + component: DeliverySequences, +}) + +// Define types outside +interface OrderWithSequence { + sequenceId: number, + readableId: number, + isPackaged: boolean, + totalAmount: number, + address: string, + latitude: number | null, + longitude: number | null, + id: number, + isDelivered: boolean, + addressId: number, + adminNotes?: string | null, + customerName?: string | null, + assignedUserName?: string | null +} + +interface SlotProgressProps { + slotId: number, + orders: any[] +} + +const SlotProgress: React.FC = ({ slotId, orders }) => { + const delivered = orders.filter((o) => o.isDelivered).length + const undelivered = orders.filter((o) => !o.isDelivered).length + const packaged = orders.filter((o) => o.isPackaged).length + const notPackaged = orders.filter((o) => !o.isPackaged).length + + const stats = [ + { label: 'Delivered', value: delivered }, + { label: 'Undelivered', value: undelivered }, + { label: 'Packaged', value: packaged }, + { label: 'Not Packaged', value: notPackaged }, + ] + + return ( +
+ + Slot {slotId} Statistics + +
+ {stats.map((stat, index) => ( +
+
+ + {stat.value} + + {stat.label} +
+
+ ))} +
+
+ ) +} + +interface OrderItemProps { + item: OrderWithSequence, + isPending: boolean, + setSelectedOrder: (order: OrderWithSequence | null) => void, + setShowOrderMenu: (show: boolean) => void, + selectedOrderIds: number[], + onToggleOrder: (id: number) => void, + assignedUserName?: string | null, + staffData?: { staff?: Array<{ id: number, name: string }> }, + setSelectedUserId?: (id: number) => void +} + +const OrderItem: React.FC = ({ + item, + isPending, + setSelectedOrder, + setShowOrderMenu, + selectedOrderIds, + onToggleOrder, + assignedUserName, + staffData, + setSelectedUserId, +}) => { + const orderItem = item + const { + attributes, + listeners, + setNodeRef, + transform, + transition, + isDragging + } = useSortable({ id: orderItem.sequenceId, disabled: isPending }) + + return ( +
+
+
+ {/* Checkbox and Drag Handle */} +
+ onToggleOrder(orderItem.id)} + size={20} + fillColor="#3b82f6" + checkColor="#FFFFFF" + /> +
+ +
+
+ + {/* Content */} +
+
+
+ + #{orderItem.readableId} + + + + Pkg + + {}} + size={16} + fillColor="#6B7280" + checkColor="#FFFFFF" + /> + +
+
+ + + ₹{orderItem.totalAmount} + + + +
+
+ +
+ + + {orderItem.address} + + {orderItem.latitude && orderItem.longitude && ( + + )} +
+ {assignedUserName && ( +
+ + Assigned to{' '} + + +
+ )} +
+
+ {/* Admin Notes */} + {orderItem.adminNotes && ( +
+ + {orderItem.adminNotes} + +
+ )} +
+
+ ) +} + +function DeliverySequences() { + const { slotId } = Route.useSearch() + const selectedSlotId = slotId ? Number(slotId) : null + const [localOrderedOrders, setLocalOrderedOrders] = useState< + OrderWithSequence[] + >([]) + const [showOrderMenu, setShowOrderMenu] = useState(false) + const [selectedOrder, setSelectedOrder] = useState( + null + ) + const [selectedUserId, setSelectedUserId] = useState(-1) + const [selectedOrderIds, setSelectedOrderIds] = useState([]) + const [hasSequenceChanged, setHasSequenceChanged] = useState(false) + const [cancelDialogOpen, setCancelDialogOpen] = useState(false) + const [notesDialogOpen, setNotesDialogOpen] = useState(false) + const navigate = useNavigate() + + const sensors = useSensors( + useSensor(PointerSensor, { activationConstraint: { delay: 200, tolerance: 8 } }) + ) + + const { data: slotsData, refetch: refetchSlots } = + trpc.admin.slots.getAll.useQuery() + const { + data: ordersData, + isLoading: ordersLoading, + refetch: refetchOrders, + } = trpc.admin.order.getSlotOrders.useQuery( + { slotId: String(selectedSlotId) }, + { + enabled: !!selectedSlotId, + } + ) + const { data: sequenceData, refetch: refetchSequence } = + trpc.admin.slots.getDeliverySequence.useQuery( + { id: String(selectedSlotId) }, + { + enabled: !!selectedSlotId, + } + ) + + const { data: staffData } = trpc.admin.staffUser.getStaff.useQuery() + + // Auto-select first slot if no slotId provided + useEffect(() => { + if (!slotId && slotsData?.slots && slotsData.slots.length > 0) { + navigate({ to: '/dashboard/orders/sequence', search: { slotId: String(slotsData.slots[0].id) }, replace: true }) + } + }, [slotId, slotsData, navigate]) + + const updateSequenceMutation = + trpc.admin.slots.updateDeliverySequence.useMutation() + const updatePackagedMutation = trpc.admin.order.updatePackaged.useMutation() + const updateDeliveredMutation = + trpc.admin.order.updateDelivered.useMutation() + + // Manual refresh functionality + useManualRefresh(() => { + refetchSlots() + refetchOrders() + refetchSequence() + }) + + useMarkDataFetchers(() => { + refetchSlots() + refetchOrders() + refetchSequence() + }) + + const slots = slotsData?.slots || [] + const orders = ordersData?.data || [] + const deliverySequence = sequenceData?.deliverySequence || [] + + const slotOptions = + slots?.map((slot) => ({ + label: dayjs(slot.deliveryTime).format('ddd DD MMM, h:mm a'), + value: slot.id, + })) || [] + + const userOptions = [ + { label: 'Unassigned', value: -1 }, + { label: 'All Users', value: -2 }, + ...(staffData?.staff?.map((staff) => ({ + label: staff.name, + value: staff.id, + })) || []), + ] + + // Create ordered orders based on delivery sequence + const computedOrderedOrders = useMemo(() => { + if (orders.length > 0) { + const userSequence = + selectedUserId !== -1 + ? (deliverySequence as any)?.[String(selectedUserId)] || [] + : null + if (selectedUserId !== -1 && userSequence && userSequence.length > 0) { + // Sort orders according to user's sequence + const sequenceMap = new Map( + userSequence.map((id: number, index: number) => [id, index]) + ) + const ordered = orders + .filter((order) => userSequence.includes(order.id)) + .map((order) => ({ ...order, sequenceId: order.id })) + .sort((a, b) => { + const aIndex = sequenceMap.get(a.sequenceId) ?? Infinity + const bIndex = sequenceMap.get(b.sequenceId) ?? Infinity + return aIndex < bIndex ? -1 : aIndex > bIndex ? 1 : 0 + }) + return ordered + } else if (selectedUserId === -1) { + // Show unassigned orders (not in any user's sequence) + const assignedIds = new Set( + Object.values(deliverySequence as any).flat() + ) + const ordered = orders + .filter((order) => !assignedIds.has(order.id)) + .map((order) => ({ ...order, sequenceId: order.id })) + .sort((a, b) => + a.sequenceId < b.sequenceId + ? -1 + : a.sequenceId > b.sequenceId + ? 1 + : 0 + ) + return ordered + } else if (selectedUserId === -2) { + // Show all orders with assignment info + const orderToUserMap = new Map() + Object.entries(deliverySequence as any).forEach(([userId, orderIds]) => { + (orderIds as number[]).forEach((orderId) => { + orderToUserMap.set(orderId, parseInt(userId)) + }) + }) + const ordered = orders + .map((order) => { + const assignedUserId = orderToUserMap.get(order.id) + const assignedUser = staffData?.staff?.find( + (s) => s.id === assignedUserId + ) + return { + ...order, + sequenceId: order.id, + assignedUserName: assignedUser?.name || null, + } + }) + .sort((a, b) => + a.sequenceId < b.sequenceId + ? -1 + : a.sequenceId > b.sequenceId + ? 1 + : 0 + ) + return ordered + } else { + // No sequence for user, show empty + return [] + } + } else { + return [] + } + }, [ordersData, sequenceData, selectedUserId]) + + // Sync local state with computed orders + useEffect(() => { + setLocalOrderedOrders(computedOrderedOrders as OrderWithSequence[]) + }, [computedOrderedOrders]) + + const handleDragEnd = ({ data }: { data: OrderWithSequence[] }) => { + if (selectedUserId !== -1 && selectedUserId !== -2) { + setLocalOrderedOrders(data) + setHasSequenceChanged(true) + } + } + + const handleDndDragEnd = (event: DragEndEvent) => { + const { active, over } = event + if (!over || active.id === over.id) return + const oldIndex = localOrderedOrders.findIndex((o) => o.sequenceId === active.id) + const newIndex = localOrderedOrders.findIndex((o) => o.sequenceId === over.id) + if (oldIndex === -1 || newIndex === -1) return + handleDragEnd({ data: arrayMove(localOrderedOrders, oldIndex, newIndex) }) + } + + const handleSaveSequence = () => { + if (!selectedSlotId || selectedUserId === -1) return + + const newSequence = { ...(deliverySequence as any) } + newSequence[String(selectedUserId)] = localOrderedOrders.map( + (order) => order.sequenceId + ) + + updateSequenceMutation.mutate( + { + id: selectedSlotId, + deliverySequence: newSequence, + }, + { + onSuccess: () => { + setHasSequenceChanged(false) + window.alert('Success: Delivery sequence updated successfully') + }, + onError: (error: any) => { + ErrorToast( + `Failed to update delivery sequence: ${ + error.message || 'Unknown error' + }` + ) + }, + } + ) + } + + if (!slotsData) { + return ( +
+
+ Loading slots... +
+ ) + } + + if (slotsData.slots.length === 0) { + return ( +
+ + + No slots available + +
+ ) + } + + return ( +
+ {selectedSlotId ? ( + <> + {/* Header Section */} +
+ + +
+ { + if (val !== '' && val !== null && val !== undefined) { + navigate({ to: '/dashboard/orders/sequence', search: { slotId: String(Number(val)) }, replace: true }) + } + }} + /> +
+
+ setSelectedUserId(Number(val))} + /> +
+
+ + {/* Content Section */} + {ordersLoading ? ( +
+
+ Loading orders... +
+ ) : localOrderedOrders.length === 0 ? ( +
+ + + No orders found for this slot + +
+ ) : ( +
+ + + o.sequenceId)} + strategy={verticalListSortingStrategy} + > + {localOrderedOrders.map((item) => ( + { + setSelectedOrderIds((prev) => + prev.includes(id) + ? prev.filter((i) => i !== id) + : [...prev, id] + ) + }} + assignedUserName={selectedUserId === -2 ? item.assignedUserName : undefined} + staffData={staffData} + setSelectedUserId={setSelectedUserId} + /> + ))} + + +
+ )} + + {/* Assignment panel (replaces FAB-triggered dropdown; SearchableSelect renders its own trigger) */} + {selectedOrderIds.length > 0 && ( +
+ opt.value !== -1), + { label: 'None', value: -3 }, + ]} + value={-1} + onValueChange={(val) => { + const numVal = Number(val) + if (numVal !== -1) { + if (numVal === -3) { + // Unassign selected orders + const newSequence = { ...(deliverySequence as any) } + Object.keys(newSequence).forEach((userId) => { + newSequence[userId] = newSequence[userId].filter( + (id: number) => !selectedOrderIds.includes(id) + ) + }) + // Save + updateSequenceMutation.mutate( + { + id: selectedSlotId, + deliverySequence: newSequence, + }, + { + onSuccess: () => { + setSelectedOrderIds([]) + refetchSequence() + window.alert( + 'Success: Orders unassigned successfully' + ) + }, + onError: (error: any) => { + ErrorToast( + `Failed to unassign orders: ${ + error.message || 'Unknown error' + }` + ) + }, + } + ) + } else { + // Assign selected orders to the user + // Update deliverySequence map + const newSequence = { ...(deliverySequence as any) } + // Remove from all other users + Object.keys(newSequence).forEach((userId) => { + newSequence[userId] = newSequence[userId].filter( + (id: number) => !selectedOrderIds.includes(id) + ) + }) + // Add to selected user + if (!newSequence[String(numVal)]) + newSequence[String(numVal)] = [] + newSequence[String(numVal)] = [ + ...new Set([ + ...newSequence[String(numVal)], + ...selectedOrderIds, + ]), + ] + // Save + updateSequenceMutation.mutate( + { + id: selectedSlotId, + deliverySequence: newSequence, + }, + { + onSuccess: () => { + setSelectedOrderIds([]) + refetchSequence() + window.alert( + 'Success: Orders assigned successfully' + ) + }, + onError: (error: any) => { + ErrorToast( + `Failed to assign orders: ${ + error.message || 'Unknown error' + }` + ) + }, + } + ) + } + } + }} + /> +
+ )} + + {/* FAB for Save */} + {hasSequenceChanged && ( +
+ +
+ )} + + ) : ( +
+ + + No slot selected. Please select a slot to view delivery sequence. + + +
+ )} + + {/* Order Menu Dialog */} + setShowOrderMenu(false)} + order={{ + id: selectedOrder?.id || 0, + readableId: selectedOrder?.readableId || 0, + isPackaged: selectedOrder?.isPackaged || false, + isDelivered: selectedOrder?.isDelivered || false, + address: selectedOrder?.address || '', + addressId: selectedOrder?.addressId || 0, + adminNotes: selectedOrder?.adminNotes || null, + latitude: selectedOrder?.latitude || null, + longitude: selectedOrder?.longitude || null, + }} + onViewDetails={() => { + if (selectedOrder) { + navigate({ to: '/dashboard/orders/$id', params: { id: String(selectedOrder.id) } }) + } + setShowOrderMenu(false) + }} + onTogglePackaged={() => { + if (!selectedOrder) return + updatePackagedMutation.mutate( + { orderId: selectedOrder.id.toString(), isPackaged: !selectedOrder.isPackaged }, + { + onSuccess: () => { + refetchOrders() + refetchSequence() + }, + onError: () => { + ErrorToast('Failed to update packaged status') + }, + } + ) + }} + onToggleDelivered={() => { + if (!selectedOrder) return + updateDeliveredMutation.mutate( + { orderId: selectedOrder.id.toString(), isDelivered: !selectedOrder.isDelivered }, + { + onSuccess: () => { + refetchOrders() + refetchSequence() + }, + onError: () => { + ErrorToast('Failed to update delivered status') + }, + } + ) + }} + onOpenAdminNotes={() => { + setShowOrderMenu(false) + setNotesDialogOpen(true) + }} + onCancelOrder={() => { + setShowOrderMenu(false) + setCancelDialogOpen(true) + }} + onAttachLocation={() => {}} + onWhatsApp={() => {}} + onDial={() => {}} + /> + + setCancelDialogOpen(false)} + onSuccess={() => { + refetchOrders() + refetchSequence() + }} + /> + + setNotesDialogOpen(false)}> + { + refetchOrders() + refetchSequence() + setNotesDialogOpen(false) + }} + onCancel={() => setNotesDialogOpen(false)} + /> + +
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.orders.tsx b/apps/admin-web/src/routes/dashboard.orders.tsx new file mode 100644 index 0000000..e1d5435 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.orders.tsx @@ -0,0 +1,99 @@ +import React, { useEffect, useState } from 'react' +import { createFileRoute, Outlet, useLocation, useNavigate } from '@tanstack/react-router' +import { ListOrdered, Route as RouteIcon } from 'lucide-react' +import { p as MyText, Dropdown } from 'web-components' +import dayjs from 'dayjs' +import { trpc } from '@/lib/trpc-client' +import { useNavigationTarget } from '@/lib/navigation-target' +import { useMarkDataFetchers } from '@/lib/refresh-context' + +export const Route = createFileRoute('/dashboard/orders')({ + component: ManageOrders, +}) + +function ManageOrders() { + const location = useLocation() + const navigate = useNavigate() + const { getNavigationTarget } = useNavigationTarget() + const [selectedSlotId, setSelectedSlotId] = useState(null) + const { data: slotsData, refetch } = trpc.admin.slots.getAll.useQuery() + + useEffect(() => { + const target = getNavigationTarget() + if (target) { + navigate({ to: target } as any) + } + }, [getNavigationTarget, navigate]) + + useMarkDataFetchers(() => { + refetch() + }) + + if (location.pathname !== '/dashboard/orders') { + return + } + + // Create slot options with Flash Deliveries as first option + const slotOptions = [ + { label: '⚡ Flash Deliveries', value: 'flash' }, + ...(slotsData?.slots?.map((slot) => ({ + label: dayjs(slot.deliveryTime).format('ddd DD MMM, h:mm a'), + value: slot.id.toString() + })) || []) + ] + + const menuItems = [ + { + title: 'Delivery Sequences', + icon: , + color: 'bg-purple-500', + onClick: () => { + if (selectedSlotId === 'flash') { + window.alert('Flash Deliveries: Flash deliveries do not have delivery sequences. Use the Orders menu to manage flash deliveries.') + return + } + navigate({ to: '/dashboard/orders/sequence', search: { slotId: selectedSlotId ?? '' } }) + }, + }, + { + title: 'Orders', + icon: , + color: 'bg-cyan-500', + onClick: () => { + if (selectedSlotId === 'flash') { + navigate({ to: '/dashboard/orders/list', search: { filter: 'flash', slotId: '' } }) + } else { + navigate({ to: '/dashboard/orders/list', search: { filter: '', slotId: selectedSlotId ?? '' } }) + } + }, + }, + ] + + return ( +
+
+ setSelectedSlotId(String(val))} + className="w-full" + /> +
+
+ {menuItems.map((item, index) => ( + + ))} +
+
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.prices.tsx b/apps/admin-web/src/routes/dashboard.prices.tsx new file mode 100644 index 0000000..4c2e005 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.prices.tsx @@ -0,0 +1,420 @@ +import React, { useState, useEffect, useMemo } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { Save, Pencil, EllipsisVertical, Shuffle } from 'lucide-react' +import { + AppContainer, + p as MyText, + pInput as MyTextInput, + BottomDialog, + Checkbox, + MyFlatList, +} from 'web-components' +import MultiSelect from '@/components/MultiSelect' +import { trpc } from '@/lib/trpc-client' + +export const Route = createFileRoute('/dashboard/prices')({ + component: PricesOverview, +}) + +interface SkuItemProps { + sku: any + productName: string + hasChanges: (skuId: number) => boolean + pendingChanges: Record + setPendingChanges: React.Dispatch>> + openEditDialog: (sku: any, productName: string) => void +} + +const SkuItemComponent: React.FC = ({ + sku, + productName, + hasChanges, + pendingChanges, + setPendingChanges, + openEditDialog, +}) => { + const changed = hasChanges(sku.id) + const change = pendingChanges[sku.id] || {} + const displayPrice = change.price !== undefined ? change.price : sku.price + const displayMarketPrice = change.marketPrice !== undefined ? change.marketPrice : sku.marketPrice + const displayFlashPrice = change.flashPrice !== undefined ? change.flashPrice : sku.flashPrice + const displayUnit = (sku.features || []).map((f: any) => f.featureValue).join(' ') || '—' + + return ( +
+
+
+ {changed && ( + + + + )} +
+
+ +
+ + +
+
+ + {productName.length > 20 ? productName.substring(0, 20) + '...' : productName} + + + {sku.displayName || sku.name || ''} + +
+
+ + { + const currentValue = change.isFlashAvailable ?? sku.isFlashAvailable ?? false + setPendingChanges((prev) => ({ + ...prev, + [sku.id]: { + ...prev[sku.id], + isFlashAvailable: !currentValue, + }, + })) + }} + /> + + Flash +
+
+
+ +
+
+ Our Price +
+ ₹{displayPrice} + +
+
+ +
+ Market Price +
+ {displayMarketPrice ? `₹${displayMarketPrice}` : 'N/A'} + +
+
+ +
+ Flash Price +
+ {displayFlashPrice ? `₹${displayFlashPrice}` : 'N/A'} + +
+
+ +
+ Size +
+ {displayUnit} + +
+
+
+
+ ) +} + +interface PendingChange { + price?: number + marketPrice?: number | null + flashPrice?: number | null + isFlashAvailable?: boolean +} + +interface EditDialogState { + open: boolean + sku: any + productName: string + tempPrice: string + tempMarketPrice: string + tempFlashPrice: string +} + +function PricesOverview() { + const navigate = useNavigate() + const [selectedStores, setSelectedStores] = useState([]) + const [pendingChanges, setPendingChanges] = useState>({}) + const [editDialog, setEditDialog] = useState({ + open: false, + sku: null, + productName: '', + tempPrice: '', + tempMarketPrice: '', + tempFlashPrice: '', + }) + const [showMenu, setShowMenu] = useState(false) + + const { data: productsData, isLoading: productsLoading, refetch: refetchProducts } = + trpc.admin.product.getProducts.useQuery() + const { data: storesData, isLoading: storesLoading } = + trpc.admin.store.getStores.useQuery() + + const updatePricesMutation = trpc.admin.product.updateProductPrices.useMutation() + + const stores = storesData?.stores || [] + const allProducts = productsData?.products || [] + + const sortedStores = useMemo(() => + [...stores].sort((a, b) => a.name.localeCompare(b.name)), + [stores] + ) + + const storeOptions = useMemo(() => + sortedStores.map((store) => ({ + label: store.name, + value: store.id.toString(), + })), + [sortedStores] + ) + + useEffect(() => { + if (stores.length > 0 && selectedStores.length === 0) { + setSelectedStores(stores.map((s) => s.id.toString())) + } + }, [stores, selectedStores]) + + const allSkus = useMemo(() => { + const skus: any[] = [] + for (const product of allProducts) { + if (product.skus && product.skus.length > 0) { + for (const sku of product.skus) { + skus.push({ ...sku, _productName: product.name, _storeId: product.storeId }) + } + } + } + return skus + }, [allProducts]) + + const filteredSkus = useMemo(() => { + if (selectedStores.length === 0) return allSkus + return allSkus.filter((sku) => + sku._storeId && selectedStores.includes(sku._storeId.toString()) + ) + }, [allSkus, selectedStores]) + + const hasChanges = (skuId: number) => !!pendingChanges[skuId] + + const openEditDialog = (sku: any, productName: string) => { + const change = pendingChanges[sku.id] || {} + setEditDialog({ + open: true, + sku, + productName, + tempPrice: (change.price ?? sku.price)?.toString() || '', + tempMarketPrice: (change.marketPrice ?? sku.marketPrice)?.toString() || '', + tempFlashPrice: (change.flashPrice ?? sku.flashPrice)?.toString() || '', + }) + } + + const saveEditDialog = () => { + const price = parseFloat(editDialog.tempPrice) + const marketPrice = editDialog.tempMarketPrice ? parseFloat(editDialog.tempMarketPrice) : null + const flashPrice = editDialog.tempFlashPrice ? parseFloat(editDialog.tempFlashPrice) : null + + if (isNaN(price) || price <= 0) { + window.alert('Please enter a valid price') + return + } + + if (editDialog.tempMarketPrice && (isNaN(marketPrice!) || marketPrice! <= 0)) { + window.alert('Please enter a valid market price') + return + } + + if (editDialog.tempFlashPrice && (isNaN(flashPrice!) || flashPrice! <= 0)) { + window.alert('Please enter a valid flash price') + return + } + + setPendingChanges((prev) => ({ + ...prev, + [editDialog.sku.id]: { + price: price !== parseFloat(editDialog.sku.price) ? price : undefined, + marketPrice: marketPrice !== parseFloat(editDialog.sku.marketPrice || '0') ? marketPrice : undefined, + flashPrice: flashPrice !== parseFloat(editDialog.sku.flashPrice || '0') ? flashPrice : undefined, + }, + })) + + } + + const handleSave = () => { + const updates = Object.entries(pendingChanges).map(([skuId, change]) => { + const sku = allSkus.find((s) => s.id === parseInt(skuId)) + const update: any = { productId: sku?.id } + if (change.price !== undefined) update.price = change.price + if (change.marketPrice !== undefined) update.marketPrice = change.marketPrice + if (change.flashPrice !== undefined) update.flashPrice = change.flashPrice + if (change.isFlashAvailable !== undefined) update.isFlashAvailable = change.isFlashAvailable + return update + }) + + updatePricesMutation.mutate( + { updates }, + { + onSuccess: () => { + setPendingChanges({}) + refetchProducts() + window.alert('Prices updated successfully') + }, + onError: (error: any) => { + window.alert(`Failed to update prices: ${error.message || 'Unknown error'}`) + }, + } + ) + } + + const changeCount = Object.keys(pendingChanges).length + + return ( +
+
+
+ setSelectedStores(value as string[])} + placeholder="Select stores" + /> +
+ + +
+ + {productsLoading || storesLoading ? ( +
+
+ Loading... +
+ ) : ( + ( + + )} + keyExtractor={(item) => item.id.toString()} + className="p-4" + /> + )} + + setEditDialog({ ...editDialog, open: false, tempFlashPrice: '', tempMarketPrice: '', tempPrice: '' })}> +
+ {editDialog.productName} + {editDialog.sku?.displayName || editDialog.sku?.name || ''} + +
+ Our Price + setEditDialog({ ...editDialog, tempPrice: e.target.value })} + type="number" + placeholder="Enter price" + /> +
+ +
+ Market Price (Optional) + setEditDialog({ ...editDialog, tempMarketPrice: e.target.value })} + type="number" + placeholder="Enter market price" + /> +
+ +
+ Flash Price (Optional) + setEditDialog({ ...editDialog, tempFlashPrice: e.target.value })} + type="number" + placeholder="Enter flash price" + /> +
+ + +
+
+ + setShowMenu(false)}> +
+ + Options + + +
+
+
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.product-groupings.$id.edit.tsx b/apps/admin-web/src/routes/dashboard.product-groupings.$id.edit.tsx new file mode 100644 index 0000000..6dd80ca --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.product-groupings.$id.edit.tsx @@ -0,0 +1,49 @@ +import React from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { AppContainer, p as MyText } from 'web-components' +import ProductGroupForm from '../components/ProductGroupForm' +import { trpc } from '@/lib/trpc-client' + +export const Route = createFileRoute('/dashboard/product-groupings/$id/edit')({ + component: EditProductGroup, +}) + +function EditProductGroup() { + const { id } = Route.useParams() + + const groupId = parseInt(id as string) + + const { data: groupsData, isLoading } = trpc.admin.product.getGroups.useQuery() + const groups = groupsData?.groups || [] + const group = groups.find((g) => g.id === groupId) + + if (isLoading) { + return ( + +
+ Loading group... +
+
+ ) + } + + if (!group) { + return ( + +
+ Group not found +
+
+ ) + } + + return ( + + window.history.back()} + onSuccess={() => window.history.back()} + /> + + ) +} diff --git a/apps/admin-web/src/routes/dashboard.product-groupings.new.tsx b/apps/admin-web/src/routes/dashboard.product-groupings.new.tsx new file mode 100644 index 0000000..e7d6649 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.product-groupings.new.tsx @@ -0,0 +1,19 @@ +import React from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { AppContainer } from 'web-components' +import ProductGroupForm from '../components/ProductGroupForm' + +export const Route = createFileRoute('/dashboard/product-groupings/new')({ + component: CreateProductGroup, +}) + +function CreateProductGroup() { + return ( + + window.history.back()} + onSuccess={() => window.history.back()} + /> + + ) +} diff --git a/apps/admin-web/src/routes/dashboard.product-groupings.tsx b/apps/admin-web/src/routes/dashboard.product-groupings.tsx new file mode 100644 index 0000000..6062b92 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.product-groupings.tsx @@ -0,0 +1,198 @@ +import React, { useState } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { Users, Pencil, Trash2, Package, Clock, Group as GroupIcon, Plus } from 'lucide-react' +import { AppContainer, p as MyText } from 'web-components' +import { useManualRefresh, useMarkDataFetchers } from '@/lib/refresh-context' +import { trpc } from '@/lib/trpc-client' +import { theme } from '@/lib/theme' +import dayjs from 'dayjs' +import type { ProductGroup } from '../components/ProductGroupForm' + +export const Route = createFileRoute('/dashboard/product-groupings')({ + component: ProductGroupings, +}) + +const GroupItem = ({ + group, + onEdit, + onDelete, + onViewProducts, + index, +}: { + group: ProductGroup + onEdit: (group: ProductGroup) => void + onDelete: (id: number) => void + onViewProducts: (products: any[]) => void + index: number +}) => { + return ( +
+
+
+
+
+ +
+
+ + Group Name + + + {group.groupName} + +
+
+ +
+ + +
+
+ + {group.description && ( +
+ + {group.description} + +
+ )} + +
+
+ +
+ + + {dayjs(group.createdAt).format('MMM DD, YYYY')} + +
+
+
+
+
+ ) +} + +function ProductGroupings() { + const navigate = useNavigate() + const { + data: groupsData, + isLoading, + error, + refetch, + } = trpc.admin.product.getGroups.useQuery() + const deleteGroup = trpc.admin.product.deleteGroup.useMutation() + + const groups = groupsData?.groups || [] + const [viewProducts, setViewProducts] = useState(null) + + useManualRefresh(refetch) + useMarkDataFetchers(() => { + refetch() + }) + + const handleCreate = () => { + navigate({ to: '/dashboard/product-groupings/new' }) + } + + const handleEdit = (group: ProductGroup) => { + navigate({ to: '/dashboard/product-groupings/$id/edit', params: { id: String(group.id) } }) + } + + const handleDelete = (id: number) => { + if (window.confirm('Are you sure you want to delete this group?')) { + deleteGroup.mutate( + { id }, + { + onSuccess: () => { + refetch() + }, + } + ) + } + } + + if (isLoading) { + return ( + +
+ Loading product groups... +
+
+ ) + } + + if (error) { + return ( + +
+ Error loading groups +
+
+ ) + } + + return ( +
+
+ {groups.length === 0 ? ( +
+
+ +
+ + No Groups Yet + + + Start by creating your first product group using the button below. + +
+ ) : ( + groups.map((group, index) => ( + + + {index < groups.length - 1 && ( +
+ )} + + )) + )} +
+ +
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.product-tags.edit.tsx b/apps/admin-web/src/routes/dashboard.product-tags.edit.tsx new file mode 100644 index 0000000..9c5e984 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.product-tags.edit.tsx @@ -0,0 +1,118 @@ +import React from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { AppContainer, p as MyText, type ImageUploaderNeoItem } from 'web-components' +import TagForm, { type TagFormData as BaseTagFormData } from '../components/TagForm' +import { trpc } from '@/lib/trpc-client' +import { useUploadToObjectStorage } from '@/hooks/useUploadToObjectStorage' + +export const Route = createFileRoute('/dashboard/product-tags/edit')({ + validateSearch: (s: Record) => ({ tagId: (s.tagId as string) ?? '' }), + component: EditTag, +}) + +type TagFormData = BaseTagFormData & { existingImageUrl?: string } + +function EditTag() { + const { tagId } = Route.useSearch() + const tagIdNum = tagId ? parseInt(tagId) : null + + const { data: tagData, isLoading: isLoadingTag, error: tagError } = trpc.admin.product.getProductTagById.useQuery( + { id: tagIdNum || 0 }, + { enabled: !!tagIdNum } + ) + const { refetch: refetchTags } = trpc.admin.product.getProductTags.useQuery(undefined, { + enabled: false, + }) + const updateTag = trpc.admin.product.updateProductTag.useMutation() + const { data: storesData } = trpc.admin.store.getStores.useQuery() + const { upload, isUploading } = useUploadToObjectStorage() + + const handleSubmit = async (values: TagFormData, images: ImageUploaderNeoItem[], removedExisting: boolean) => { + if (!tagIdNum) return + + try { + let imageUrl: string | null | undefined + let uploadUrls: string[] = [] + + const newImage = images.find((image) => image.mimeType !== null) + if (newImage) { + const response = await fetch(newImage.imgUrl) + const blob = await response.blob() + const result = await upload({ + images: [{ blob, mimeType: newImage.mimeType || 'image/jpeg' }], + contextString: 'tags', + }) + imageUrl = result.keys[0] + uploadUrls = result.presignedUrls + } else if (removedExisting) { + imageUrl = null + } + + await updateTag.mutateAsync({ + id: tagIdNum, + tagName: values.tagName, + tagDescription: values.tagDescription || undefined, + imageUrl, + isDashboardTag: values.isDashboardTag, + relatedStores: values.relatedStores, + productIds: values.productIds, + uploadUrls, + }) + + await refetchTags() + window.alert('Tag updated successfully') + window.history.back() + } catch (error: any) { + const errorMessage = error.message || 'Failed to update tag' + window.alert(errorMessage) + } + } + + if (isLoadingTag) { + return ( + +
+ Loading tag... +
+
+ ) + } + + if (tagError || !tagData?.tag) { + return ( + +
+ Tag not found +
+
+ ) + } + + const tag = tagData.tag + const tagProductIds = tag.productIds || (tag.products || []).map((p: any) => p.productId) + const orderedProductIds = (tag.sortOrder || []).filter((id: number) => tagProductIds.includes(id)) + const remainingProductIds = tagProductIds.filter((id: number) => !orderedProductIds.includes(id)) + const initialValues: TagFormData = { + tagName: tag.tagName, + tagDescription: tag.tagDescription || '', + isDashboardTag: tag.isDashboardTag, + relatedStores: Array.isArray(tag.relatedStores) ? tag.relatedStores : [], + productIds: [...orderedProductIds, ...remainingProductIds], + existingImageUrl: tag.imageUrl || undefined, + } + + return ( + +
+ ({ id: store.id, name: store.name })) || []} + /> +
+
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.product-tags.new.tsx b/apps/admin-web/src/routes/dashboard.product-tags.new.tsx new file mode 100644 index 0000000..e4046e1 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.product-tags.new.tsx @@ -0,0 +1,77 @@ +import React from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { AppContainer, type ImageUploaderNeoItem } from 'web-components' +import TagForm, { type TagFormData } from '../components/TagForm' +import { trpc } from '@/lib/trpc-client' +import { useUploadToObjectStorage } from '@/hooks/useUploadToObjectStorage' + +export const Route = createFileRoute('/dashboard/product-tags/new')({ + component: AddTag, +}) + +function AddTag() { + const createTag = trpc.admin.product.createProductTag.useMutation() + const { refetch: refetchTags } = trpc.admin.product.getProductTags.useQuery(undefined, { + enabled: false, + }) + const { data: storesData } = trpc.admin.store.getStores.useQuery() + const { upload, isUploading } = useUploadToObjectStorage() + + const handleSubmit = async (values: TagFormData, images: ImageUploaderNeoItem[], _removedExisting: boolean) => { + try { + let imageUrl: string | null | undefined + let uploadUrls: string[] = [] + + const newImage = images.find((image) => image.mimeType !== null) + if (newImage) { + const response = await fetch(newImage.imgUrl) + const blob = await response.blob() + const result = await upload({ + images: [{ blob, mimeType: newImage.mimeType || 'image/jpeg' }], + contextString: 'tags', + }) + imageUrl = result.keys[0] + uploadUrls = result.presignedUrls + } + + await createTag.mutateAsync({ + tagName: values.tagName, + tagDescription: values.tagDescription || undefined, + imageUrl, + isDashboardTag: values.isDashboardTag, + relatedStores: values.relatedStores, + productIds: values.productIds, + uploadUrls, + }) + + await refetchTags() + window.alert('Tag created successfully') + window.history.back() + } catch (error: any) { + const errorMessage = error.message || 'Failed to create tag' + window.alert(errorMessage) + } + } + + const initialValues: TagFormData = { + tagName: '', + tagDescription: '', + isDashboardTag: false, + relatedStores: [], + productIds: [], + } + + return ( + +
+ ({ id: store.id, name: store.name })) || []} + /> +
+
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.product-tags.order.tsx b/apps/admin-web/src/routes/dashboard.product-tags.order.tsx new file mode 100644 index 0000000..7bb2984 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.product-tags.order.tsx @@ -0,0 +1,286 @@ +import React, { useState, useEffect, useCallback } from 'react' +import { createFileRoute } from '@tanstack/react-router' +import { useQueryClient } from '@tanstack/react-query' +import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, type DragEndEvent } from '@dnd-kit/core' +import { SortableContext, useSortable, arrayMove, verticalListSortingStrategy } from '@dnd-kit/sortable' +import { CSS } from '@dnd-kit/utilities' +import { GripVertical, Tag as TagIcon, ChevronLeft, CircleAlert } from 'lucide-react' +import { AppContainer, p as MyText } from 'web-components' +import { trpc } from '@/lib/trpc-client' +import type { DragOrderItemProps } from '@/types/drag-order-item' + +export const Route = createFileRoute('/dashboard/product-tags/order')({ + component: TagOrders, +}) + +interface Tag { + id: number + tagName: string + imageUrl: string | null +} + +const itemStyle: React.CSSProperties = { + width: '100%', + height: 60, + backgroundColor: 'white', + borderRadius: 8, + borderWidth: 1, + borderStyle: 'solid', + borderColor: '#e5e7eb', + padding: 10, + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + boxShadow: '0 1px 2px rgba(0,0,0,0.1)', + marginTop: 4, + marginBottom: 4, +} + +const activeItemStyle: React.CSSProperties = { + ...itemStyle, + borderColor: '#3b82f6', + boxShadow: '0 4px 8px rgba(59,130,246,0.3)', +} + +const SortableTagItem: React.FC> = ({ item, isActive }) => { + const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: item.id }) + const active = isActive || isDragging + + return ( +
+
+ +
+ + {item.imageUrl ? ( + {item.tagName} + ) : ( +
+ +
+ )} + +
+ + {item.tagName} + +
+
+ ) +} + +function TagOrders() { + const queryClient = useQueryClient() + const [tags, setTags] = useState([]) + const [hasChanges, setHasChanges] = useState(false) + + const { data: constants, isLoading: isLoadingConstants, error: constantsError } = trpc.admin.const.getConstants.useQuery() + const { data: tagsData, isLoading: isLoadingTags, error: tagsError } = trpc.admin.product.getProductTags.useQuery() + const updateConstants = trpc.admin.const.updateConstants.useMutation() + + const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } })) + + useEffect(() => { + if (tagsData?.tags) { + const tagsOrderConstant = constants?.find((c) => c.key === 'tagsOrder') + + let orderedIds: number[] = [] + + if (tagsOrderConstant) { + const value = tagsOrderConstant.value + + if (Array.isArray(value)) { + orderedIds = value.map((id: any) => parseInt(id)) + } else if (typeof value === 'string') { + orderedIds = value.split(',').map((id: string) => parseInt(id.trim())).filter((id) => !isNaN(id)) + } + } + + const tagMap = new Map(tagsData.tags.map((t) => [t.id, t])) + + const sortedTags: Tag[] = [] + + for (const id of orderedIds) { + const tag = tagMap.get(id) + if (tag) { + sortedTags.push({ + id: tag.id, + tagName: tag.tagName, + imageUrl: tag.imageUrl || null, + }) + tagMap.delete(id) + } + } + + for (const tag of tagMap.values()) { + sortedTags.push({ + id: tag.id, + tagName: tag.tagName, + imageUrl: tag.imageUrl || null, + }) + } + + setTags(sortedTags) + } + }, [constants, tagsData]) + + const handleDragEnd = useCallback((event: DragEndEvent) => { + const { active, over } = event + if (over && active.id !== over.id) { + setTags((prev) => { + const oldIndex = prev.findIndex((t) => t.id === active.id) + const newIndex = prev.findIndex((t) => t.id === over.id) + return arrayMove(prev, oldIndex, newIndex) + }) + setHasChanges(true) + } + }, []) + + const handleSave = () => { + const tagIds = tags.map((t) => t.id) + + updateConstants.mutate( + { + constants: [{ + key: 'tagsOrder', + value: tagIds, + }], + }, + { + onSuccess: () => { + setHasChanges(false) + window.alert('Tag order updated successfully!') + queryClient.invalidateQueries({ queryKey: ['const.getConstants'] }) + }, + onError: (error) => { + window.alert('Failed to update tag order. Please try again.') + console.error('Update tag order error:', error) + }, + } + ) + } + + if (isLoadingConstants || isLoadingTags) { + return ( + +
+
+ + Tag Orders +
+
+
+
+ + {isLoadingConstants ? 'Loading order...' : 'Loading tags...'} + +
+
+ + ) + } + + if (constantsError || tagsError) { + return ( + +
+
+ + Tag Orders +
+
+
+ + Error + + {constantsError ? 'Failed to load order' : 'Failed to load tags'} + + +
+
+ + ) + } + + return ( +
+
+ + + Tag Orders + + +
+ + {tags.length === 0 ? ( +
+ + + No tags available + +
+ ) : ( +
+
+ + Long press and drag to reorder • {tags.length} items + +
+ +
+ + t.id)} strategy={verticalListSortingStrategy}> + {tags.map((tag) => ( + {}} isActive={false} /> + ))} + + +
+
+ )} +
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.product-tags.tsx b/apps/admin-web/src/routes/dashboard.product-tags.tsx new file mode 100644 index 0000000..c1e0ac1 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.product-tags.tsx @@ -0,0 +1,142 @@ +import React from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { ArrowDownUp, Plus, CircleAlert, Tags, LayoutDashboard } from 'lucide-react' +import { p as MyText, MyFlatList } from 'web-components' +import { useManualRefresh, useMarkDataFetchers } from '@/lib/refresh-context' +import { TagMenu } from '../components/TagMenu' +import { trpc } from '@/lib/trpc-client' +import type { ProductTagCore } from '@packages/shared' + +export const Route = createFileRoute('/dashboard/product-tags')({ + component: ProductTags, +}) + +interface TagItemData extends ProductTagCore { + id: number + tagDescription: string | null + imageUrl: string | null + isDashboardTag: boolean + createdAt: string | Date +} + +interface TagItemProps { + item: TagItemData + onDeleteSuccess: () => void +} + +const TagItem: React.FC = ({ item, onDeleteSuccess }) => ( +
+
+
+ {item.imageUrl && ( + {item.tagName} + )} +
+ {item.tagName} + {item.tagDescription && ( + {item.tagDescription} + )} + {item.isDashboardTag && ( +
+ + Dashboard Tag +
+ )} +
+
+ +
+
+) + +interface TagHeaderProps { + onAddNewTag: () => void + onOrderTags: () => void +} + +const TagHeader: React.FC = ({ onAddNewTag, onOrderTags }) => ( +
+ + +
+) + +function ProductTags() { + const navigate = useNavigate() + const { data: tagsData, isLoading, error, refetch } = trpc.admin.product.getProductTags.useQuery() + + const tags = tagsData?.tags || [] + + useManualRefresh(refetch) + + useMarkDataFetchers(() => { + refetch() + }) + + const handleAddNewTag = () => { + navigate({ to: '/dashboard/product-tags/new' }) + } + + const handleOrderTags = () => { + navigate({ to: '/dashboard/product-tags/order' }) + } + + if (isLoading) { + return ( +
+ Loading tags... +
+ ) + } + + if (error) { + return ( +
+ + Error + {error?.message || 'Failed to load tags'} + +
+ ) + } + + return ( +
+ } + keyExtractor={(item) => item.id.toString()} + ListHeaderComponent={} + ListEmptyComponent={ +
+ + No tags yet + Create your first product tag +
+ } + className="pb-4" + /> +
+ ) +} diff --git a/apps/admin-web/src/routes/dashboard.products.$id.tsx b/apps/admin-web/src/routes/dashboard.products.$id.tsx new file mode 100644 index 0000000..dbea6e7 --- /dev/null +++ b/apps/admin-web/src/routes/dashboard.products.$id.tsx @@ -0,0 +1,461 @@ +import React, { useState, useRef } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { + Star, + CircleAlert, + ArrowLeft, + Pencil, + FileText, + LayoutGrid, + Tag, + MessageSquareText, + BadgeCheck, + Reply, + X, + MessageCircle, + Quote, +} from 'lucide-react' +import { AppContainer, p as MyText, BottomDialog, ImageUploader, ImageCarousel } from 'web-components' +import { trpc } from '@/lib/trpc-client' +import { useMarkDataFetchers } from '@/lib/refresh-context' +import { useUploadToObjectStorage } from '@/hooks/useUploadToObjectStorage' +import { Formik } from 'formik' + +export const Route = createFileRoute('/dashboard/products/$id')({ + component: ProductDetail, +}) + +interface ReviewResponseFormProps { + reviewId: number + onClose: () => void +} + +const ReviewResponseForm: React.FC = ({ reviewId, onClose }) => { + const [selectedImages, setSelectedImages] = useState<{ blob: Blob, mimeType: string }[]>([]) + const [displayImages, setDisplayImages] = useState<{ uri?: string }[]>([]) + const fileInputRef = useRef(null) + + const respondToReview = trpc.admin.product.respondToReview.useMutation() + const { upload } = useUploadToObjectStorage() + + const handleFilesSelected = async (files: FileList | null) => { + if (!files || files.length === 0) { + setSelectedImages([]) + setDisplayImages([]) + return + } + const fileArray = Array.from(files) + const blobArray = fileArray.map((file) => ({ blob: file, mimeType: file.type || 'image/jpeg' })) + setSelectedImages(blobArray) + setDisplayImages(fileArray.map((file) => ({ uri: URL.createObjectURL(file) }))) + } + + const handleRemoveImage = (uri: string) => { + const index = displayImages.findIndex((img) => img.uri === uri) + if (index !== -1) { + const newDisplay = displayImages.filter((_, i) => i !== index) + const newFiles = selectedImages.filter((_, i) => i !== index) + setDisplayImages(newDisplay) + setSelectedImages(newFiles) + } + } + + const handleSubmit = async (adminResponse: string) => { + try { + const { keys, presignedUrls } = await upload({ + images: selectedImages, + contextString: 'review', + }) + + await respondToReview.mutateAsync({ + reviewId, + adminResponse, + adminResponseImages: keys, + uploadUrls: presignedUrls, + }) + + window.alert('Response submitted') + onClose() + setSelectedImages([]) + setDisplayImages([]) + } catch (error: any) { + window.alert(error.message || 'Failed to submit response.') + } + } + + return ( + handleSubmit(values.adminResponse)} + > + {({ handleChange, handleSubmit: formikSubmit, values }) => ( +
+