From 57903b80b6a9dc7753eb6d1f44c9a9a08ae8f0ca Mon Sep 17 00:00:00 2001 From: claude Date: Thu, 12 Mar 2026 09:33:28 +0000 Subject: [PATCH] update grpc --- bun.lock | 231 +- package.json | 22 +- src/api/httpClientAdapter.server.ts | 1 + src/api/rpcclient.ts | 29 +- src/components/DashboardNav.vue | 92 +- src/composables/useAdminRuntimeMqtt.ts | 58 + src/composables/useNotifications.ts | 26 +- .../useSettingsPreferencesQuery.ts | 38 +- src/composables/useUploadQueue.ts | 307 +- src/composables/useUsageQuery.ts | 18 +- src/index.tsx | 8 +- src/mocks/videos.ts | 51 +- src/routes/admin/AdTemplates.vue | 334 + src/routes/admin/Agents.vue | 191 + src/routes/admin/Jobs.vue | 362 + src/routes/admin/Layout.vue | 3 + src/routes/admin/Logs.vue | 59 + src/routes/admin/Overview.vue | 55 + src/routes/admin/Payments.vue | 223 + src/routes/admin/Plans.vue | 342 + src/routes/admin/Users.vue | 351 + src/routes/admin/Videos.vue | 354 + .../components/AdminPlaceholderTable.vue | 27 + .../admin/components/AdminSectionShell.vue | 18 + src/routes/auth/forgot.vue | 4 +- src/routes/auth/google-finalize.vue | 4 +- src/routes/index.ts | 30 +- src/routes/overview/Overview.vue | 15 +- .../overview/components/RecentVideos.vue | 4 +- src/routes/settings/AdsVast/AdsVast.vue | 78 +- src/routes/settings/Billing/Billing.vue | 102 +- src/routes/settings/DangerZone/DangerZone.vue | 6 +- src/routes/settings/DomainsDns/DomainsDns.vue | 12 +- .../NotificationSettings.vue | 5 +- .../PlayerSettings/PlayerSettings.vue | 5 +- .../billing/BillingPlansSection.vue | 4 +- src/routes/video/CopyVideoModal.vue | 14 +- src/routes/video/DetailVideoModal.vue | 43 +- src/routes/video/Videos.vue | 15 +- src/routes/video/components/CardPopover.vue | 4 +- .../video/components/VideoBulkActions.vue | 2 +- src/routes/video/components/VideoGrid.vue | 4 +- src/routes/video/components/VideoTable.vue | 4 +- src/server/gen/proto/app/v1/account.ts | 1788 ++++ src/server/gen/proto/app/v1/admin.ts | 7156 +++++++++++++++++ src/server/gen/proto/app/v1/auth.ts | 1090 +++ src/server/gen/proto/app/v1/catalog.ts | 1434 ++++ src/server/gen/proto/app/v1/common.ts | 5842 ++++++++++++++ src/server/gen/proto/app/v1/payments.ts | 902 +++ src/server/gen/proto/app/v1/videos.ts | 1283 +++ .../gen/proto/google/protobuf/timestamp.ts | 231 + src/server/middlewares/authenticate.ts | 15 +- src/server/middlewares/setup.ts | 19 +- src/server/modules/merge.ts | 232 - src/server/routes/auth.ts | 253 +- src/server/routes/display.ts | 50 - src/server/routes/manifest.ts | 12 - src/server/routes/merge.ts | 59 - src/server/routes/rpc/auth.ts | 99 + src/server/routes/rpc/index.ts | 71 +- src/server/routes/rpc/me.ts | 724 +- src/server/services/grpcClient.ts | 258 +- src/server/utils/grpcHelper.ts | 90 +- src/server/utils/index.ts | 76 +- src/stores/auth.ts | 421 +- tsconfig.json | 2 +- 66 files changed, 24100 insertions(+), 1562 deletions(-) create mode 100644 src/composables/useAdminRuntimeMqtt.ts create mode 100644 src/routes/admin/AdTemplates.vue create mode 100644 src/routes/admin/Agents.vue create mode 100644 src/routes/admin/Jobs.vue create mode 100644 src/routes/admin/Layout.vue create mode 100644 src/routes/admin/Logs.vue create mode 100644 src/routes/admin/Overview.vue create mode 100644 src/routes/admin/Payments.vue create mode 100644 src/routes/admin/Plans.vue create mode 100644 src/routes/admin/Users.vue create mode 100644 src/routes/admin/Videos.vue create mode 100644 src/routes/admin/components/AdminPlaceholderTable.vue create mode 100644 src/routes/admin/components/AdminSectionShell.vue create mode 100644 src/server/gen/proto/app/v1/account.ts create mode 100644 src/server/gen/proto/app/v1/admin.ts create mode 100644 src/server/gen/proto/app/v1/auth.ts create mode 100644 src/server/gen/proto/app/v1/catalog.ts create mode 100644 src/server/gen/proto/app/v1/common.ts create mode 100644 src/server/gen/proto/app/v1/payments.ts create mode 100644 src/server/gen/proto/app/v1/videos.ts create mode 100644 src/server/gen/proto/google/protobuf/timestamp.ts delete mode 100644 src/server/modules/merge.ts delete mode 100644 src/server/routes/display.ts delete mode 100644 src/server/routes/manifest.ts delete mode 100644 src/server/routes/merge.ts create mode 100644 src/server/routes/rpc/auth.ts diff --git a/bun.lock b/bun.lock index 92e6c8f..552f795 100644 --- a/bun.lock +++ b/bun.lock @@ -11,34 +11,31 @@ "@hiogawa/tiny-rpc": "^0.2.3-pre.18", "@hono/node-server": "^1.19.11", "@hono/zod-validator": "^0.7.6", - "@pinia/colada": "^0.21.7", - "@unhead/vue": "^2.1.10", + "@pinia/colada": "^1.0.0", + "@unhead/vue": "^2.1.12", "@vueuse/core": "^14.2.1", "aws4fetch": "^1.0.20", "clsx": "^2.1.1", - "hono": "^4.12.5", - "i18next": "^25.8.14", + "hono": "^4.12.7", + "i18next": "^25.8.18", "i18next-http-backend": "^3.0.2", "i18next-vue": "^5.4.0", "is-mobile": "^5.0.0", "pinia": "^3.0.4", "tailwind-merge": "^3.5.0", - "vue": "^3.5.29", + "vue": "^3.5.30", "vue-router": "^5.0.3", "zod": "^4.3.6", }, "devDependencies": { - "@cloudflare/vite-plugin": "^1.26.0", "@types/bun": "^1.3.10", - "@types/node": "^25.3.3", "@vitejs/plugin-vue": "^6.0.4", "@vitejs/plugin-vue-jsx": "^5.1.4", - "unocss": "^66.6.5", + "unocss": "^66.6.6", "unplugin-auto-import": "^21.0.0", "unplugin-vue-components": "^31.0.0", "vite": "^8.0.0-beta.16", "vite-ssr-components": "^0.5.2", - "wrangler": "^4.70.0", }, }, }, @@ -101,24 +98,6 @@ "@bufbuild/protobuf": ["@bufbuild/protobuf@2.11.0", "", {}, "sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ=="], - "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.2", "", {}, "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ=="], - - "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.14.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "^1.20260218.0" }, "optionalPeers": ["workerd"] }, "sha512-XKAkWhi1nBdNsSEoNG9nkcbyvfUrSjSf+VYVPfOto3gLTZVc3F4g6RASCMh6IixBKCG2yDgZKQIHGKtjcnLnKg=="], - - "@cloudflare/vite-plugin": ["@cloudflare/vite-plugin@1.26.0", "", { "dependencies": { "@cloudflare/unenv-preset": "2.14.0", "miniflare": "4.20260301.1", "unenv": "2.0.0-rc.24", "wrangler": "4.70.0", "ws": "8.18.0" }, "peerDependencies": { "vite": "^6.1.0 || ^7.0.0" } }, "sha512-F5jSOj9JeWMp9iQa2x+Ocjz++SCfK6Phcca/YLkaddPw5ie7W1VvEWudQ/gxYtRd47mQ/PfCLkE9QGyy6OGEng=="], - - "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260301.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-+kJvwociLrvy1JV9BAvoSVsMEIYD982CpFmo/yMEvBwxDIjltYsLTE8DLi0mCkGsQ8Ygidv2fD9wavzXeiY7OQ=="], - - "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260301.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-PPIetY3e67YBr9O4UhILK8nbm5TqUDl14qx4rwFNrRSBOvlzuczzbd4BqgpAtbGVFxKp1PWpjAnBvGU/OI/tLQ=="], - - "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260301.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Gu5vaVTZuYl3cHa+u5CDzSVDBvSkfNyuAHi6Mdfut7TTUdcb3V5CIcR/mXRSyMXzEy9YxEWIfdKMxOMBjupvYQ=="], - - "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260301.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-igL1pkyCXW6GiGpjdOAvqMi87UW0LMc/+yIQe/CSzuZJm5GzXoAMrwVTkCFnikk6JVGELrM5x0tGYlxa0sk5Iw=="], - - "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260301.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Q0wMJ4kcujXILwQKQFc1jaYamVsNvjuECzvRrTI8OxGFMx2yq9aOsswViE4X1gaS2YQQ5u0JGwuGi5WdT1Lt7A=="], - - "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], - "@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="], "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], @@ -201,56 +180,6 @@ "@iconify/utils": ["@iconify/utils@3.1.0", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@iconify/types": "^2.0.0", "mlly": "^1.8.0" } }, "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw=="], - "@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="], - - "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], - - "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], - - "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], - - "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], - - "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], - - "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], - - "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], - - "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], - - "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], - - "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], - - "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], - - "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], - - "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], - - "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], - - "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], - - "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], - - "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], - - "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], - - "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], - - "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], - - "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], - - "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], - - "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], - - "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], - "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], @@ -311,16 +240,10 @@ "@oxc-project/types": ["@oxc-project/types@0.115.0", "", {}, "sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw=="], - "@pinia/colada": ["@pinia/colada@0.21.7", "", { "peerDependencies": { "pinia": "^2.2.6 || ^3.0.0", "vue": "^3.5.17" } }, "sha512-b8dJgRSjh7o6NnPXuvMbqv6JhoD/m/CwdadKl5SQvygsbUveYCBoqtnWzPch8AEW/UK0I3rFoATE8WrfI2cgKA=="], + "@pinia/colada": ["@pinia/colada@1.0.0", "", { "peerDependencies": { "pinia": "^2.2.6 || ^3.0.0", "vue": "^3.5.17" } }, "sha512-YKSybA6wusFK4CAUPzItoSgPCfScVnnnO2MSlmaaisE/L7luE77GxFyhTzipM8IbvbXh4zkCy97OE7w9WX34wA=="], "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], - "@poppinss/colors": ["@poppinss/colors@4.1.6", "", { "dependencies": { "kleur": "^4.1.5" } }, "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg=="], - - "@poppinss/dumper": ["@poppinss/dumper@0.6.5", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@sindresorhus/is": "^7.0.2", "supports-color": "^10.0.0" } }, "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw=="], - - "@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="], - "@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="], "@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="], @@ -371,10 +294,6 @@ "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.2", "", {}, "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw=="], - "@sindresorhus/is": ["@sindresorhus/is@7.2.0", "", {}, "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw=="], - - "@speed-highlight/core": ["@speed-highlight/core@1.2.14", "", {}, "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA=="], - "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], "@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="], @@ -385,49 +304,49 @@ "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], - "@unhead/vue": ["@unhead/vue@2.1.10", "", { "dependencies": { "hookable": "^6.0.1", "unhead": "2.1.10" }, "peerDependencies": { "vue": ">=3.5.18" } }, "sha512-VP78Onh2HNezLPfhYjfHqn4dxlcQsE6PJgTTs61NksO/thvilNswtgBq0N0MWCLtn43N5akEPGW2y2zxM3PWgQ=="], + "@unhead/vue": ["@unhead/vue@2.1.12", "", { "dependencies": { "hookable": "^6.0.1", "unhead": "2.1.12" }, "peerDependencies": { "vue": ">=3.5.18" } }, "sha512-zEWqg0nZM8acpuTZE40wkeUl8AhIe0tU0OkilVi1D4fmVjACrwoh5HP6aNqJ8kUnKsoy6D+R3Vi/O+fmdNGO7g=="], - "@unocss/cli": ["@unocss/cli@66.6.5", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "@unocss/config": "66.6.4", "@unocss/core": "66.6.5", "@unocss/preset-wind3": "66.6.5", "@unocss/preset-wind4": "66.6.5", "@unocss/transformer-directives": "66.6.5", "cac": "^6.7.14", "chokidar": "^5.0.0", "colorette": "^2.0.20", "consola": "^3.4.2", "magic-string": "^0.30.21", "pathe": "^2.0.3", "perfect-debounce": "^2.1.0", "tinyglobby": "^0.2.15", "unplugin-utils": "^0.3.1" }, "bin": { "unocss": "bin/unocss.mjs" } }, "sha512-UlETATpAZ+A5gOfj+z+BMXuIUcXCMjvlQteQE0VR2Yf0VIxz4sVO4z0VCXwXsxLTMfQiIMDpKVrGeczcYicvTA=="], + "@unocss/cli": ["@unocss/cli@66.6.6", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "@unocss/config": "66.6.6", "@unocss/core": "66.6.6", "@unocss/preset-wind3": "66.6.6", "@unocss/preset-wind4": "66.6.6", "@unocss/transformer-directives": "66.6.6", "cac": "^6.7.14", "chokidar": "^5.0.0", "colorette": "^2.0.20", "consola": "^3.4.2", "magic-string": "^0.30.21", "pathe": "^2.0.3", "perfect-debounce": "^2.1.0", "tinyglobby": "^0.2.15", "unplugin-utils": "^0.3.1" }, "bin": { "unocss": "bin/unocss.mjs" } }, "sha512-78SY8j4hAVelK+vP/adsDGaSjEITasYLFECJLHWxUJSzK+G9UIc5wtL/u4jA+zKvwVkHcDvbkcO5K6wwwpAixg=="], - "@unocss/config": ["@unocss/config@66.6.4", "", { "dependencies": { "@unocss/core": "66.6.4", "colorette": "^2.0.20", "consola": "^3.4.2", "unconfig": "^7.5.0" } }, "sha512-iwHl5FG81cOAMalqigjw21Z2tMa0xjN0doQxnGOLx8KP+BllruXSjBj8CRk3m6Ny9fDxfpFY0ruYbIBA5AGwDQ=="], + "@unocss/config": ["@unocss/config@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "colorette": "^2.0.20", "consola": "^3.4.2", "unconfig": "^7.5.0" } }, "sha512-menlnkqAFX/4wR2aandY8hSqrt01JE+rOzvtQxWaBt8kf1du62b0sS72FE5Z40n6HlEsEbF91N9FCfhnzG6i6g=="], - "@unocss/core": ["@unocss/core@66.6.5", "", {}, "sha512-hzjo+0EF+pNbf+tb0OjRNZRF9BJoKECcZZgtufxRPpWJdlv+aYmNkH1p9fldlHHzYcn3ZqVnnHnmk7HwaolJbg=="], + "@unocss/core": ["@unocss/core@66.6.6", "", {}, "sha512-Sbbx0ZQqmV8K2lg8E+z9MJzWb1MgRtJnvqzxDIrNuBjXasKhbcFt5wEMBtEZJOr63Z4ck0xThhZK53HmYT2jmg=="], - "@unocss/extractor-arbitrary-variants": ["@unocss/extractor-arbitrary-variants@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5" } }, "sha512-wqzRtbyy3I595WCwwb8VBmznJTHWcTdylzVT+WBgacJDjRlT1sXaq2fRlOsHvtTRj1qG70t3PwKc6XgU0hutNg=="], + "@unocss/extractor-arbitrary-variants": ["@unocss/extractor-arbitrary-variants@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6" } }, "sha512-uMzekF2miZRUwSZGvy3yYQiBAcSAs9LiXK8e3NjldxEw8xcRDWgTErxgStRoBeAD6UyzDcg/Cvwtf2guMbtR+g=="], - "@unocss/inspector": ["@unocss/inspector@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5", "@unocss/rule-utils": "66.6.5", "colorette": "^2.0.20", "gzip-size": "^6.0.0", "sirv": "^3.0.2" } }, "sha512-rrXPlSeRfYajEL65FL1Ok9Hfhjy9zvuZZwqXh9P0qCJlou2r2IqDFO/Gf9j5yO89tnKIfJ8ff6jEyqUmzbKSMQ=="], + "@unocss/inspector": ["@unocss/inspector@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "@unocss/rule-utils": "66.6.6", "colorette": "^2.0.20", "gzip-size": "^6.0.0", "sirv": "^3.0.2" } }, "sha512-CpXIsqHwxCXJtUjUz6S29diHCIA+EJ1u5WML/6m2YPI4ObgWAVKrExy09inSg2icS52lFkWWdWQSeqc9kl5W6Q=="], - "@unocss/preset-attributify": ["@unocss/preset-attributify@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5" } }, "sha512-fx+pKMZ0WgT+dfinVaLkNXlx6oZFwtMbZj5O/1SQia0UcfhnyS+G35HYpbgoc9GEAl3DclxxotzZjveZm++9fA=="], + "@unocss/preset-attributify": ["@unocss/preset-attributify@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6" } }, "sha512-3H12UI1rBt60PQy+S4IEeFYWu1/WQFuc2yhJ5mu/RCvX5/qwlIGanBpuh+xzTPXU1fWBlZN68yyO9uWOQgTqZQ=="], - "@unocss/preset-icons": ["@unocss/preset-icons@66.6.5", "", { "dependencies": { "@iconify/utils": "^3.1.0", "@unocss/core": "66.6.5", "ofetch": "^1.5.1" } }, "sha512-03ppAcTWD77w1WZhORT8c9beTHBtWu3cx+c4qfShOfY6LQmZgx5i7DhCij5Wcj/U1zYA4Vrh13CDEmpsdZO3Cw=="], + "@unocss/preset-icons": ["@unocss/preset-icons@66.6.6", "", { "dependencies": { "@iconify/utils": "^3.1.0", "@unocss/core": "66.6.6", "ofetch": "^1.5.1" } }, "sha512-HfIEEqf3jyKexOB2Sux556n0NkPoUftb2H4+Cf7prJvKHopMkZ/OUkXjwvUlxt1e5UpAEaIa0A2Ir7+ApxXoGA=="], - "@unocss/preset-mini": ["@unocss/preset-mini@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5", "@unocss/extractor-arbitrary-variants": "66.6.5", "@unocss/rule-utils": "66.6.5" } }, "sha512-Ber3k2jlE8JP0y507hw/lvdDvcxfY0t4zaGA7hVZdEqlH6Eus/TqIVZ9tdMH4u0VDWYeAs98YV+auUJmMqGXpg=="], + "@unocss/preset-mini": ["@unocss/preset-mini@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "@unocss/extractor-arbitrary-variants": "66.6.6", "@unocss/rule-utils": "66.6.6" } }, "sha512-k+/95PKMPOK57cJcSmz34VkIFem8BlujRRx6/L0Yusw7vLJMh98k0rPhC5s+NomZ/d9ZPgbNylskLhItJlak3w=="], - "@unocss/preset-tagify": ["@unocss/preset-tagify@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5" } }, "sha512-YYk/eg1OWX4Nx7rK1YZLMHXXntzNRDHp6BIInJteQmlXw0sFgrtdMKj7fnxrORsBDHwxWMp4sWEucPvfCtTlVQ=="], + "@unocss/preset-tagify": ["@unocss/preset-tagify@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6" } }, "sha512-KgBXYPYS0g4TVC3NLiIB78YIqUlvDLanz1EHIDo34rOTUfMgY8Uf5VuDJAzMu4Sc0LiwwBJbk6nIG9/Zm7ufWg=="], - "@unocss/preset-typography": ["@unocss/preset-typography@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5", "@unocss/rule-utils": "66.6.5" } }, "sha512-Cb63tdC0P2rgj/4t4DrSCl6RHebNpjUp9FQArg0KCnFnW75nWtKlsKpHuEXpi7KwrgOIx+rjlkwC1bDcsdNLHw=="], + "@unocss/preset-typography": ["@unocss/preset-typography@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "@unocss/rule-utils": "66.6.6" } }, "sha512-SM1km5nqt15z4sTabfOobSC633I5Ol5nnme6JFTra4wiyCUNs+Cg31nJ6jnopWDUT4SEAXqfUH7jKSSoCnI6ZA=="], - "@unocss/preset-uno": ["@unocss/preset-uno@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5", "@unocss/preset-wind3": "66.6.5" } }, "sha512-feZfGyzt3dH4h6yP2kjsx5MuoI1gU7vY/VL5O+ObosaB7HzzOFCsu2WzlvWn/FTRBi+scvdq436hsfflVyHYfQ=="], + "@unocss/preset-uno": ["@unocss/preset-uno@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "@unocss/preset-wind3": "66.6.6" } }, "sha512-40PcBDtlhW7QP7e/WOxC684IhN5T1dXvj1dgx9ZzK+8lEDGjcX7bN2noW4aSenzSrHymeSsMrL/0ltL4ED/5Zw=="], - "@unocss/preset-web-fonts": ["@unocss/preset-web-fonts@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5", "ofetch": "^1.5.1" } }, "sha512-u5jEHYTMeseykqinXd2VY2n7q9yFQlZotREpfSAft8ENNJdV7Yg/6It3lL68zT/k1AV/A8gk94KEuDh0fnoSxQ=="], + "@unocss/preset-web-fonts": ["@unocss/preset-web-fonts@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "ofetch": "^1.5.1" } }, "sha512-5ikwgrJB8VPzKd0bqgGNgYUGix90KFnVtKJPjWTP5qsv3+ZtZnea1rRbAFl8i2t52hg35msNBsQo+40IC3xB6A=="], - "@unocss/preset-wind": ["@unocss/preset-wind@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5", "@unocss/preset-wind3": "66.6.5" } }, "sha512-GLu7LzVF0LHqdZoHFZ8dbsCv8TD5ZH/r10CQbrL5qwmp4a/uyfDEmsre4Nsqim7JktRyXn3HK2XQmTB8AmXpgQ=="], + "@unocss/preset-wind": ["@unocss/preset-wind@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "@unocss/preset-wind3": "66.6.6" } }, "sha512-TMy3lZ35FP/4QqDHOLWZmV+RoOGWUDqnDEOTjOKI1CQARGta0ppUmq+IZMuI1ZJLuOa4OZ9V6SfnwMXwRLgXmw=="], - "@unocss/preset-wind3": ["@unocss/preset-wind3@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5", "@unocss/preset-mini": "66.6.5", "@unocss/rule-utils": "66.6.5" } }, "sha512-0ccQoJmHq4tTnn5C0UKhP598B/gG65AjqlfgfRpwt059yAWYqizGy6MRUGdLklyEK4H06E6qbMBqIjla2rOexQ=="], + "@unocss/preset-wind3": ["@unocss/preset-wind3@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "@unocss/preset-mini": "66.6.6", "@unocss/rule-utils": "66.6.6" } }, "sha512-rk6gPPIQ7z2DVucOqp7XZ4vGpKAuzBV1vtUDvDh5WscxzO/QlqaeTfTALk5YgGpmLaF4+ns6FrTgLjV+wHgHuQ=="], - "@unocss/preset-wind4": ["@unocss/preset-wind4@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5", "@unocss/extractor-arbitrary-variants": "66.6.5", "@unocss/rule-utils": "66.6.5" } }, "sha512-JT57CU60PY3/PHBvxY+UG53I9K+awin/TodZTn4lqQNnF2v6fjkeBKiys9cxeoP4wbHuQWorrW4GqRLNDWIMcw=="], + "@unocss/preset-wind4": ["@unocss/preset-wind4@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "@unocss/extractor-arbitrary-variants": "66.6.6", "@unocss/rule-utils": "66.6.6" } }, "sha512-caTDM9rZSlp4tyPWWAnwMvQr2PXq53LsEYwd3N8zj0ou2hcsqptJvF+mFvyhvGF66x26wWJr/FwuUEhh7qycaw=="], - "@unocss/rule-utils": ["@unocss/rule-utils@66.6.5", "", { "dependencies": { "@unocss/core": "^66.6.5", "magic-string": "^0.30.21" } }, "sha512-eDGXoMebb5aeEAFa2y4gnGLC+CHZPx93JYCt6uvEyf9xOoetwDcZaYC8brWdjaSKn+WVgsfxiZreC7F0rJywOQ=="], + "@unocss/rule-utils": ["@unocss/rule-utils@66.6.6", "", { "dependencies": { "@unocss/core": "^66.6.6", "magic-string": "^0.30.21" } }, "sha512-krWtQKGshOaqQMuxeGq1NOA8NL35VdpYlmQEWOe39BY6TACT51bgQFu40MRfsAIMZZtoGS2YYTrnHojgR92omw=="], - "@unocss/transformer-attributify-jsx": ["@unocss/transformer-attributify-jsx@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5", "oxc-parser": "^0.115.0", "oxc-walker": "^0.7.0" } }, "sha512-/dVaRR7V/2Alskb2rUPmP/lhyb/YCxYyYNxp30kxxW0ew6mZWXQRzsxOJJVmGp23Uw7HxUW63t8zXzUdoI0b+g=="], + "@unocss/transformer-attributify-jsx": ["@unocss/transformer-attributify-jsx@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "oxc-parser": "^0.115.0", "oxc-walker": "^0.7.0" } }, "sha512-NnDchmN2EeFLy4lfVqDgNe9j1+w2RLL2L9zKECXs5g6rDVfeeEK6FNgxSq3XnPcKltjNCy1pF4MaDOROG7r8yA=="], - "@unocss/transformer-compile-class": ["@unocss/transformer-compile-class@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5" } }, "sha512-U/ukk5lyZOFNyz9hVzZBkxciayjgimyfPuQBa5PHSC4W3nDmnFd1zgXzUVaM6KduPmiTExzpJSDgELb2OTbpqg=="], + "@unocss/transformer-compile-class": ["@unocss/transformer-compile-class@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6" } }, "sha512-KKssJxU8fZ9x84yznIirbtta2sB0LN/3lm0bp+Wl1298HITaNiVeG2n26iStQ3N7r240xRN2RarxncSVCMFwWw=="], - "@unocss/transformer-directives": ["@unocss/transformer-directives@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5", "@unocss/rule-utils": "66.6.5", "css-tree": "^3.1.0" } }, "sha512-QgofDdDedNK6dQ246+RXhM6gTzRz7NuetQQ8UnNgArm4PBHngVrrkjCzG1ByDTtEtoE8WR70UMR4Vf5dXTcHPw=="], + "@unocss/transformer-directives": ["@unocss/transformer-directives@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6", "@unocss/rule-utils": "66.6.6", "css-tree": "^3.1.0" } }, "sha512-CReFTcBfMtKkRvzIqxL20VptWt5C1Om27dwoKzyVFBXv0jzViWysbu0y0AQg3bsgD4cFqndFyAGyeL84j0nbKg=="], - "@unocss/transformer-variant-group": ["@unocss/transformer-variant-group@66.6.5", "", { "dependencies": { "@unocss/core": "66.6.5" } }, "sha512-k6vQgn/P7ObHBRYw6o1+xwdQIfwc6b9O5TFFe87UmBB6hJ2zaHWRVuPB6oky7F9Gz8bPfXC3WJuv7UyIwRmBQQ=="], + "@unocss/transformer-variant-group": ["@unocss/transformer-variant-group@66.6.6", "", { "dependencies": { "@unocss/core": "66.6.6" } }, "sha512-j4L/0Tw6AdMVB2dDnuBlDbevyL1/0CAk88a77VF/VjgEIBwB9VXsCCUsxz+2Dohcl7N2GMm7+kpaWA6qt2PSaA=="], - "@unocss/vite": ["@unocss/vite@66.6.5", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "@unocss/config": "66.6.4", "@unocss/core": "66.6.5", "@unocss/inspector": "66.6.5", "chokidar": "^5.0.0", "magic-string": "^0.30.21", "pathe": "^2.0.3", "tinyglobby": "^0.2.15", "unplugin-utils": "^0.3.1" }, "peerDependencies": { "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0" } }, "sha512-J/QZa6h94ordZlZytIKQkuYa+G2GiWiS3y9O1uoHAAN2tzFSkgCXNUif7lHu1h4eCrgC0AOHJSYWg1LIASNDkg=="], + "@unocss/vite": ["@unocss/vite@66.6.6", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "@unocss/config": "66.6.6", "@unocss/core": "66.6.6", "@unocss/inspector": "66.6.6", "chokidar": "^5.0.0", "magic-string": "^0.30.21", "pathe": "^2.0.3", "tinyglobby": "^0.2.15", "unplugin-utils": "^0.3.1" }, "peerDependencies": { "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0" } }, "sha512-DgG7KcUUMtoDhPOlFf2l4dR+66xZ23SdZvTYpikk5nZfLCzZd62vedutD7x0bTR6VpK2YRq39B+F+Z6TktNY/w=="], "@vitejs/plugin-vue": ["@vitejs/plugin-vue@6.0.4", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-rc.2" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "vue": "^3.2.25" } }, "sha512-uM5iXipgYIn13UUQCZNdWkYk+sysBeA97d5mHsAoAt1u/wpN3+zxOmsVJWosuzX+IMGRzeYUNytztrYznboIkQ=="], @@ -441,13 +360,13 @@ "@vue/babel-plugin-resolve-type": ["@vue/babel-plugin-resolve-type@2.0.1", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/parser": "^7.28.4", "@vue/compiler-sfc": "^3.5.22" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ybwgIuRGRRBhOU37GImDoWQoz+TlSqap65qVI6iwg/J7FfLTLmMf97TS7xQH9I7Qtr/gp161kYVdhr1ZMraSYQ=="], - "@vue/compiler-core": ["@vue/compiler-core@3.5.29", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/shared": "3.5.29", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-cuzPhD8fwRHk8IGfmYaR4eEe4cAyJEL66Ove/WZL7yWNL134nqLddSLwNRIsFlnnW1kK+p8Ck3viFnC0chXCXw=="], + "@vue/compiler-core": ["@vue/compiler-core@3.5.30", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/shared": "3.5.30", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw=="], - "@vue/compiler-dom": ["@vue/compiler-dom@3.5.29", "", { "dependencies": { "@vue/compiler-core": "3.5.29", "@vue/shared": "3.5.29" } }, "sha512-n0G5o7R3uBVmVxjTIYcz7ovr8sy7QObFG8OQJ3xGCDNhbG60biP/P5KnyY8NLd81OuT1WJflG7N4KWYHaeeaIg=="], + "@vue/compiler-dom": ["@vue/compiler-dom@3.5.30", "", { "dependencies": { "@vue/compiler-core": "3.5.30", "@vue/shared": "3.5.30" } }, "sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g=="], - "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.29", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/compiler-core": "3.5.29", "@vue/compiler-dom": "3.5.29", "@vue/compiler-ssr": "3.5.29", "@vue/shared": "3.5.29", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-oJZhN5XJs35Gzr50E82jg2cYdZQ78wEwvRO6Y63TvLVTc+6xICzJHP1UIecdSPPYIbkautNBanDiWYa64QSFIA=="], + "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.30", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/compiler-core": "3.5.30", "@vue/compiler-dom": "3.5.30", "@vue/compiler-ssr": "3.5.30", "@vue/shared": "3.5.30", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.8", "source-map-js": "^1.2.1" } }, "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A=="], - "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.29", "", { "dependencies": { "@vue/compiler-dom": "3.5.29", "@vue/shared": "3.5.29" } }, "sha512-Y/ARJZE6fpjzL5GH/phJmsFwx3g6t2KmHKHx5q+MLl2kencADKIrhH5MLF6HHpRMmlRAYBRSvv347Mepf1zVNw=="], + "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.30", "", { "dependencies": { "@vue/compiler-dom": "3.5.30", "@vue/shared": "3.5.30" } }, "sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA=="], "@vue/devtools-api": ["@vue/devtools-api@7.7.9", "", { "dependencies": { "@vue/devtools-kit": "^7.7.9" } }, "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g=="], @@ -455,15 +374,15 @@ "@vue/devtools-shared": ["@vue/devtools-shared@7.7.9", "", { "dependencies": { "rfdc": "^1.4.1" } }, "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA=="], - "@vue/reactivity": ["@vue/reactivity@3.5.29", "", { "dependencies": { "@vue/shared": "3.5.29" } }, "sha512-zcrANcrRdcLtmGZETBxWqIkoQei8HaFpZWx/GHKxx79JZsiZ8j1du0VUJtu4eJjgFvU/iKL5lRXFXksVmI+5DA=="], + "@vue/reactivity": ["@vue/reactivity@3.5.30", "", { "dependencies": { "@vue/shared": "3.5.30" } }, "sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q=="], - "@vue/runtime-core": ["@vue/runtime-core@3.5.29", "", { "dependencies": { "@vue/reactivity": "3.5.29", "@vue/shared": "3.5.29" } }, "sha512-8DpW2QfdwIWOLqtsNcds4s+QgwSaHSJY/SUe04LptianUQ/0xi6KVsu/pYVh+HO3NTVvVJjIPL2t6GdeKbS4Lg=="], + "@vue/runtime-core": ["@vue/runtime-core@3.5.30", "", { "dependencies": { "@vue/reactivity": "3.5.30", "@vue/shared": "3.5.30" } }, "sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg=="], - "@vue/runtime-dom": ["@vue/runtime-dom@3.5.29", "", { "dependencies": { "@vue/reactivity": "3.5.29", "@vue/runtime-core": "3.5.29", "@vue/shared": "3.5.29", "csstype": "^3.2.3" } }, "sha512-AHvvJEtcY9tw/uk+s/YRLSlxxQnqnAkjqvK25ZiM4CllCZWzElRAoQnCM42m9AHRLNJ6oe2kC5DCgD4AUdlvXg=="], + "@vue/runtime-dom": ["@vue/runtime-dom@3.5.30", "", { "dependencies": { "@vue/reactivity": "3.5.30", "@vue/runtime-core": "3.5.30", "@vue/shared": "3.5.30", "csstype": "^3.2.3" } }, "sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw=="], - "@vue/server-renderer": ["@vue/server-renderer@3.5.29", "", { "dependencies": { "@vue/compiler-ssr": "3.5.29", "@vue/shared": "3.5.29" }, "peerDependencies": { "vue": "3.5.29" } }, "sha512-G/1k6WK5MusLlbxSE2YTcqAAezS+VuwHhOvLx2KnQU7G2zCH6KIb+5Wyt6UjMq7a3qPzNEjJXs1hvAxDclQH+g=="], + "@vue/server-renderer": ["@vue/server-renderer@3.5.30", "", { "dependencies": { "@vue/compiler-ssr": "3.5.30", "@vue/shared": "3.5.30" }, "peerDependencies": { "vue": "3.5.30" } }, "sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ=="], - "@vue/shared": ["@vue/shared@3.5.29", "", {}, "sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg=="], + "@vue/shared": ["@vue/shared@3.5.30", "", {}, "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ=="], "@vueuse/core": ["@vueuse/core@14.2.1", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "14.2.1", "@vueuse/shared": "14.2.1" }, "peerDependencies": { "vue": "^3.5.0" } }, "sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ=="], @@ -491,8 +410,6 @@ "birpc": ["birpc@2.9.0", "", {}, "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw=="], - "blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="], - "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="], "bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="], @@ -521,8 +438,6 @@ "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], - "copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="], "cross-fetch": ["cross-fetch@4.0.0", "", { "dependencies": { "node-fetch": "^2.6.12" } }, "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g=="], @@ -547,8 +462,6 @@ "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], - "error-stack-parser-es": ["error-stack-parser-es@1.0.5", "", {}, "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA=="], - "esbuild": ["esbuild@0.27.3", "", { "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" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], @@ -573,11 +486,11 @@ "gzip-size": ["gzip-size@6.0.0", "", { "dependencies": { "duplexer": "^0.1.2" } }, "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q=="], - "hono": ["hono@4.12.5", "", {}, "sha512-3qq+FUBtlTHhtYxbxheZgY8NIFnkkC/MR8u5TTsr7YZ3wixryQ3cCwn3iZbg8p8B88iDBBAYSfZDS75t8MN7Vg=="], + "hono": ["hono@4.12.7", "", {}, "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw=="], "hookable": ["hookable@6.0.1", "", {}, "sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw=="], - "i18next": ["i18next@25.8.14", "", { "dependencies": { "@babel/runtime": "^7.28.4" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-paMUYkfWJMsWPeE/Hejcw+XLhHrQPehem+4wMo+uELnvIwvCG019L9sAIljwjCmEMtFQQO3YeitJY8Kctei3iA=="], + "i18next": ["i18next@25.8.18", "", { "dependencies": { "@babel/runtime": "^7.28.6" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-lzY5X83BiL5AP77+9DydbrqkQHFN9hUzWGjqjLpPcp5ZOzuu1aSoKaU3xbBLSjWx9dAzW431y+d+aogxOZaKRA=="], "i18next-http-backend": ["i18next-http-backend@3.0.2", "", { "dependencies": { "cross-fetch": "4.0.0" } }, "sha512-PdlvPnvIp4E1sYi46Ik4tBYh/v/NbYfFFgTjkwFl0is8A18s7/bx9aXqsrOax9WUbeNS6mD2oix7Z0yGGf6m5g=="], @@ -597,8 +510,6 @@ "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], - "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], - "lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="], "lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="], @@ -643,8 +554,6 @@ "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], - "miniflare": ["miniflare@4.20260301.1", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.18.2", "workerd": "1.20260301.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-fqkHx0QMKswRH9uqQQQOU/RoaS3Wjckxy3CUX3YGJr0ZIMu7ObvI+NovdYi6RIsSPthNtq+3TPmRNxjeRiasog=="], - "mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="], "mlly": ["mlly@1.8.0", "", { "dependencies": { "acorn": "^8.15.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.1" } }, "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g=="], @@ -673,8 +582,6 @@ "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], - "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], - "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], "perfect-debounce": ["perfect-debounce@2.1.0", "", {}, "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g=="], @@ -707,8 +614,6 @@ "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "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" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], - "sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], @@ -725,8 +630,6 @@ "superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="], - "supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], - "tailwind-merge": ["tailwind-merge@3.5.0", "", {}, "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A=="], "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], @@ -747,17 +650,13 @@ "unconfig-core": ["unconfig-core@7.5.0", "", { "dependencies": { "@quansync/fs": "^1.0.0", "quansync": "^1.0.0" } }, "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w=="], - "undici": ["undici@7.18.2", "", {}, "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw=="], - "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], - "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "^2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], - - "unhead": ["unhead@2.1.10", "", { "dependencies": { "hookable": "^6.0.1" } }, "sha512-We8l9uNF8zz6U8lfQaVG70+R/QBfQx1oPIgXin4BtZnK2IQpz6yazQ0qjMNVBDw2ADgF2ea58BtvSK+XX5AS7g=="], + "unhead": ["unhead@2.1.12", "", { "dependencies": { "hookable": "^6.0.1" } }, "sha512-iTHdWD9ztTunOErtfUFk6Wr11BxvzumcYJ0CzaSCBUOEtg+DUZ9+gnE99i8QkLFT2q1rZD48BYYGXpOZVDLYkA=="], "unimport": ["unimport@5.6.0", "", { "dependencies": { "acorn": "^8.15.0", "escape-string-regexp": "^5.0.0", "estree-walker": "^3.0.3", "local-pkg": "^1.1.2", "magic-string": "^0.30.21", "mlly": "^1.8.0", "pathe": "^2.0.3", "picomatch": "^4.0.3", "pkg-types": "^2.3.0", "scule": "^1.3.0", "strip-literal": "^3.1.0", "tinyglobby": "^0.2.15", "unplugin": "^2.3.11", "unplugin-utils": "^0.3.1" } }, "sha512-8rqAmtJV8o60x46kBAJKtHpJDJWkA2xcBqWKPI14MgUb05o1pnpnCnXSxedUXyeq7p8fR5g3pTo2BaswZ9lD9A=="], - "unocss": ["unocss@66.6.5", "", { "dependencies": { "@unocss/cli": "66.6.5", "@unocss/core": "66.6.5", "@unocss/preset-attributify": "66.6.5", "@unocss/preset-icons": "66.6.5", "@unocss/preset-mini": "66.6.5", "@unocss/preset-tagify": "66.6.5", "@unocss/preset-typography": "66.6.5", "@unocss/preset-uno": "66.6.5", "@unocss/preset-web-fonts": "66.6.5", "@unocss/preset-wind": "66.6.5", "@unocss/preset-wind3": "66.6.5", "@unocss/preset-wind4": "66.6.5", "@unocss/transformer-attributify-jsx": "66.6.5", "@unocss/transformer-compile-class": "66.6.5", "@unocss/transformer-directives": "66.6.5", "@unocss/transformer-variant-group": "66.6.5", "@unocss/vite": "66.6.5" }, "peerDependencies": { "@unocss/astro": "66.6.5", "@unocss/postcss": "66.6.5", "@unocss/webpack": "66.6.5" }, "optionalPeers": ["@unocss/astro", "@unocss/postcss", "@unocss/webpack"] }, "sha512-WlpPlV7yAzEPREcwaKeacP+1jOm6ImhyKJRkK18tIW2b2BRZZDKln7X8P+NzJtAr0kziNY/ttUKZNZRnSmzP1A=="], + "unocss": ["unocss@66.6.6", "", { "dependencies": { "@unocss/cli": "66.6.6", "@unocss/core": "66.6.6", "@unocss/preset-attributify": "66.6.6", "@unocss/preset-icons": "66.6.6", "@unocss/preset-mini": "66.6.6", "@unocss/preset-tagify": "66.6.6", "@unocss/preset-typography": "66.6.6", "@unocss/preset-uno": "66.6.6", "@unocss/preset-web-fonts": "66.6.6", "@unocss/preset-wind": "66.6.6", "@unocss/preset-wind3": "66.6.6", "@unocss/preset-wind4": "66.6.6", "@unocss/transformer-attributify-jsx": "66.6.6", "@unocss/transformer-compile-class": "66.6.6", "@unocss/transformer-directives": "66.6.6", "@unocss/transformer-variant-group": "66.6.6", "@unocss/vite": "66.6.6" }, "peerDependencies": { "@unocss/astro": "66.6.6", "@unocss/postcss": "66.6.6", "@unocss/webpack": "66.6.6" }, "optionalPeers": ["@unocss/astro", "@unocss/postcss", "@unocss/webpack"] }, "sha512-PRKK945e2oZKHV664MA5Z9CDHbvY/V79IvTOUWKZ514jpl3UsJU3sS+skgxmKJSmwrWvXE5OVcmPthJrD/7vxg=="], "unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="], @@ -775,7 +674,7 @@ "vite-ssr-components": ["vite-ssr-components@0.5.2", "", { "dependencies": { "@babel/parser": "^7.27.2", "@babel/traverse": "^7.27.1", "picomatch": "^4.0.2" } }, "sha512-1a8YThRwyyu1gGjc1Ral9Q4uS+n0D4GydhbkVd9c1SA1YNgXyrOizttped87C1ItEznQzhiCyQjaOcYnXa0zMA=="], - "vue": ["vue@3.5.29", "", { "dependencies": { "@vue/compiler-dom": "3.5.29", "@vue/compiler-sfc": "3.5.29", "@vue/runtime-dom": "3.5.29", "@vue/server-renderer": "3.5.29", "@vue/shared": "3.5.29" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-BZqN4Ze6mDQVNAni0IHeMJ5mwr8VAJ3MQC9FmprRhcBYENw+wOAAjRj8jfmN6FLl0j96OXbR+CjWhmAmM+QGnA=="], + "vue": ["vue@3.5.30", "", { "dependencies": { "@vue/compiler-dom": "3.5.30", "@vue/compiler-sfc": "3.5.30", "@vue/runtime-dom": "3.5.30", "@vue/server-renderer": "3.5.30", "@vue/shared": "3.5.30" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg=="], "vue-router": ["vue-router@5.0.3", "", { "dependencies": { "@babel/generator": "^7.28.6", "@vue-macros/common": "^3.1.1", "@vue/devtools-api": "^8.0.6", "ast-walker-scope": "^0.8.3", "chokidar": "^5.0.0", "json5": "^2.2.3", "local-pkg": "^1.1.2", "magic-string": "^0.30.21", "mlly": "^1.8.0", "muggle-string": "^0.4.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "scule": "^1.3.0", "tinyglobby": "^0.2.15", "unplugin": "^3.0.0", "unplugin-utils": "^0.3.1", "yaml": "^2.8.2" }, "peerDependencies": { "@pinia/colada": ">=0.21.2", "@vue/compiler-sfc": "^3.5.17", "pinia": "^3.0.4", "vue": "^3.5.0" }, "optionalPeers": ["@pinia/colada", "@vue/compiler-sfc", "pinia"] }, "sha512-nG1c7aAFac7NYj8Hluo68WyWfc41xkEjaR0ViLHCa3oDvTQ/nIuLJlXJX1NUPw/DXzx/8+OKMng045HHQKQKWw=="], @@ -785,14 +684,8 @@ "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], - "workerd": ["workerd@1.20260301.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260301.1", "@cloudflare/workerd-darwin-arm64": "1.20260301.1", "@cloudflare/workerd-linux-64": "1.20260301.1", "@cloudflare/workerd-linux-arm64": "1.20260301.1", "@cloudflare/workerd-windows-64": "1.20260301.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-oterQ1IFd3h7PjCfT4znSFOkJCvNQ6YMOyZ40YsnO3nrSpgB4TbJVYWFOnyJAw71/RQuupfVqZZWKvsy8GO3fw=="], - - "wrangler": ["wrangler@4.70.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.14.0", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260301.1", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260301.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260226.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-PNDZ9o4e+B5x+1bUbz62Hmwz6G9lw+I9pnYe/AguLddJFjfIyt2cmFOUOb3eOZSoXsrhcEPUg2YidYIbVwUkfw=="], - "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], - "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], @@ -803,24 +696,24 @@ "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], - "youch": ["youch@4.1.0-beta.10", "", { "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" } }, "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ=="], - - "youch-core": ["youch-core@0.3.3", "", { "dependencies": { "@poppinss/exception": "^1.2.2", "error-stack-parser-es": "^1.0.5" } }, "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA=="], - "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], - "@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], - "@quansync/fs/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], - "@unocss/config/@unocss/core": ["@unocss/core@66.6.4", "", {}, "sha512-Fii3lhVJVFrKUz6hMGAkq3sXBfNnXB2G8bldNHuBHJpDAoP1F0oO/SU/oSqSjCYvtcD5RtOn8qwzcHuuN3B/mg=="], - "@vitejs/plugin-vue-jsx/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.5", "", {}, "sha512-RxlLX/DPoarZ9PtxVrQgZhPoor987YtKQqCo5zkjX+0S0yLJ7Vv515Wk6+xtTL67VONKJKxETWZwuZjss2idYw=="], + "@vue-macros/common/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.29", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/compiler-core": "3.5.29", "@vue/compiler-dom": "3.5.29", "@vue/compiler-ssr": "3.5.29", "@vue/shared": "3.5.29", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-oJZhN5XJs35Gzr50E82jg2cYdZQ78wEwvRO6Y63TvLVTc+6xICzJHP1UIecdSPPYIbkautNBanDiWYa64QSFIA=="], + + "@vue/babel-plugin-jsx/@vue/shared": ["@vue/shared@3.5.29", "", {}, "sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg=="], + + "@vue/babel-plugin-resolve-type/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.29", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/compiler-core": "3.5.29", "@vue/compiler-dom": "3.5.29", "@vue/compiler-ssr": "3.5.29", "@vue/shared": "3.5.29", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-oJZhN5XJs35Gzr50E82jg2cYdZQ78wEwvRO6Y63TvLVTc+6xICzJHP1UIecdSPPYIbkautNBanDiWYa64QSFIA=="], + "@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + "@vue/compiler-sfc/postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], + "@vue/devtools-kit/hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="], "@vue/devtools-kit/perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="], @@ -829,8 +722,6 @@ "rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.6", "", {}, "sha512-Y0+JT8Mi1mmW08K6HieG315XNRu4L0rkfCpA364HtytjgiqYnMYRdFPcxRl+BQQqNXzecL2S9nii+RUpO93XIA=="], - "sharp/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], - "strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], "unconfig/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], @@ -841,6 +732,26 @@ "vue-router/unplugin": ["unplugin@3.0.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg=="], + "@vue-macros/common/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.29", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/shared": "3.5.29", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-cuzPhD8fwRHk8IGfmYaR4eEe4cAyJEL66Ove/WZL7yWNL134nqLddSLwNRIsFlnnW1kK+p8Ck3viFnC0chXCXw=="], + + "@vue-macros/common/@vue/compiler-sfc/@vue/compiler-dom": ["@vue/compiler-dom@3.5.29", "", { "dependencies": { "@vue/compiler-core": "3.5.29", "@vue/shared": "3.5.29" } }, "sha512-n0G5o7R3uBVmVxjTIYcz7ovr8sy7QObFG8OQJ3xGCDNhbG60biP/P5KnyY8NLd81OuT1WJflG7N4KWYHaeeaIg=="], + + "@vue-macros/common/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.29", "", { "dependencies": { "@vue/compiler-dom": "3.5.29", "@vue/shared": "3.5.29" } }, "sha512-Y/ARJZE6fpjzL5GH/phJmsFwx3g6t2KmHKHx5q+MLl2kencADKIrhH5MLF6HHpRMmlRAYBRSvv347Mepf1zVNw=="], + + "@vue-macros/common/@vue/compiler-sfc/@vue/shared": ["@vue/shared@3.5.29", "", {}, "sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg=="], + + "@vue-macros/common/@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "@vue/babel-plugin-resolve-type/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.29", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/shared": "3.5.29", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-cuzPhD8fwRHk8IGfmYaR4eEe4cAyJEL66Ove/WZL7yWNL134nqLddSLwNRIsFlnnW1kK+p8Ck3viFnC0chXCXw=="], + + "@vue/babel-plugin-resolve-type/@vue/compiler-sfc/@vue/compiler-dom": ["@vue/compiler-dom@3.5.29", "", { "dependencies": { "@vue/compiler-core": "3.5.29", "@vue/shared": "3.5.29" } }, "sha512-n0G5o7R3uBVmVxjTIYcz7ovr8sy7QObFG8OQJ3xGCDNhbG60biP/P5KnyY8NLd81OuT1WJflG7N4KWYHaeeaIg=="], + + "@vue/babel-plugin-resolve-type/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.29", "", { "dependencies": { "@vue/compiler-dom": "3.5.29", "@vue/shared": "3.5.29" } }, "sha512-Y/ARJZE6fpjzL5GH/phJmsFwx3g6t2KmHKHx5q+MLl2kencADKIrhH5MLF6HHpRMmlRAYBRSvv347Mepf1zVNw=="], + + "@vue/babel-plugin-resolve-type/@vue/compiler-sfc/@vue/shared": ["@vue/shared@3.5.29", "", {}, "sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg=="], + + "@vue/babel-plugin-resolve-type/@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], "vue-router/@vue/devtools-api/@vue/devtools-kit": ["@vue/devtools-kit@8.0.6", "", { "dependencies": { "@vue/devtools-shared": "^8.0.6", "birpc": "^2.6.1", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^2.0.0", "speakingurl": "^14.0.1", "superjson": "^2.2.2" } }, "sha512-9zXZPTJW72OteDXeSa5RVML3zWDCRcO5t77aJqSs228mdopYj5AiTpihozbsfFJ0IodfNs7pSgOGO3qfCuxDtw=="], diff --git a/package.json b/package.json index 52d9d60..10c1ba7 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,7 @@ "scripts": { "dev": "bunx --bun vite", "build": "bunx --bun vite build", - "preview": "bunx --bun vite preview", - "deploy": "wrangler deploy", - "cf-typegen": "wrangler types --env-interface CloudflareBindings", - "tail": "wrangler tail" + "preview": "bunx --bun vite preview" }, "dependencies": { "@bufbuild/protobuf": "^2.11.0", @@ -16,33 +13,30 @@ "@hiogawa/tiny-rpc": "^0.2.3-pre.18", "@hono/node-server": "^1.19.11", "@hono/zod-validator": "^0.7.6", - "@pinia/colada": "^0.21.7", - "@unhead/vue": "^2.1.10", + "@pinia/colada": "^1.0.0", + "@unhead/vue": "^2.1.12", "@vueuse/core": "^14.2.1", "aws4fetch": "^1.0.20", "clsx": "^2.1.1", - "hono": "^4.12.5", - "i18next": "^25.8.14", + "hono": "^4.12.7", + "i18next": "^25.8.18", "i18next-http-backend": "^3.0.2", "i18next-vue": "^5.4.0", "is-mobile": "^5.0.0", "pinia": "^3.0.4", "tailwind-merge": "^3.5.0", - "vue": "^3.5.29", + "vue": "^3.5.30", "vue-router": "^5.0.3", "zod": "^4.3.6" }, "devDependencies": { - "@cloudflare/vite-plugin": "^1.26.0", "@types/bun": "^1.3.10", - "@types/node": "^25.3.3", "@vitejs/plugin-vue": "^6.0.4", "@vitejs/plugin-vue-jsx": "^5.1.4", - "unocss": "^66.6.5", + "unocss": "^66.6.6", "unplugin-auto-import": "^21.0.0", "unplugin-vue-components": "^31.0.0", "vite": "^8.0.0-beta.16", - "vite-ssr-components": "^0.5.2", - "wrangler": "^4.70.0" + "vite-ssr-components": "^0.5.2" } } diff --git a/src/api/httpClientAdapter.server.ts b/src/api/httpClientAdapter.server.ts index 5ac17f6..2453acd 100644 --- a/src/api/httpClientAdapter.server.ts +++ b/src/api/httpClientAdapter.server.ts @@ -3,6 +3,7 @@ import { Result } from "@hiogawa/utils"; import { tryGetContext } from "hono/context-storage"; const GET_PAYLOAD_PARAM = "payload"; +export const baseAPIURL = "https://api.pipic.fun"; export function httpClientAdapter(opts: { url: string; diff --git a/src/api/rpcclient.ts b/src/api/rpcclient.ts index 223819a..fdae708 100644 --- a/src/api/rpcclient.ts +++ b/src/api/rpcclient.ts @@ -1,19 +1,20 @@ -import { - proxyTinyRpc, - TinyRpcClientAdapter, - TinyRpcError, -} from "@hiogawa/tiny-rpc"; -import { Result } from "@hiogawa/utils"; +import { proxyTinyRpc } from "@hiogawa/tiny-rpc"; import { httpClientAdapter } from "@httpClientAdapter"; -// console.log("httpClientAdapter module:", httpClientAdapter.toString()); -declare let __host__: string; +import type { RpcRoutes } from "@/server/routes/rpc"; + const endpoint = "/rpc"; +const publicEndpoint = "/rpc-public"; const url = import.meta.env.SSR ? "http://localhost" : ""; -import { type RpcRoutes } from "@/server/routes/rpc"; +const publicMethods = ["login", "register", "forgotPassword", "resetPassword", "getGoogleLoginUrl"]; export const client = proxyTinyRpc({ - adapter: httpClientAdapter({ - url: url + endpoint, - pathsForGET: [], - }), -}); \ No newline at end of file + adapter: { + send: async (data) => { + const targetEndpoint = publicMethods.includes(data.path) ? publicEndpoint : endpoint; + return await httpClientAdapter({ + url: `${url}${targetEndpoint}`, + pathsForGET: ["health"], + }).send(data); + }, + }, +}); diff --git a/src/components/DashboardNav.vue b/src/components/DashboardNav.vue index b1450e3..e9c2494 100644 --- a/src/components/DashboardNav.vue +++ b/src/components/DashboardNav.vue @@ -1,12 +1,13 @@ diff --git a/src/composables/useAdminRuntimeMqtt.ts b/src/composables/useAdminRuntimeMqtt.ts new file mode 100644 index 0000000..e8e0979 --- /dev/null +++ b/src/composables/useAdminRuntimeMqtt.ts @@ -0,0 +1,58 @@ +import { TinyMqttClient } from "@/lib/liteMqtt"; +import { useAuthStore } from "@/stores/auth"; +import { computed, onBeforeUnmount, watch } from "vue"; + +type RuntimeMessage = { + topic: string; + payload: any; +}; + +const mqttBrokerUrl = "wss://mqtt-dashboard.com:8884/mqtt"; + +export function useAdminRuntimeMqtt(onMessage: (message: RuntimeMessage) => void) { + const auth = useAuthStore(); + let client: TinyMqttClient | undefined; + + const isAdmin = computed(() => auth.user?.role?.toUpperCase?.() === "ADMIN"); + + const connect = () => { + if (import.meta.env.SSR || !isAdmin.value) return; + disconnect(); + client = new TinyMqttClient( + mqttBrokerUrl, + ["picpic/events", "picpic/logs/#", "picpic/job/+"], + (topic, raw) => { + try { + onMessage({ topic, payload: JSON.parse(raw) }); + } catch { + onMessage({ topic, payload: raw }); + } + }, + ); + client.connect(); + }; + + const disconnect = () => { + client?.disconnect(); + client = undefined; + }; + + const stopWatch = watch( + () => [auth.user?.id, auth.user?.role], + () => { + if (isAdmin.value) { + connect(); + } else { + disconnect(); + } + }, + { immediate: true }, + ); + + onBeforeUnmount(() => { + stopWatch(); + disconnect(); + }); + + return { disconnect }; +} diff --git a/src/composables/useNotifications.ts b/src/composables/useNotifications.ts index 99587e4..5beee40 100644 --- a/src/composables/useNotifications.ts +++ b/src/composables/useNotifications.ts @@ -1,4 +1,4 @@ -import { client } from '@/api/client'; +import { client as rpcClient } from '@/api/rpcclient'; import { computed, ref } from 'vue'; import { useTranslation } from 'i18next-vue'; @@ -24,9 +24,7 @@ type NotificationApiItem = { read?: boolean; actionUrl?: string; actionLabel?: string; - action_url?: string; - action_label?: string; - created_at?: string; + createdAt?: string; }; const notifications = ref([]); @@ -69,18 +67,18 @@ export function useNotifications() { type: normalizeType(item.type), title: item.title || '', message: item.message || '', - time: formatRelativeTime(item.created_at), + time: formatRelativeTime(item.createdAt), read: Boolean(item.read), - actionUrl: item.actionUrl || item.action_url || undefined, - actionLabel: item.actionLabel || item.action_label || undefined, - createdAt: item.created_at, + actionUrl: item.actionUrl || undefined, + actionLabel: item.actionLabel || undefined, + createdAt: item.createdAt, }); const fetchNotifications = async () => { loading.value = true; try { - const response = await client.notifications.notificationsList({ baseUrl: '/r' }); - notifications.value = (((response.data as any)?.data?.notifications || []) as NotificationApiItem[]).map(mapNotification); + const response = await rpcClient.listNotifications(); + notifications.value = (response.notifications || []).map(mapNotification); loaded.value = true; return notifications.value; } finally { @@ -90,24 +88,24 @@ export function useNotifications() { const markRead = async (id: string) => { if (!id) return; - await client.notifications.readCreate(id, { baseUrl: '/r' }); + await rpcClient.markNotificationRead({ id }); const item = notifications.value.find(notification => notification.id === id); if (item) item.read = true; }; const deleteNotification = async (id: string) => { if (!id) return; - await client.notifications.notificationsDelete2(id, { baseUrl: '/r' }); + await rpcClient.deleteNotification({ id }); notifications.value = notifications.value.filter(notification => notification.id !== id); }; const markAllRead = async () => { - await client.notifications.readAllCreate({ baseUrl: '/r' }); + await rpcClient.markAllNotificationsRead(); notifications.value = notifications.value.map(item => ({ ...item, read: true })); }; const clearAll = async () => { - await client.notifications.notificationsDelete({ baseUrl: '/r' }); + await rpcClient.clearNotifications(); notifications.value = []; }; diff --git a/src/composables/useSettingsPreferencesQuery.ts b/src/composables/useSettingsPreferencesQuery.ts index c79e2e1..28c39e8 100644 --- a/src/composables/useSettingsPreferencesQuery.ts +++ b/src/composables/useSettingsPreferencesQuery.ts @@ -1,4 +1,6 @@ -import { client, type PreferencesSettingsPreferencesRequest } from '@/api/client'; +import { client as rpcClient } from '@/api/rpcclient'; +import type { Preferences } from '@/server/gen/proto/app/v1/common'; +import type { UpdatePreferencesRequest } from '@/server/gen/proto/app/v1/account'; import { useQuery } from '@pinia/colada'; export const SETTINGS_PREFERENCES_QUERY_KEY = ['settings', 'preferences'] as const; @@ -36,9 +38,7 @@ export type PlayerSettingsDraft = { }; type PreferencesResponse = { - data?: { - preferences?: PreferencesSettingsPreferencesRequest; - }; + preferences?: Preferences; }; const DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT: SettingsPreferencesSnapshot = { @@ -56,17 +56,17 @@ const DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT: SettingsPreferencesSnapshot = { }; const normalizePreferencesSnapshot = (responseData: unknown): SettingsPreferencesSnapshot => { - const preferences = (responseData as PreferencesResponse | undefined)?.data?.preferences; + const preferences = (responseData as PreferencesResponse | undefined)?.preferences; return { - emailNotifications: preferences?.email_notifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.emailNotifications, - pushNotifications: preferences?.push_notifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.pushNotifications, - marketingNotifications: preferences?.marketing_notifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.marketingNotifications, - telegramNotifications: preferences?.telegram_notifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.telegramNotifications, + emailNotifications: preferences?.emailNotifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.emailNotifications, + pushNotifications: preferences?.pushNotifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.pushNotifications, + marketingNotifications: preferences?.marketingNotifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.marketingNotifications, + telegramNotifications: preferences?.telegramNotifications ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.telegramNotifications, autoplay: preferences?.autoplay ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.autoplay, loop: preferences?.loop ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.loop, muted: preferences?.muted ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.muted, - showControls: preferences?.show_controls ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.showControls, + showControls: preferences?.showControls ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.showControls, pip: preferences?.pip ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.pip, airplay: preferences?.airplay ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.airplay, chromecast: preferences?.chromecast ?? DEFAULT_SETTINGS_PREFERENCES_SNAPSHOT.chromecast, @@ -97,20 +97,20 @@ export const createPlayerSettingsDraft = ( export const toNotificationPreferencesPayload = ( draft: NotificationSettingsDraft, -): PreferencesSettingsPreferencesRequest => ({ - email_notifications: draft.email, - push_notifications: draft.push, - marketing_notifications: draft.marketing, - telegram_notifications: draft.telegram, +): UpdatePreferencesRequest => ({ + emailNotifications: draft.email, + pushNotifications: draft.push, + marketingNotifications: draft.marketing, + telegramNotifications: draft.telegram, }); export const toPlayerPreferencesPayload = ( draft: PlayerSettingsDraft, -): PreferencesSettingsPreferencesRequest => ({ +): UpdatePreferencesRequest => ({ autoplay: draft.autoplay, loop: draft.loop, muted: draft.muted, - show_controls: draft.showControls, + showControls: draft.showControls, pip: draft.pip, airplay: draft.airplay, chromecast: draft.chromecast, @@ -120,8 +120,8 @@ export function useSettingsPreferencesQuery() { return useQuery({ key: () => SETTINGS_PREFERENCES_QUERY_KEY, query: async () => { - const response = await client.settings.preferencesList({ baseUrl: '/r' }); - return normalizePreferencesSnapshot(response.data); + const response = await rpcClient.getPreferences(); + return normalizePreferencesSnapshot(response); }, }); } diff --git a/src/composables/useUploadQueue.ts b/src/composables/useUploadQueue.ts index 76c3e53..30a56d4 100644 --- a/src/composables/useUploadQueue.ts +++ b/src/composables/useUploadQueue.ts @@ -1,4 +1,4 @@ -import { client, ContentType } from '@/api/client'; +import { client as rpcClient } from '@/api/rpcclient'; import { computed, ref } from 'vue'; export interface QueueItem { @@ -11,34 +11,24 @@ export interface QueueItem { total?: string; speed?: string; thumbnail?: string; - file?: File; // Keep reference to file for local uploads - url?: string; // Keep reference to url for remote uploads + file?: File; + url?: string; playbackUrl?: string; videoId?: string; - mergeId?: string; - // Upload chunk tracking - activeChunks?: number; - uploadedUrls?: string[]; + objectKey?: string; cancelled?: boolean; } const items = ref([]); - -// Upload limits const MAX_ITEMS = 5; - -// Chunk upload configuration -const CHUNK_SIZE = 90 * 1024 * 1024; // 90MB per chunk -const MAX_PARALLEL = 3; const MAX_RETRY = 3; -// Track active XHRs per item id so we can abort them on cancel -const activeXhrs = new Map>(); +const activeXhrs = new Map(); const abortItem = (id: string) => { - const xhrs = activeXhrs.get(id); - if (xhrs) { - xhrs.forEach(xhr => xhr.abort()); + const xhr = activeXhrs.get(id); + if (xhr) { + xhr.abort(); activeXhrs.delete(id); } }; @@ -70,11 +60,9 @@ export function useUploadQueue() { uploaded: '0 MB', total: formatSize(file.size), speed: '0 MB/s', - file: file, + file, thumbnail: undefined, - activeChunks: 0, - uploadedUrls: [], - cancelled: false + cancelled: false, })); items.value.push(...newItems); @@ -94,10 +82,8 @@ export function useUploadQueue() { uploaded: '0 MB', total: t('upload.queueItem.unknownSize'), speed: '0 MB/s', - url: url, - activeChunks: 0, - uploadedUrls: [], - cancelled: false + url, + cancelled: false, })); items.value.push(...newItems); @@ -118,7 +104,6 @@ export function useUploadQueue() { if (item) { item.cancelled = true; item.status = 'error'; - item.activeChunks = 0; item.speed = '0 MB/s'; } }; @@ -127,7 +112,7 @@ export function useUploadQueue() { items.value.forEach(item => { if (item.status === 'pending') { if (item.type === 'local') { - startChunkUpload(item.id); + startUpload(item.id); } else { startMockRemoteFetch(item.id); } @@ -135,204 +120,147 @@ export function useUploadQueue() { }); }; - // Real Chunk Upload Logic - const startChunkUpload = async (id: string) => { + const startUpload = async (id: string) => { const item = items.value.find(i => i.id === id); if (!item || !item.file) return; item.status = 'uploading'; - item.activeChunks = 0; - item.uploadedUrls = []; - - const file = item.file; - const totalChunks = Math.ceil(file.size / CHUNK_SIZE); - const progressMap = new Map(); // chunk index -> uploaded bytes - const queue: number[] = Array.from({ length: totalChunks }, (_, i) => i); - - const updateProgress = () => { - let totalUploaded = 0; - progressMap.forEach(value => { - totalUploaded += value; - }); - const percent = Math.min((totalUploaded / file.size) * 100, 100); - item.progress = parseFloat(percent.toFixed(1)); - item.uploaded = formatSize(totalUploaded); - - // Calculate speed (simplified) - const currentSpeed = item.activeChunks ? item.activeChunks * 2 * 1024 * 1024 : 0; - item.speed = formatSize(currentSpeed) + '/s'; - }; - - const processQueue = async () => { - if (item.cancelled) return; - - const activePromises: Promise[] = []; - - while ((item.activeChunks || 0) < MAX_PARALLEL && queue.length > 0) { - const index = queue.shift()!; - item.activeChunks = (item.activeChunks || 0) + 1; - - const promise = uploadChunk(index, file, progressMap, updateProgress, item) - .then(() => { - item.activeChunks = (item.activeChunks || 0) - 1; - }); - activePromises.push(promise); - } - - if (activePromises.length > 0) { - await Promise.all(activePromises); - await processQueue(); - } - }; + item.progress = 0; + item.uploaded = '0 MB'; + item.speed = '0 MB/s'; try { - await processQueue(); + const response = await rpcClient.getUploadUrl({ filename: item.file.name }); + if (!response.uploadUrl || !response.key) { + throw new Error(t('upload.errors.mergeFailed')); + } + + item.objectKey = response.key; + await uploadFileToPresignedUrl(item, response.uploadUrl); if (!item.cancelled) { item.status = 'processing'; await completeUpload(item); } } catch (error) { - item.status = 'error'; - console.error('Upload failed:', error); + if (!item.cancelled) { + item.status = 'error'; + console.error('Upload failed:', error); + } } }; - const uploadChunk = ( - index: number, - file: File, - progressMap: Map, - updateProgress: () => void, - item: QueueItem - ): Promise => { - return new Promise((resolve, reject) => { - let retry = 0; + const uploadFileToPresignedUrl = async (item: QueueItem, uploadUrl: string) => { + if (!item.file) return; - const attempt = () => { - if (item.cancelled) return resolve(); - - const start = index * CHUNK_SIZE; - const end = Math.min(start + CHUNK_SIZE, file.size); - const chunk = file.slice(start, end); - - const formData = new FormData(); - formData.append('file', chunk, file.name); - - const xhr = new XMLHttpRequest(); - xhr.open('POST', 'https://tmpfiles.org/api/v1/upload'); - - // Register this XHR so it can be aborted on cancel - if (!activeXhrs.has(item.id)) activeXhrs.set(item.id, new Set()); - activeXhrs.get(item.id)!.add(xhr); - - const unregister = () => activeXhrs.get(item.id)?.delete(xhr); - - xhr.upload.onprogress = (e) => { - if (e.lengthComputable) { - progressMap.set(index, e.loaded); - updateProgress(); - } - }; - - xhr.onload = function () { - unregister(); - if (item.cancelled) return resolve(); - if (xhr.status === 200) { - try { - const res = JSON.parse(xhr.responseText); - if (res.status === 'success') { - progressMap.set(index, chunk.size); - if (item.uploadedUrls) { - item.uploadedUrls[index] = res.data.url; - } - updateProgress(); - resolve(); - return; - } - } catch { - handleError(); - } - } - handleError(); - }; - - xhr.onabort = () => { - unregister(); - resolve(); // treat abort as graceful completion — processQueue will short-circuit via item.cancelled - }; - - xhr.onerror = () => { - unregister(); - handleError(); - }; - - function handleError() { - retry++; - if (retry <= MAX_RETRY) { - setTimeout(attempt, 2000); - } else { - item.status = 'error'; - reject(new Error(t('upload.errors.chunkUploadFailed', { index: index + 1 }))); - } + for (let attempt = 1; attempt <= MAX_RETRY; attempt++) { + try { + await sendFile(item, uploadUrl); + return; + } catch (error) { + if (item.cancelled) { + return; } + if (attempt === MAX_RETRY) { + throw error; + } + } + } + }; - xhr.send(formData); + const sendFile = (item: QueueItem, uploadUrl: string): Promise => { + return new Promise((resolve, reject) => { + if (!item.file) { + resolve(); + return; + } + + const xhr = new XMLHttpRequest(); + const startedAt = Date.now(); + + activeXhrs.set(item.id, xhr); + xhr.open('PUT', uploadUrl); + if (item.file.type) { + xhr.setRequestHeader('Content-Type', item.file.type); + } + + const cleanup = () => { + if (activeXhrs.get(item.id) === xhr) { + activeXhrs.delete(item.id); + } }; - attempt(); + xhr.upload.onprogress = (event) => { + if (!event.lengthComputable || !item.file) return; + + const uploadedBytes = event.loaded; + const percent = Math.min((uploadedBytes / item.file.size) * 100, 100); + const elapsedSeconds = Math.max((Date.now() - startedAt) / 1000, 0.001); + const speed = uploadedBytes / elapsedSeconds; + + item.progress = parseFloat(percent.toFixed(1)); + item.uploaded = formatSize(uploadedBytes); + item.total = formatSize(item.file.size); + item.speed = `${formatSize(speed)}/s`; + }; + + xhr.onload = () => { + cleanup(); + if (item.cancelled) { + resolve(); + return; + } + if (xhr.status >= 200 && xhr.status < 300) { + item.progress = 100; + item.uploaded = item.total; + item.speed = '0 MB/s'; + resolve(); + return; + } + reject(new Error(t('upload.errors.chunkUploadFailed', { index: 1 }))); + }; + + xhr.onerror = () => { + cleanup(); + reject(new Error(t('upload.errors.chunkUploadFailed', { index: 1 }))); + }; + + xhr.onabort = () => { + cleanup(); + resolve(); + }; + + xhr.send(item.file); }); }; const completeUpload = async (item: QueueItem) => { - if (!item.file || !item.uploadedUrls) return; + if (!item.file || !item.objectKey) return; try { - const response = await fetch('/merge', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - filename: item.file.name, - chunks: item.uploadedUrls, - size: item.file.size - }) - }); - - const data = await response.json(); - - if (!response.ok) { - throw new Error(data.error || t('upload.errors.mergeFailed')); - } - - const playbackUrl = data.playback_url || data.play_url; - if (!playbackUrl) { - throw new Error('Playback URL missing after merge'); - } - - const createResponse = await client.videos.videosCreate({ + const createResponse = await rpcClient.createVideo({ title: item.file.name.replace(/\.[^.]+$/, ''), description: '', - url: playbackUrl, + url: item.objectKey, size: item.file.size, duration: 0, format: item.file.type || 'video/mp4', - }, { baseUrl: '/r' }); + }); - const createdVideo = (createResponse.data as any)?.data?.video || (createResponse.data as any)?.data; + const createdVideo = createResponse.video; item.videoId = createdVideo?.id; - item.mergeId = data.id; - item.playbackUrl = playbackUrl; - item.url = playbackUrl; + item.playbackUrl = createdVideo?.url || item.objectKey; + item.url = createdVideo?.url || item.objectKey; item.status = 'complete'; item.progress = 100; item.uploaded = item.total; item.speed = '0 MB/s'; } catch (error) { item.status = 'error'; - console.error('Merge failed:', error); + console.error('Create video failed:', error); } }; - // Mock Remote Fetch Logic const startMockRemoteFetch = (id: string) => { const item = items.value.find(i => i.id === id); if (!item) return; @@ -345,7 +273,6 @@ export function useUploadQueue() { }, 3000 + Math.random() * 3000); }; - const formatSize = (bytes: number): string => { if (bytes === 0) return '0 B'; const k = 1024; @@ -370,17 +297,11 @@ export function useUploadQueue() { const pendingCount = computed(() => { return items.value.filter(i => i.status === 'pending').length; }); + function removeAll() { items.value = []; } - // watch(items, (newItems) => { - // // console.log(newItems); - // if (newItems.length === 0) return; - // if (newItems.filter(i => i.status === 'pending' || i.status === 'uploading').length === 0) { - // // startQueue(); - // items.value = []; - // } - // }, { deep: true }); + return { items, addFiles, diff --git a/src/composables/useUsageQuery.ts b/src/composables/useUsageQuery.ts index b9c160a..9129759 100644 --- a/src/composables/useUsageQuery.ts +++ b/src/composables/useUsageQuery.ts @@ -1,4 +1,4 @@ -import { client } from '@/api/client'; +import { client as rpcClient } from '@/api/rpcclient'; import { useQuery } from '@pinia/colada'; export const USAGE_QUERY_KEY = ['usage'] as const; @@ -9,10 +9,8 @@ export type UsageSnapshot = { }; type UsageResponse = { - data?: { - total_videos?: number; - total_storage?: number; - }; + totalVideos?: number; + totalStorage?: number; }; const DEFAULT_USAGE_SNAPSHOT: UsageSnapshot = { @@ -21,11 +19,11 @@ const DEFAULT_USAGE_SNAPSHOT: UsageSnapshot = { }; const normalizeUsageSnapshot = (responseData: unknown): UsageSnapshot => { - const usage = (responseData as UsageResponse | undefined)?.data; + const usage = responseData as UsageResponse | undefined; return { - totalVideos: usage?.total_videos ?? DEFAULT_USAGE_SNAPSHOT.totalVideos, - totalStorage: usage?.total_storage ?? DEFAULT_USAGE_SNAPSHOT.totalStorage, + totalVideos: usage?.totalVideos ?? DEFAULT_USAGE_SNAPSHOT.totalVideos, + totalStorage: usage?.totalStorage ?? DEFAULT_USAGE_SNAPSHOT.totalStorage, }; }; @@ -33,8 +31,8 @@ export function useUsageQuery() { return useQuery({ key: () => USAGE_QUERY_KEY, query: async () => { - const response = await client.usage.usageList({ baseUrl: '/r' }); - return normalizeUsageSnapshot(response.data); + const response = await rpcClient.getUsage(); + return normalizeUsageSnapshot(response); }, }); } diff --git a/src/index.tsx b/src/index.tsx index e111174..1e3516b 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,13 +1,11 @@ import { Hono } from 'hono'; import { setupMiddlewares } from './server/middlewares/setup'; -import { registerDisplayRoutes } from './server/routes/display'; -import { registerManifestRoutes } from './server/routes/manifest'; -import { registerMergeRoutes } from './server/routes/merge'; import { registerSSRRoutes } from './server/routes/ssr'; import { registerWellKnownRoutes } from './server/routes/wellKnown'; import { setupServices } from './server/services/grpcClient'; import { registerRpcRoutes } from './server/routes/rpc'; +import { registerAuthRoutes } from './server/routes/auth'; const app = new Hono(); // Global middlewares @@ -15,10 +13,8 @@ setupMiddlewares(app); setupServices(app); // Routes registerWellKnownRoutes(app); +registerAuthRoutes(app); registerRpcRoutes(app); -registerMergeRoutes(app); -registerDisplayRoutes(app); -registerManifestRoutes(app); registerSSRRoutes(app); export default app; diff --git a/src/mocks/videos.ts b/src/mocks/videos.ts index 64c7d38..0ca60db 100644 --- a/src/mocks/videos.ts +++ b/src/mocks/videos.ts @@ -1,4 +1,4 @@ -import type { ModelVideo } from "@/api/client"; +import type { Video as ModelVideo } from "@/server/gen/proto/app/v1/common"; export const mockVideos: ModelVideo[] = [ { @@ -9,7 +9,7 @@ export const mockVideos: ModelVideo[] = [ duration: 345, // 5m 45s status: 'ready', size: 1024 * 1024 * 45, // 45MB - created_at: new Date(Date.now() - 1000 * 60 * 60 * 24 * 2).toISOString(), // 2 days ago + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 24 * 2).toISOString(), // 2 days ago views: 12500, url: '#' }, @@ -20,9 +20,8 @@ export const mockVideos: ModelVideo[] = [ thumbnail: 'https://picsum.photos/seed/video2/640/360', duration: 890, // 14m 50s status: 'processing', - processing_status: '75%', size: 1024 * 1024 * 128, // 128MB - created_at: new Date(Date.now() - 1000 * 60 * 60 * 5).toISOString(), // 5 hours ago + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 5).toISOString(), // 5 hours ago views: 0, url: '#' }, @@ -34,7 +33,7 @@ export const mockVideos: ModelVideo[] = [ duration: 120, // 2m 00s status: 'ready', size: 1024 * 1024 * 25, // 25MB - created_at: new Date(Date.now() - 1000 * 60 * 60 * 24 * 7).toISOString(), // 1 week ago + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 24 * 7).toISOString(), // 1 week ago views: 340, url: '#' }, @@ -46,7 +45,7 @@ export const mockVideos: ModelVideo[] = [ duration: 1800, // 30m 00s status: 'ready', size: 1024 * 1024 * 350, // 350MB - created_at: new Date(Date.now() - 1000 * 60 * 60 * 24 * 14).toISOString(), // 2 weeks ago + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 24 * 14).toISOString(), // 2 weeks ago views: 12, url: '#' }, @@ -58,7 +57,7 @@ export const mockVideos: ModelVideo[] = [ duration: 600, // 10m 00s status: 'failed', size: 1024 * 1024 * 80, // 80MB - created_at: new Date(Date.now() - 1000 * 60 * 30).toISOString(), // 30 mins ago + createdAt: new Date(Date.now() - 1000 * 60 * 30).toISOString(), // 30 mins ago views: 0, url: '#' }, @@ -70,7 +69,7 @@ export const mockVideos: ModelVideo[] = [ duration: 5400, // 1h 30m status: 'ready', size: 1024 * 1024 * 1024 * 2.5, // 2.5GB - created_at: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30).toISOString(), // 1 month ago + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30).toISOString(), // 1 month ago views: 45000, url: '#' }, @@ -82,7 +81,7 @@ export const mockVideos: ModelVideo[] = [ duration: 1540, status: 'ready', size: 1024 * 1024 * 200, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 24 * 3).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 24 * 3).toISOString(), views: 8900, url: '#' }, @@ -94,7 +93,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -106,7 +105,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -118,7 +117,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -130,7 +129,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -142,7 +141,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -154,7 +153,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -166,7 +165,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -178,7 +177,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -190,7 +189,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -202,7 +201,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -214,7 +213,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -226,7 +225,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -238,7 +237,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -250,7 +249,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -262,7 +261,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -274,7 +273,7 @@ export const mockVideos: ModelVideo[] = [ duration: 3200, status: 'ready', size: 1024 * 1024 * 800, - created_at: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), + createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), views: 1500, url: '#' }, @@ -340,7 +339,7 @@ export const updateMockVideo = async (id: string, updates: { title: string; desc ...mockVideos[videoIndex], title: updates.title, description: updates.description, - updated_at: new Date().toISOString() + updatedAt: new Date().toISOString() }; return mockVideos[videoIndex]; }; diff --git a/src/routes/admin/AdTemplates.vue b/src/routes/admin/AdTemplates.vue new file mode 100644 index 0000000..24089a3 --- /dev/null +++ b/src/routes/admin/AdTemplates.vue @@ -0,0 +1,334 @@ + + +