Compare commits
35 Commits
f003e77d52
...
75973c72ee
Author | SHA1 | Date | |
---|---|---|---|
75973c72ee | |||
b4a0320e3e | |||
8cf9395354 | |||
1e8d28e194 | |||
c0340677a1 | |||
54a2de0a11 | |||
3abd6666c0 | |||
44e13724fc | |||
dd7e2242a0 | |||
503a93a09f | |||
507f2c331e | |||
a1a4abff46 | |||
c6b7736dac | |||
fa5ab258da | |||
9dd06fa7bc | |||
bb7f846305 | |||
7f9563a2a6 | |||
d0d9c21aba | |||
44bc99dd9d | |||
2c83b79881 | |||
1a20d5afe0 | |||
ae338f88ee | |||
96903dec2b | |||
58b4e2613c | |||
2b0497c83a | |||
3bc72720d1 | |||
557a013b42 | |||
16cfae8bad | |||
cbd46d4030 | |||
6b93a781b7 | |||
fe2fd4fe36 | |||
dd70543594 | |||
1ff71ab241 | |||
cf7a285f57 | |||
79a37d927a |
@ -5,4 +5,7 @@ data
|
|||||||
*.md
|
*.md
|
||||||
*config*
|
*config*
|
||||||
Inter.css
|
Inter.css
|
||||||
MiSans.css
|
MiSans.css
|
||||||
|
*.yaml
|
||||||
|
*.yml
|
||||||
|
*.mdx
|
||||||
|
14
Dockerfile.next
Normal file
14
Dockerfile.next
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
FROM node:lts-slim AS production
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY ./packages/next/.next ./.next
|
||||||
|
COPY ./packages/next/public ./public
|
||||||
|
COPY ./packages/next/package.json ./package.json
|
||||||
|
COPY ./packages/next/node_modules ./node_modules
|
||||||
|
|
||||||
|
ENV NODE_ENV production
|
||||||
|
|
||||||
|
EXPOSE 7400
|
||||||
|
|
||||||
|
CMD ["npm", "start"]
|
382
bun.lock
382
bun.lock
@ -4,18 +4,24 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "cvsa",
|
"name": "cvsa",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"arg": "^5.0.2",
|
||||||
"postgres": "^3.4.5",
|
"postgres": "^3.4.5",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/bun": "^1.2.15",
|
||||||
|
"prettier": "^3.5.3",
|
||||||
"vite-tsconfig-paths": "^5.1.4",
|
"vite-tsconfig-paths": "^5.1.4",
|
||||||
"vitest": "^3.1.2",
|
"vitest": "^3.1.2",
|
||||||
"vitest-tsconfig-paths": "^3.4.1",
|
"vitest-tsconfig-paths": "^3.4.1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages/backend": {
|
"packages/backend": {
|
||||||
"name": "backend",
|
"name": "@cvsa/backend",
|
||||||
|
"version": "0.5.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@koshnic/ratelimit": "^1.0.3",
|
||||||
"@rabbit-company/argon2id": "^2.1.0",
|
"@rabbit-company/argon2id": "^2.1.0",
|
||||||
|
"chalk": "^5.4.1",
|
||||||
"hono": "^4.7.8",
|
"hono": "^4.7.8",
|
||||||
"hono-rate-limiter": "^0.4.2",
|
"hono-rate-limiter": "^0.4.2",
|
||||||
"ioredis": "^5.6.1",
|
"ioredis": "^5.6.1",
|
||||||
@ -31,7 +37,8 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages/core": {
|
"packages/core": {
|
||||||
"name": "core",
|
"name": "@cvsa/core",
|
||||||
|
"version": "0.0.5",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@koshnic/ratelimit": "^1.0.3",
|
"@koshnic/ratelimit": "^1.0.3",
|
||||||
"chalk": "^5.4.1",
|
"chalk": "^5.4.1",
|
||||||
@ -54,6 +61,7 @@
|
|||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
"ioredis": "^5.6.1",
|
"ioredis": "^5.6.1",
|
||||||
"onnxruntime-node": "1.19.2",
|
"onnxruntime-node": "1.19.2",
|
||||||
|
"postgres": "^3.4.5",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"concurrently": "^9.1.2",
|
"concurrently": "^9.1.2",
|
||||||
@ -87,33 +95,33 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
||||||
|
|
||||||
"@astrojs/compiler": ["@astrojs/compiler@2.11.0", "", {}, "sha512-zZOO7i+JhojO8qmlyR/URui6LyfHJY6m+L9nwyX5GiKD78YoRaZ5tzz6X0fkl+5bD3uwlDHayf6Oe8Fu36RKNg=="],
|
"@astrojs/compiler": ["@astrojs/compiler@2.12.0", "", {}, "sha512-7bCjW6tVDpUurQLeKBUN9tZ5kSv5qYrGmcn0sG0IwacL7isR2ZbyyA3AdZ4uxsuUFOS2SlgReTH7wkxO6zpqWA=="],
|
||||||
|
|
||||||
"@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="],
|
"@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="],
|
||||||
|
|
||||||
"@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.1", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.2.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.1", "remark-smartypants": "^3.0.2", "shiki": "^3.0.0", "smol-toml": "^1.3.1", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-c5F5gGrkczUaTVgmMW9g1YMJGzOtRvjjhw6IfGuxarM6ct09MpwysP10US729dy07gg8y+ofVifezvP3BNsWZg=="],
|
"@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.2", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.2.1", "smol-toml": "^1.3.1", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-bO35JbWpVvyKRl7cmSJD822e8YA8ThR/YbUsciWNA7yTcqpIAL2hJDToWP5KcZBWxGT6IOdOkHSXARSNZc4l/Q=="],
|
||||||
|
|
||||||
"@astrojs/node": ["@astrojs/node@9.2.1", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "send": "^1.1.0", "server-destroy": "^1.0.1" }, "peerDependencies": { "astro": "^5.3.0" } }, "sha512-kEHLB37ooW91p7FLGalqa3jVQRIafntfKiZgCnjN1lEYw+j8NP6VJHQbLHmzzbtKUI0J+srGiTnGZmaHErHE5w=="],
|
"@astrojs/node": ["@astrojs/node@9.2.2", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "send": "^1.2.0", "server-destroy": "^1.0.1" }, "peerDependencies": { "astro": "^5.3.0" } }, "sha512-PtLPuuojmcl9O3CEvXqL/D+wB4x5DlbrGOvP0MeTAh/VfKFprYAzgw1+45xsnTO+QvPWb26l1cT+ZQvvohmvMw=="],
|
||||||
|
|
||||||
"@astrojs/prism": ["@astrojs/prism@3.2.0", "", { "dependencies": { "prismjs": "^1.29.0" } }, "sha512-GilTHKGCW6HMq7y3BUv9Ac7GMe/MO9gi9GW62GzKtth0SwukCu/qp2wLiGpEujhY+VVhaG9v7kv/5vFzvf4NYw=="],
|
"@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="],
|
||||||
|
|
||||||
"@astrojs/svelte": ["@astrojs/svelte@7.0.11", "", { "dependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.3", "svelte2tsx": "^0.7.35", "vite": "^6.2.6" }, "peerDependencies": { "astro": "^5.0.0", "svelte": "^5.1.16", "typescript": "^5.3.3" } }, "sha512-+hn43pBQBLOMXrVYnxqP8b6JNLVhMVXzK3nEgqBfhXfAYdZxJkUUcnbpE8GL1OddTYUnUDFuk2E5hE2kA35LqA=="],
|
"@astrojs/svelte": ["@astrojs/svelte@7.1.0", "", { "dependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.3", "svelte2tsx": "^0.7.39", "vite": "^6.3.5" }, "peerDependencies": { "astro": "^5.0.0", "svelte": "^5.1.16", "typescript": "^5.3.3" } }, "sha512-nNAO7iFgCZXCN31N4xBSS/k7vZAZxeZ/v8V6VWZOKG47gVlxeAJBHzn2GlXMMVkxIamr6dhrkDrhYFKIPzoGpw=="],
|
||||||
|
|
||||||
"@astrojs/telemetry": ["@astrojs/telemetry@3.2.1", "", { "dependencies": { "ci-info": "^4.2.0", "debug": "^4.4.0", "dlv": "^1.1.3", "dset": "^3.1.4", "is-docker": "^3.0.0", "is-wsl": "^3.1.0", "which-pm-runs": "^1.1.0" } }, "sha512-SSVM820Jqc6wjsn7qYfV9qfeQvePtVc1nSofhyap7l0/iakUKywj3hfy3UJAOV4sGV4Q/u450RD4AaCaFvNPlg=="],
|
"@astrojs/telemetry": ["@astrojs/telemetry@3.3.0", "", { "dependencies": { "ci-info": "^4.2.0", "debug": "^4.4.0", "dlv": "^1.1.3", "dset": "^3.1.4", "is-docker": "^3.0.0", "is-wsl": "^3.1.0", "which-pm-runs": "^1.1.0" } }, "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ=="],
|
||||||
|
|
||||||
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="],
|
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
|
||||||
|
|
||||||
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="],
|
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="],
|
||||||
|
|
||||||
"@babel/parser": ["@babel/parser@7.27.0", "", { "dependencies": { "@babel/types": "^7.27.0" }, "bin": "./bin/babel-parser.js" }, "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg=="],
|
"@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="],
|
||||||
|
|
||||||
"@babel/types": ["@babel/types@7.27.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg=="],
|
"@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="],
|
||||||
|
|
||||||
"@bull-board/api": ["@bull-board/api@6.9.5", "", { "dependencies": { "redis-info": "^3.1.0" }, "peerDependencies": { "@bull-board/ui": "6.9.5" } }, "sha512-9d03Mu9fuQ3sHAxAwUmlTo8C9KwKHd6Ef2IUOZMG93cAHsQ0oaOpYc5d0roZacYFvfYKr7bTANptKO1f3GLp2g=="],
|
"@bull-board/api": ["@bull-board/api@6.9.6", "", { "dependencies": { "redis-info": "^3.1.0" }, "peerDependencies": { "@bull-board/ui": "6.9.6" } }, "sha512-k1h35Q+y5hdf9UoPhp6mLG5+QM9AHP8luyggxEJ+/ZkoSMJ0h45HjHhqbexEAzdgsVN7lncXNLNn6myKwwcjkw=="],
|
||||||
|
|
||||||
"@bull-board/express": ["@bull-board/express@6.9.5", "", { "dependencies": { "@bull-board/api": "6.9.5", "@bull-board/ui": "6.9.5", "ejs": "^3.1.10", "express": "^4.21.1 || ^5.0.0" } }, "sha512-N2B/RSEX/EpIvT/uOJXCACevElv2CUEqrvgoLuwM2n1Fb3VWaatj/S004VLUtHjOCPfODosJ1xoxelelQcV3Dw=="],
|
"@bull-board/express": ["@bull-board/express@6.9.6", "", { "dependencies": { "@bull-board/api": "6.9.6", "@bull-board/ui": "6.9.6", "ejs": "^3.1.10", "express": "^4.21.1 || ^5.0.0" } }, "sha512-DUNSxAp1ZXoBraRP4b5mWmlIBFazZ1BKlrRgBlMK3wfnzOTYUmorvbN3+JeLgCMm9bpYw4ybvfiaFkmPe8AKJg=="],
|
||||||
|
|
||||||
"@bull-board/ui": ["@bull-board/ui@6.9.5", "", { "dependencies": { "@bull-board/api": "6.9.5" } }, "sha512-+4YnDvyuY3MOVkXFxkspRbqawLtIExHzRQ4raQWagOc35KD7v2/ccFGyRPDI/N0bemsiNkOPkcZGf/LFcaOZmA=="],
|
"@bull-board/ui": ["@bull-board/ui@6.9.6", "", { "dependencies": { "@bull-board/api": "6.9.6" } }, "sha512-uRYJ3G4hsodEuhVd7yIl7MSsGNYZNa0nCcivK472ojUV22t4ZB2j2KKew07jBhlhPN5jxzQ5PJh16lOnrWk9vQ=="],
|
||||||
|
|
||||||
"@capsizecss/unpack": ["@capsizecss/unpack@2.4.0", "", { "dependencies": { "blob-to-buffer": "^1.2.8", "cross-fetch": "^3.0.4", "fontkit": "^2.0.2" } }, "sha512-GrSU71meACqcmIUxPYOJvGKF0yryjN/L1aCuE9DViCTJI7bfkjgYDPD1zbNDcINJwSSP6UaBZY9GAbYDO7re0Q=="],
|
"@capsizecss/unpack": ["@capsizecss/unpack@2.4.0", "", { "dependencies": { "blob-to-buffer": "^1.2.8", "cross-fetch": "^3.0.4", "fontkit": "^2.0.2" } }, "sha512-GrSU71meACqcmIUxPYOJvGKF0yryjN/L1aCuE9DViCTJI7bfkjgYDPD1zbNDcINJwSSP6UaBZY9GAbYDO7re0Q=="],
|
||||||
|
|
||||||
@ -121,67 +129,71 @@
|
|||||||
|
|
||||||
"@cush/relative": ["@cush/relative@1.0.0", "", {}, "sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA=="],
|
"@cush/relative": ["@cush/relative@1.0.0", "", {}, "sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA=="],
|
||||||
|
|
||||||
|
"@cvsa/backend": ["@cvsa/backend@workspace:packages/backend"],
|
||||||
|
|
||||||
|
"@cvsa/core": ["@cvsa/core@workspace:packages/core"],
|
||||||
|
|
||||||
"@dabh/diagnostics": ["@dabh/diagnostics@2.0.3", "", { "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA=="],
|
"@dabh/diagnostics": ["@dabh/diagnostics@2.0.3", "", { "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA=="],
|
||||||
|
|
||||||
"@emnapi/runtime": ["@emnapi/runtime@1.4.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ=="],
|
"@emnapi/runtime": ["@emnapi/runtime@1.4.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ=="],
|
||||||
|
|
||||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ=="],
|
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA=="],
|
||||||
|
|
||||||
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.3", "", { "os": "android", "cpu": "arm" }, "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A=="],
|
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.5", "", { "os": "android", "cpu": "arm" }, "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA=="],
|
||||||
|
|
||||||
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.3", "", { "os": "android", "cpu": "arm64" }, "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ=="],
|
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.5", "", { "os": "android", "cpu": "arm64" }, "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg=="],
|
||||||
|
|
||||||
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.3", "", { "os": "android", "cpu": "x64" }, "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ=="],
|
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.5", "", { "os": "android", "cpu": "x64" }, "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw=="],
|
||||||
|
|
||||||
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w=="],
|
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ=="],
|
||||||
|
|
||||||
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A=="],
|
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ=="],
|
||||||
|
|
||||||
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw=="],
|
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw=="],
|
||||||
|
|
||||||
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q=="],
|
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw=="],
|
||||||
|
|
||||||
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.3", "", { "os": "linux", "cpu": "arm" }, "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ=="],
|
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.5", "", { "os": "linux", "cpu": "arm" }, "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw=="],
|
||||||
|
|
||||||
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A=="],
|
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg=="],
|
||||||
|
|
||||||
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.3", "", { "os": "linux", "cpu": "ia32" }, "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw=="],
|
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA=="],
|
||||||
|
|
||||||
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.3", "", { "os": "linux", "cpu": "none" }, "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g=="],
|
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg=="],
|
||||||
|
|
||||||
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.3", "", { "os": "linux", "cpu": "none" }, "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag=="],
|
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg=="],
|
||||||
|
|
||||||
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg=="],
|
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ=="],
|
||||||
|
|
||||||
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.3", "", { "os": "linux", "cpu": "none" }, "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA=="],
|
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA=="],
|
||||||
|
|
||||||
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ=="],
|
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ=="],
|
||||||
|
|
||||||
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.3", "", { "os": "linux", "cpu": "x64" }, "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA=="],
|
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.5", "", { "os": "linux", "cpu": "x64" }, "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw=="],
|
||||||
|
|
||||||
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.3", "", { "os": "none", "cpu": "arm64" }, "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA=="],
|
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.5", "", { "os": "none", "cpu": "arm64" }, "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw=="],
|
||||||
|
|
||||||
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.3", "", { "os": "none", "cpu": "x64" }, "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g=="],
|
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.5", "", { "os": "none", "cpu": "x64" }, "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ=="],
|
||||||
|
|
||||||
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.3", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ=="],
|
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.5", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw=="],
|
||||||
|
|
||||||
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w=="],
|
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg=="],
|
||||||
|
|
||||||
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.3", "", { "os": "sunos", "cpu": "x64" }, "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA=="],
|
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA=="],
|
||||||
|
|
||||||
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ=="],
|
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw=="],
|
||||||
|
|
||||||
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew=="],
|
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ=="],
|
||||||
|
|
||||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.3", "", { "os": "win32", "cpu": "x64" }, "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg=="],
|
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g=="],
|
||||||
|
|
||||||
"@huggingface/jinja": ["@huggingface/jinja@0.4.1", "", {}, "sha512-3WXbMFaPkk03LRCM0z0sylmn8ddDm4ubjU7X+Hg4M2GOuMklwoGAFXp9V2keq7vltoB/c7McE5aHUVVddAewsw=="],
|
"@huggingface/jinja": ["@huggingface/jinja@0.4.1", "", {}, "sha512-3WXbMFaPkk03LRCM0z0sylmn8ddDm4ubjU7X+Hg4M2GOuMklwoGAFXp9V2keq7vltoB/c7McE5aHUVVddAewsw=="],
|
||||||
|
|
||||||
"@huggingface/transformers": ["@huggingface/transformers@3.5.1", "", { "dependencies": { "@huggingface/jinja": "^0.4.1", "onnxruntime-node": "1.21.0", "onnxruntime-web": "1.22.0-dev.20250409-89f8206ba4", "sharp": "^0.34.1" } }, "sha512-qWsPoJMBPYcrGuzRMVL//3dwcLXED9r+j+Hzw+hZpBfrMPdyq57ehNs7lew0D34Paj0DO0E0kZQjOZcIVN17hQ=="],
|
"@huggingface/transformers": ["@huggingface/transformers@3.5.2", "", { "dependencies": { "@huggingface/jinja": "^0.4.1", "onnxruntime-node": "1.21.0", "onnxruntime-web": "1.22.0-dev.20250409-89f8206ba4", "sharp": "^0.34.1" } }, "sha512-mfRXkmcL99+ibpjM++pvZmc2h3po8i1ZgSRI5Rtgh++P15GU0lY8UQteYt/w5V+GQw+Jpao93MoipcePzh3mKg=="],
|
||||||
|
|
||||||
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.1", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.1.0" }, "os": "darwin", "cpu": "arm64" }, "sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A=="],
|
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.1.0" }, "os": "darwin", "cpu": "arm64" }, "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg=="],
|
||||||
|
|
||||||
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.1", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.1.0" }, "os": "darwin", "cpu": "x64" }, "sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q=="],
|
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.1.0" }, "os": "darwin", "cpu": "x64" }, "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.1.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA=="],
|
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.1.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA=="],
|
||||||
|
|
||||||
@ -201,23 +213,25 @@
|
|||||||
|
|
||||||
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A=="],
|
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A=="],
|
||||||
|
|
||||||
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.1", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.1.0" }, "os": "linux", "cpu": "arm" }, "sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA=="],
|
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.1.0" }, "os": "linux", "cpu": "arm" }, "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ=="],
|
||||||
|
|
||||||
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.1", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.1.0" }, "os": "linux", "cpu": "arm64" }, "sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ=="],
|
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.1.0" }, "os": "linux", "cpu": "arm64" }, "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q=="],
|
||||||
|
|
||||||
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.1", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.1.0" }, "os": "linux", "cpu": "s390x" }, "sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA=="],
|
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.1.0" }, "os": "linux", "cpu": "s390x" }, "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw=="],
|
||||||
|
|
||||||
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.1", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.1.0" }, "os": "linux", "cpu": "x64" }, "sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA=="],
|
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.1.0" }, "os": "linux", "cpu": "x64" }, "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ=="],
|
||||||
|
|
||||||
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.1", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" }, "os": "linux", "cpu": "arm64" }, "sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ=="],
|
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" }, "os": "linux", "cpu": "arm64" }, "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA=="],
|
||||||
|
|
||||||
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.1", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.1.0" }, "os": "linux", "cpu": "x64" }, "sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg=="],
|
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.1.0" }, "os": "linux", "cpu": "x64" }, "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA=="],
|
||||||
|
|
||||||
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.1", "", { "dependencies": { "@emnapi/runtime": "^1.4.0" }, "cpu": "none" }, "sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg=="],
|
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.2", "", { "dependencies": { "@emnapi/runtime": "^1.4.3" }, "cpu": "none" }, "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ=="],
|
||||||
|
|
||||||
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw=="],
|
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ=="],
|
||||||
|
|
||||||
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.1", "", { "os": "win32", "cpu": "x64" }, "sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw=="],
|
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw=="],
|
||||||
|
|
||||||
|
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.2", "", { "os": "win32", "cpu": "x64" }, "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw=="],
|
||||||
|
|
||||||
"@ioredis/commands": ["@ioredis/commands@1.2.0", "", {}, "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg=="],
|
"@ioredis/commands": ["@ioredis/commands@1.2.0", "", {}, "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg=="],
|
||||||
|
|
||||||
@ -279,106 +293,110 @@
|
|||||||
|
|
||||||
"@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="],
|
"@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.40.1", "", { "os": "android", "cpu": "arm" }, "sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw=="],
|
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.41.1", "", { "os": "android", "cpu": "arm" }, "sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw=="],
|
||||||
|
|
||||||
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.40.1", "", { "os": "android", "cpu": "arm64" }, "sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw=="],
|
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.41.1", "", { "os": "android", "cpu": "arm64" }, "sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA=="],
|
||||||
|
|
||||||
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.40.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA=="],
|
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.41.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w=="],
|
||||||
|
|
||||||
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.40.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw=="],
|
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.41.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg=="],
|
||||||
|
|
||||||
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.40.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw=="],
|
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.41.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg=="],
|
||||||
|
|
||||||
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.40.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q=="],
|
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.41.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.40.1", "", { "os": "linux", "cpu": "arm" }, "sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg=="],
|
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.41.1", "", { "os": "linux", "cpu": "arm" }, "sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.40.1", "", { "os": "linux", "cpu": "arm" }, "sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg=="],
|
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.41.1", "", { "os": "linux", "cpu": "arm" }, "sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.40.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg=="],
|
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.41.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.40.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ=="],
|
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.41.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.40.1", "", { "os": "linux", "cpu": "none" }, "sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ=="],
|
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.41.1", "", { "os": "linux", "cpu": "none" }, "sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.40.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg=="],
|
"@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.41.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.40.1", "", { "os": "linux", "cpu": "none" }, "sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ=="],
|
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.41.1", "", { "os": "linux", "cpu": "none" }, "sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.40.1", "", { "os": "linux", "cpu": "none" }, "sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA=="],
|
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.41.1", "", { "os": "linux", "cpu": "none" }, "sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.40.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg=="],
|
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.41.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.40.1", "", { "os": "linux", "cpu": "x64" }, "sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ=="],
|
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.41.1", "", { "os": "linux", "cpu": "x64" }, "sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.40.1", "", { "os": "linux", "cpu": "x64" }, "sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ=="],
|
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.41.1", "", { "os": "linux", "cpu": "x64" }, "sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.40.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg=="],
|
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.41.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.40.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA=="],
|
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.41.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg=="],
|
||||||
|
|
||||||
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.40.1", "", { "os": "win32", "cpu": "x64" }, "sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA=="],
|
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.41.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw=="],
|
||||||
|
|
||||||
"@shikijs/core": ["@shikijs/core@3.3.0", "", { "dependencies": { "@shikijs/types": "3.3.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-CovkFL2WVaHk6PCrwv6ctlmD4SS1qtIfN8yEyDXDYWh4ONvomdM9MaFw20qHuqJOcb8/xrkqoWQRJ//X10phOQ=="],
|
"@shikijs/core": ["@shikijs/core@3.5.0", "", { "dependencies": { "@shikijs/types": "3.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-iycvvnVG7MWZHRNuoqpYkV3Qc8DNLU74Lxh/roDwUqJJoXRnCTbbVJGfSWAdBslUgJMsjSHwFL42i55voavDDg=="],
|
||||||
|
|
||||||
"@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.3.0", "", { "dependencies": { "@shikijs/types": "3.3.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.2.0" } }, "sha512-XlhnFGv0glq7pfsoN0KyBCz9FJU678LZdQ2LqlIdAj6JKsg5xpYKay3DkazXWExp3DTJJK9rMOuGzU2911pg7Q=="],
|
"@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.5.0", "", { "dependencies": { "@shikijs/types": "3.5.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-3MhSnVHEdGb4L4FS/HAPc7WtPmIfHjRZraObf6tKxQaGuQGZfBsoLVCGuoGfiqt/zy0MKpll3oiZiQ/maT/wlQ=="],
|
||||||
|
|
||||||
"@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.3.0", "", { "dependencies": { "@shikijs/types": "3.3.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-l0vIw+GxeNU7uGnsu6B+Crpeqf+WTQ2Va71cHb5ZYWEVEPdfYwY5kXwYqRJwHrxz9WH+pjSpXQz+TJgAsrkA5A=="],
|
"@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.5.0", "", { "dependencies": { "@shikijs/types": "3.5.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-DLM1VL+WvWFHQlikP8MTc8T2MdEGAOJhAi9+48wkQ7kO7c/99h4ALK0b0CPQBCeLMp37raoM1Ucuo3OTSjtUxA=="],
|
||||||
|
|
||||||
"@shikijs/langs": ["@shikijs/langs@3.3.0", "", { "dependencies": { "@shikijs/types": "3.3.0" } }, "sha512-zt6Kf/7XpBQKSI9eqku+arLkAcDQ3NHJO6zFjiChI8w0Oz6Jjjay7pToottjQGjSDCFk++R85643WbyINcuL+g=="],
|
"@shikijs/langs": ["@shikijs/langs@3.5.0", "", { "dependencies": { "@shikijs/types": "3.5.0" } }, "sha512-kBJhmj0ZkULbf3O+Asr8Xs7hcFtQdPnqIld2kKrG9WhDpIvqMRWSj3L9LECi2TH7vV6ROrvJ78/1yEASL0d00w=="],
|
||||||
|
|
||||||
"@shikijs/themes": ["@shikijs/themes@3.3.0", "", { "dependencies": { "@shikijs/types": "3.3.0" } }, "sha512-tXeCvLXBnqq34B0YZUEaAD1lD4lmN6TOHAhnHacj4Owh7Ptb/rf5XCDeROZt2rEOk5yuka3OOW2zLqClV7/SOg=="],
|
"@shikijs/themes": ["@shikijs/themes@3.5.0", "", { "dependencies": { "@shikijs/types": "3.5.0" } }, "sha512-xr4bPmAORm2fhfVeaCDfRXiq0rxAxPRR0Bhiw+EaofgJ79Jj61fnVZDF40nJKvmMoKnC60TqCTpbr15ToTgTOA=="],
|
||||||
|
|
||||||
"@shikijs/types": ["@shikijs/types@3.3.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-KPCGnHG6k06QG/2pnYGbFtFvpVJmC3uIpXrAiPrawETifujPBv0Se2oUxm5qYgjCvGJS9InKvjytOdN+bGuX+Q=="],
|
"@shikijs/types": ["@shikijs/types@3.5.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-VvqGHhS8BWClF7eVnEJLe0nAhQw/1L+xC5mp6uj+tVr3tjD2ASx2Mx9M9l7tZQO++1qwZeIIusvSRhz4aKODFQ=="],
|
||||||
|
|
||||||
"@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
|
"@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
|
||||||
|
|
||||||
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="],
|
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="],
|
||||||
|
|
||||||
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@5.0.3", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.0", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.15", "vitefu": "^1.0.4" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-MCFS6CrQDu1yGwspm4qtli0e63vaPCehf6V7pIMP15AsWgMKrqDGCPFF/0kn4SP0ii4aySu4Pa62+fIRGFMjgw=="],
|
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@5.1.0", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.1", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.17", "vitefu": "^1.0.6" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-wojIS/7GYnJDYIg1higWj2ROA6sSRWvcR1PO/bqEyFr/5UZah26c8Cz4u0NaqjPeVltzsVpt2Tm8d2io0V+4Tw=="],
|
||||||
|
|
||||||
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@4.0.1", "", { "dependencies": { "debug": "^4.3.7" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw=="],
|
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@4.0.1", "", { "dependencies": { "debug": "^4.3.7" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw=="],
|
||||||
|
|
||||||
"@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
|
"@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
|
||||||
|
|
||||||
"@tailwindcss/node": ["@tailwindcss/node@4.1.4", "", { "dependencies": { "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.29.2", "tailwindcss": "4.1.4" } }, "sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw=="],
|
"@tailwindcss/node": ["@tailwindcss/node@4.1.8", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.8" } }, "sha512-OWwBsbC9BFAJelmnNcrKuf+bka2ZxCE2A4Ft53Tkg4uoiE67r/PMEYwCsourC26E+kmxfwE0hVzMdxqeW+xu7Q=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.4", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.4", "@tailwindcss/oxide-darwin-arm64": "4.1.4", "@tailwindcss/oxide-darwin-x64": "4.1.4", "@tailwindcss/oxide-freebsd-x64": "4.1.4", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.4", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.4", "@tailwindcss/oxide-linux-arm64-musl": "4.1.4", "@tailwindcss/oxide-linux-x64-gnu": "4.1.4", "@tailwindcss/oxide-linux-x64-musl": "4.1.4", "@tailwindcss/oxide-wasm32-wasi": "4.1.4", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.4", "@tailwindcss/oxide-win32-x64-msvc": "4.1.4" } }, "sha512-p5wOpXyOJx7mKh5MXh5oKk+kqcz8T+bA3z/5VWWeQwFrmuBItGwz8Y2CHk/sJ+dNb9B0nYFfn0rj/cKHZyjahQ=="],
|
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.8", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.8", "@tailwindcss/oxide-darwin-arm64": "4.1.8", "@tailwindcss/oxide-darwin-x64": "4.1.8", "@tailwindcss/oxide-freebsd-x64": "4.1.8", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.8", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.8", "@tailwindcss/oxide-linux-arm64-musl": "4.1.8", "@tailwindcss/oxide-linux-x64-gnu": "4.1.8", "@tailwindcss/oxide-linux-x64-musl": "4.1.8", "@tailwindcss/oxide-wasm32-wasi": "4.1.8", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.8", "@tailwindcss/oxide-win32-x64-msvc": "4.1.8" } }, "sha512-d7qvv9PsM5N3VNKhwVUhpK6r4h9wtLkJ6lz9ZY9aeZgrUWk1Z8VPyqyDT9MZlem7GTGseRQHkeB1j3tC7W1P+A=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.4", "", { "os": "android", "cpu": "arm64" }, "sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA=="],
|
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.8", "", { "os": "android", "cpu": "arm64" }, "sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JGRj0SYFuDuAGilWFBlshcexev2hOKfNkoX+0QTksKYq2zgF9VY/vVMq9m8IObYnLna0Xlg+ytCi2FN2rOL0Sg=="],
|
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-sdDeLNvs3cYeWsEJ4H1DvjOzaGios4QbBTNLVLVs0XQ0V95bffT3+scptzYGPMjm7xv4+qMhCDrkHwhnUySEzA=="],
|
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-VHxAqxqdghM83HslPhRsNhHo91McsxRJaEnShJOMu8mHmEj9Ig7ToHJtDukkuLWLzLboh2XSjq/0zO6wgvykNA=="],
|
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.8", "", { "os": "freebsd", "cpu": "x64" }, "sha512-g8C8eGEyhHTqwPStSwZNSrOlyx0bhK/V/+zX0Y+n7DoRUzyS8eMbVshVOLJTDDC+Qn9IJnilYbIKzpB9n4aBsg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4", "", { "os": "linux", "cpu": "arm" }, "sha512-OTU/m/eV4gQKxy9r5acuesqaymyeSCnsx1cFto/I1WhPmi5HDxX1nkzb8KYBiwkHIGg7CTfo/AcGzoXAJBxLfg=="],
|
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.8", "", { "os": "linux", "cpu": "arm" }, "sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-hKlLNvbmUC6z5g/J4H+Zx7f7w15whSVImokLPmP6ff1QqTVE+TxUM9PGuNsjHvkvlHUtGTdDnOvGNSEUiXI1Ww=="],
|
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw=="],
|
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ=="],
|
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.8", "", { "os": "linux", "cpu": "x64" }, "sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ=="],
|
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.8", "", { "os": "linux", "cpu": "x64" }, "sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.4", "", { "dependencies": { "@emnapi/core": "^1.4.0", "@emnapi/runtime": "^1.4.0", "@emnapi/wasi-threads": "^1.0.1", "@napi-rs/wasm-runtime": "^0.2.8", "@tybys/wasm-util": "^0.9.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q=="],
|
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.8", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@emnapi/wasi-threads": "^1.0.2", "@napi-rs/wasm-runtime": "^0.2.10", "@tybys/wasm-util": "^0.9.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-CXBPVFkpDjM67sS1psWohZ6g/2/cd+cq56vPxK4JeawelxwK4YECgl9Y9TjkE2qfF+9/s1tHHJqrC4SS6cVvSg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-VlnhfilPlO0ltxW9/BgfLI5547PYzqBMPIzRrk4W7uupgCt8z6Trw/tAj6QUtF2om+1MH281Pg+HHUJoLesmng=="],
|
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.4", "", { "os": "win32", "cpu": "x64" }, "sha512-+7S63t5zhYjslUGb8NcgLpFXD+Kq1F/zt5Xv5qTv7HaFTG/DHyHD9GA6ieNAxhgyA4IcKa/zy7Xx4Oad2/wuhw=="],
|
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.8", "", { "os": "win32", "cpu": "x64" }, "sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ=="],
|
||||||
|
|
||||||
"@tailwindcss/vite": ["@tailwindcss/vite@4.1.4", "", { "dependencies": { "@tailwindcss/node": "4.1.4", "@tailwindcss/oxide": "4.1.4", "tailwindcss": "4.1.4" }, "peerDependencies": { "vite": "^5.2.0 || ^6" } }, "sha512-4UQeMrONbvrsXKXXp/uxmdEN5JIJ9RkH7YVzs6AMxC/KC1+Np7WZBaNIco7TEjlkthqxZbt8pU/ipD+hKjm80A=="],
|
"@tailwindcss/vite": ["@tailwindcss/vite@4.1.8", "", { "dependencies": { "@tailwindcss/node": "4.1.8", "@tailwindcss/oxide": "4.1.8", "tailwindcss": "4.1.8" }, "peerDependencies": { "vite": "^5.2.0 || ^6" } }, "sha512-CQ+I8yxNV5/6uGaJjiuymgw0kEQiNKRinYbZXPdx1fk5WgiyReG0VaUx/Xq6aVNSUNJFzxm6o8FNKS5aMaim5A=="],
|
||||||
|
|
||||||
"@types/bun": ["@types/bun@1.2.11", "", { "dependencies": { "bun-types": "1.2.11" } }, "sha512-ZLbbI91EmmGwlWTRWuV6J19IUiUC5YQ3TCEuSHI3usIP75kuoA8/0PVF+LTrbEnVc8JIhpElWOxv1ocI1fJBbw=="],
|
"@types/bun": ["@types/bun@1.2.15", "", { "dependencies": { "bun-types": "1.2.15" } }, "sha512-U1ljPdBEphF0nw1MIk0hI7kPg7dFdPyM7EenHsp6W5loNHl7zqy6JQf/RKCgnUn2KDzUpkBwHPnEJEjII594bA=="],
|
||||||
|
|
||||||
"@types/chai": ["@types/chai@4.3.20", "", {}, "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ=="],
|
"@types/chai": ["@types/chai@5.2.2", "", { "dependencies": { "@types/deep-eql": "*" } }, "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg=="],
|
||||||
|
|
||||||
"@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="],
|
"@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="],
|
||||||
|
|
||||||
|
"@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="],
|
||||||
|
|
||||||
"@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="],
|
"@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="],
|
||||||
|
|
||||||
|
"@types/fontkit": ["@types/fontkit@2.0.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-wN+8bYxIpJf+5oZdrdtaX04qUuWHcKxcDEgRS9Qm9ZClSHjzEn13SxUC+5eRM+4yXIeTYk8mTzLAWGF64847ew=="],
|
||||||
|
|
||||||
"@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
|
"@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
|
||||||
|
|
||||||
"@types/ioredis": ["@types/ioredis@5.0.0", "", { "dependencies": { "ioredis": "*" } }, "sha512-zJbJ3FVE17CNl5KXzdeSPtdltc4tMT3TzC6fxQS0sQngkbFZ6h+0uTafsRqu+eSLIugf6Yb0Ea0SUuRr42Nk9g=="],
|
"@types/ioredis": ["@types/ioredis@5.0.0", "", { "dependencies": { "ioredis": "*" } }, "sha512-zJbJ3FVE17CNl5KXzdeSPtdltc4tMT3TzC6fxQS0sQngkbFZ6h+0uTafsRqu+eSLIugf6Yb0Ea0SUuRr42Nk9g=="],
|
||||||
@ -393,11 +411,11 @@
|
|||||||
|
|
||||||
"@types/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "*" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="],
|
"@types/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "*" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@22.15.3", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw=="],
|
"@types/node": ["@types/node@22.15.29", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ=="],
|
||||||
|
|
||||||
"@types/node-fetch": ["@types/node-fetch@2.6.12", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA=="],
|
"@types/node-fetch": ["@types/node-fetch@2.6.12", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA=="],
|
||||||
|
|
||||||
"@types/pg": ["@types/pg@8.11.14", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^4.0.1" } }, "sha512-qyD11E5R3u0eJmd1lB0WnWKXJGA7s015nyARWljfz5DcX83TKAIlY+QrmvzQTsbIe+hkiFtkyL2gHC6qwF6Fbg=="],
|
"@types/pg": ["@types/pg@8.15.4", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg=="],
|
||||||
|
|
||||||
"@types/triple-beam": ["@types/triple-beam@1.3.5", "", {}, "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="],
|
"@types/triple-beam": ["@types/triple-beam@1.3.5", "", {}, "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="],
|
||||||
|
|
||||||
@ -405,19 +423,19 @@
|
|||||||
|
|
||||||
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
|
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
|
||||||
|
|
||||||
"@vitest/expect": ["@vitest/expect@3.1.2", "", { "dependencies": { "@vitest/spy": "3.1.2", "@vitest/utils": "3.1.2", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA=="],
|
"@vitest/expect": ["@vitest/expect@3.2.2", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.2", "@vitest/utils": "3.2.2", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-ipHw0z669vEMjzz3xQE8nJX1s0rQIb7oEl4jjl35qWTwm/KIHERIg/p/zORrjAaZKXfsv7IybcNGHwhOOAPMwQ=="],
|
||||||
|
|
||||||
"@vitest/mocker": ["@vitest/mocker@3.1.2", "", { "dependencies": { "@vitest/spy": "3.1.2", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw=="],
|
"@vitest/mocker": ["@vitest/mocker@3.2.2", "", { "dependencies": { "@vitest/spy": "3.2.2", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-jKojcaRyIYpDEf+s7/dD3LJt53c0dPfp5zCPXz9H/kcGrSlovU/t1yEaNzM9oFME3dcd4ULwRI/x0Po1Zf+LTw=="],
|
||||||
|
|
||||||
"@vitest/pretty-format": ["@vitest/pretty-format@3.1.2", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w=="],
|
"@vitest/pretty-format": ["@vitest/pretty-format@3.2.2", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-FY4o4U1UDhO9KMd2Wee5vumwcaHw7Vg4V7yR4Oq6uK34nhEJOmdRYrk3ClburPRUA09lXD/oXWZ8y/Sdma0aUQ=="],
|
||||||
|
|
||||||
"@vitest/runner": ["@vitest/runner@3.1.2", "", { "dependencies": { "@vitest/utils": "3.1.2", "pathe": "^2.0.3" } }, "sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g=="],
|
"@vitest/runner": ["@vitest/runner@3.2.2", "", { "dependencies": { "@vitest/utils": "3.2.2", "pathe": "^2.0.3" } }, "sha512-GYcHcaS3ejGRZYed2GAkvsjBeXIEerDKdX3orQrBJqLRiea4NSS9qvn9Nxmuy1IwIB+EjFOaxXnX79l8HFaBwg=="],
|
||||||
|
|
||||||
"@vitest/snapshot": ["@vitest/snapshot@3.1.2", "", { "dependencies": { "@vitest/pretty-format": "3.1.2", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q=="],
|
"@vitest/snapshot": ["@vitest/snapshot@3.2.2", "", { "dependencies": { "@vitest/pretty-format": "3.2.2", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-aMEI2XFlR1aNECbBs5C5IZopfi5Lb8QJZGGpzS8ZUHML5La5wCbrbhLOVSME68qwpT05ROEEOAZPRXFpxZV2wA=="],
|
||||||
|
|
||||||
"@vitest/spy": ["@vitest/spy@3.1.2", "", { "dependencies": { "tinyspy": "^3.0.2" } }, "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA=="],
|
"@vitest/spy": ["@vitest/spy@3.2.2", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-6Utxlx3o7pcTxvp0u8kUiXtRFScMrUg28KjB3R2hon7w4YqOFAEA9QwzPVVS1QNL3smo4xRNOpNZClRVfpMcYg=="],
|
||||||
|
|
||||||
"@vitest/utils": ["@vitest/utils@3.1.2", "", { "dependencies": { "@vitest/pretty-format": "3.1.2", "loupe": "^3.1.3", "tinyrainbow": "^2.0.0" } }, "sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg=="],
|
"@vitest/utils": ["@vitest/utils@3.2.2", "", { "dependencies": { "@vitest/pretty-format": "3.2.2", "loupe": "^3.1.3", "tinyrainbow": "^2.0.0" } }, "sha512-qJYMllrWpF/OYfWHP32T31QCaLa3BAzT/n/8mNGhPdVcjY+JYazQFO1nsJvXU12Kp1xMpNY4AGuljPTNjQve6A=="],
|
||||||
|
|
||||||
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
|
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
|
||||||
|
|
||||||
@ -435,6 +453,8 @@
|
|||||||
|
|
||||||
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
|
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
|
||||||
|
|
||||||
|
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
|
||||||
|
|
||||||
"argon2id": ["argon2id@1.0.1", "", {}, "sha512-rsiD3lX+0L0CsiZARp3bf9EGxprtuWAT7PpiJd+Fk53URV0/USOQkBIP1dLTV8t6aui0ECbymQ9W9YCcTd6XgA=="],
|
"argon2id": ["argon2id@1.0.1", "", {}, "sha512-rsiD3lX+0L0CsiZARp3bf9EGxprtuWAT7PpiJd+Fk53URV0/USOQkBIP1dLTV8t6aui0ECbymQ9W9YCcTd6XgA=="],
|
||||||
|
|
||||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||||
@ -445,7 +465,7 @@
|
|||||||
|
|
||||||
"assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="],
|
"assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="],
|
||||||
|
|
||||||
"astro": ["astro@5.7.8", "", { "dependencies": { "@astrojs/compiler": "^2.11.0", "@astrojs/internal-helpers": "0.6.1", "@astrojs/markdown-remark": "6.3.1", "@astrojs/telemetry": "3.2.1", "@capsizecss/unpack": "^2.4.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.4", "acorn": "^8.14.1", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.2.0", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.0.2", "cssesc": "^3.0.0", "debug": "^4.4.0", "deterministic-object-hash": "^2.0.2", "devalue": "^5.1.1", "diff": "^5.2.0", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.6.0", "esbuild": "^0.25.0", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.1.1", "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.17", "magicast": "^0.3.5", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.0", "package-manager-detector": "^1.1.0", "picomatch": "^4.0.2", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.1", "shiki": "^3.2.1", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.12", "tsconfck": "^3.1.5", "ultrahtml": "^1.6.0", "unifont": "~0.4.1", "unist-util-visit": "^5.0.0", "unstorage": "^1.15.0", "vfile": "^6.0.3", "vite": "^6.2.6", "vitefu": "^1.0.6", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.1", "zod": "^3.24.2", "zod-to-json-schema": "^3.24.5", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.33.3" }, "bin": { "astro": "astro.js" } }, "sha512-82ku6+wOGXP5c5+YOkBzEGJ/k8/GVSeN0xD/TNUrPf5nvWpGGpngxtUAwuruKF6wIxRC1/SwlUVCs/4QT98iZQ=="],
|
"astro": ["astro@5.9.0", "", { "dependencies": { "@astrojs/compiler": "^2.12.0", "@astrojs/internal-helpers": "0.6.1", "@astrojs/markdown-remark": "6.3.2", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^2.4.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.4", "acorn": "^8.14.1", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.2.0", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.0.2", "cssesc": "^3.0.0", "debug": "^4.4.0", "deterministic-object-hash": "^2.0.2", "devalue": "^5.1.1", "diff": "^5.2.0", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.6.0", "esbuild": "^0.25.0", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.3.0", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.1.1", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.17", "magicast": "^0.3.5", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.0", "package-manager-detector": "^1.1.0", "picomatch": "^4.0.2", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.1", "shiki": "^3.2.1", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.12", "tsconfck": "^3.1.5", "ultrahtml": "^1.6.0", "unifont": "~0.5.0", "unist-util-visit": "^5.0.0", "unstorage": "^1.15.0", "vfile": "^6.0.3", "vite": "^6.3.4", "vitefu": "^1.0.6", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.1", "zod": "^3.24.2", "zod-to-json-schema": "^3.24.5", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.33.3" }, "bin": { "astro": "astro.js" } }, "sha512-AHF7oZDBQRwggHUG0bwBhRQjrDD+vJpCtPd0/GVxDB1hGRV0SQuFWS0UHX5bYczIqFcao1z9o9o0r2rQtHrTMg=="],
|
||||||
|
|
||||||
"async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
|
"async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
|
||||||
|
|
||||||
@ -455,8 +475,6 @@
|
|||||||
|
|
||||||
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||||
|
|
||||||
"backend": ["backend@workspace:packages/backend"],
|
|
||||||
|
|
||||||
"bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="],
|
"bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="],
|
||||||
|
|
||||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
@ -483,11 +501,11 @@
|
|||||||
|
|
||||||
"browser-stdout": ["browser-stdout@1.3.1", "", {}, "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="],
|
"browser-stdout": ["browser-stdout@1.3.1", "", {}, "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="],
|
||||||
|
|
||||||
"browserslist": ["browserslist@4.24.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" } }, "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A=="],
|
"browserslist": ["browserslist@4.25.0", "", { "dependencies": { "caniuse-lite": "^1.0.30001718", "electron-to-chromium": "^1.5.160", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA=="],
|
||||||
|
|
||||||
"bullmq": ["bullmq@5.52.1", "", { "dependencies": { "cron-parser": "^4.9.0", "ioredis": "^5.4.1", "msgpackr": "^1.11.2", "node-abort-controller": "^3.1.1", "semver": "^7.5.4", "tslib": "^2.0.0", "uuid": "^9.0.0" } }, "sha512-u7CSV9wID3MBEX2DNubEErbAlrADgm8abUBAi6h8rQTnuTkhhgMs2iD7uhqplK8lIgUOkBIW3sDJWaMSInH47A=="],
|
"bullmq": ["bullmq@5.53.2", "", { "dependencies": { "cron-parser": "^4.9.0", "ioredis": "^5.4.1", "msgpackr": "^1.11.2", "node-abort-controller": "^3.1.1", "semver": "^7.5.4", "tslib": "^2.0.0", "uuid": "^9.0.0" } }, "sha512-xHgxrP/yNJHD7VCw1h+eRBh+2TCPBCM39uC9gCyksYc6ufcJP+HTZ/A2lzB2x7qMFWrvsX7tM40AT2BmdkYL/Q=="],
|
||||||
|
|
||||||
"bun-types": ["bun-types@1.2.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-dbkp5Lo8HDrXkLrONm6bk+yiiYQSntvFUzQp0v3pzTAsXk6FtgVMjdQ+lzFNVAmQFUkPQZ3WMZqH5tTo+Dp/IA=="],
|
"bun-types": ["bun-types@1.2.15", "", { "dependencies": { "@types/node": "*" } }, "sha512-NarRIaS+iOaQU1JPfyKhZm4AsUOrwUOqRNHY0XxI8GI8jYxiLXLcdjYMG9UKS+fwWasc1uw1htV9AX24dD+p4w=="],
|
||||||
|
|
||||||
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
|
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
|
||||||
|
|
||||||
@ -499,7 +517,7 @@
|
|||||||
|
|
||||||
"camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="],
|
"camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="],
|
||||||
|
|
||||||
"caniuse-lite": ["caniuse-lite@1.0.30001715", "", {}, "sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw=="],
|
"caniuse-lite": ["caniuse-lite@1.0.30001721", "", {}, "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ=="],
|
||||||
|
|
||||||
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
|
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
|
||||||
|
|
||||||
@ -563,8 +581,6 @@
|
|||||||
|
|
||||||
"cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="],
|
"cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="],
|
||||||
|
|
||||||
"core": ["core@workspace:packages/core"],
|
|
||||||
|
|
||||||
"crawler": ["crawler@workspace:packages/crawler"],
|
"crawler": ["crawler@workspace:packages/crawler"],
|
||||||
|
|
||||||
"cron-parser": ["cron-parser@4.9.0", "", { "dependencies": { "luxon": "^3.2.1" } }, "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q=="],
|
"cron-parser": ["cron-parser@4.9.0", "", { "dependencies": { "luxon": "^3.2.1" } }, "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q=="],
|
||||||
@ -573,7 +589,7 @@
|
|||||||
|
|
||||||
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
||||||
|
|
||||||
"crossws": ["crossws@0.3.4", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-uj0O1ETYX1Bh6uSgktfPvwDiPYGQ3aI4qVsaC/LWpkIzGj1nUYm5FK3K+t11oOlpN01lGbprFCH4wBlKdJjVgw=="],
|
"crossws": ["crossws@0.3.5", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA=="],
|
||||||
|
|
||||||
"css-tree": ["css-tree@3.1.0", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="],
|
"css-tree": ["css-tree@3.1.0", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="],
|
||||||
|
|
||||||
@ -581,7 +597,7 @@
|
|||||||
|
|
||||||
"date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="],
|
"date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="],
|
||||||
|
|
||||||
"debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
"decamelize": ["decamelize@4.0.0", "", {}, "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ=="],
|
"decamelize": ["decamelize@4.0.0", "", {}, "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ=="],
|
||||||
|
|
||||||
@ -637,7 +653,7 @@
|
|||||||
|
|
||||||
"ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
|
"ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
|
||||||
|
|
||||||
"electron-to-chromium": ["electron-to-chromium@1.5.143", "", {}, "sha512-QqklJMOFBMqe46k8iIOwA9l2hz57V2OKMmP5eSWcUvwx+mASAsbU+wkF1pHjn9ZVSBPrsYWr4/W/95y5SwYg2g=="],
|
"electron-to-chromium": ["electron-to-chromium@1.5.165", "", {}, "sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw=="],
|
||||||
|
|
||||||
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||||
|
|
||||||
@ -661,7 +677,7 @@
|
|||||||
|
|
||||||
"es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="],
|
"es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="],
|
||||||
|
|
||||||
"esbuild": ["esbuild@0.25.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.3", "@esbuild/android-arm": "0.25.3", "@esbuild/android-arm64": "0.25.3", "@esbuild/android-x64": "0.25.3", "@esbuild/darwin-arm64": "0.25.3", "@esbuild/darwin-x64": "0.25.3", "@esbuild/freebsd-arm64": "0.25.3", "@esbuild/freebsd-x64": "0.25.3", "@esbuild/linux-arm": "0.25.3", "@esbuild/linux-arm64": "0.25.3", "@esbuild/linux-ia32": "0.25.3", "@esbuild/linux-loong64": "0.25.3", "@esbuild/linux-mips64el": "0.25.3", "@esbuild/linux-ppc64": "0.25.3", "@esbuild/linux-riscv64": "0.25.3", "@esbuild/linux-s390x": "0.25.3", "@esbuild/linux-x64": "0.25.3", "@esbuild/netbsd-arm64": "0.25.3", "@esbuild/netbsd-x64": "0.25.3", "@esbuild/openbsd-arm64": "0.25.3", "@esbuild/openbsd-x64": "0.25.3", "@esbuild/sunos-x64": "0.25.3", "@esbuild/win32-arm64": "0.25.3", "@esbuild/win32-ia32": "0.25.3", "@esbuild/win32-x64": "0.25.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q=="],
|
"esbuild": ["esbuild@0.25.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.5", "@esbuild/android-arm": "0.25.5", "@esbuild/android-arm64": "0.25.5", "@esbuild/android-x64": "0.25.5", "@esbuild/darwin-arm64": "0.25.5", "@esbuild/darwin-x64": "0.25.5", "@esbuild/freebsd-arm64": "0.25.5", "@esbuild/freebsd-x64": "0.25.5", "@esbuild/linux-arm": "0.25.5", "@esbuild/linux-arm64": "0.25.5", "@esbuild/linux-ia32": "0.25.5", "@esbuild/linux-loong64": "0.25.5", "@esbuild/linux-mips64el": "0.25.5", "@esbuild/linux-ppc64": "0.25.5", "@esbuild/linux-riscv64": "0.25.5", "@esbuild/linux-s390x": "0.25.5", "@esbuild/linux-x64": "0.25.5", "@esbuild/netbsd-arm64": "0.25.5", "@esbuild/netbsd-x64": "0.25.5", "@esbuild/openbsd-arm64": "0.25.5", "@esbuild/openbsd-x64": "0.25.5", "@esbuild/sunos-x64": "0.25.5", "@esbuild/win32-arm64": "0.25.5", "@esbuild/win32-ia32": "0.25.5", "@esbuild/win32-x64": "0.25.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ=="],
|
||||||
|
|
||||||
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
||||||
|
|
||||||
@ -671,7 +687,7 @@
|
|||||||
|
|
||||||
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
|
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
|
||||||
|
|
||||||
"esrap": ["esrap@1.4.6", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-F/D2mADJ9SHY3IwksD4DAXjTt7qt7GWUf3/8RhCNWmC/67tyb55dpimHmy7EplakFaflV0R/PC+fdSPqrRHAQw=="],
|
"esrap": ["esrap@1.4.7", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-0ZxW6guTF/AeKeKi7he93lmgv7Hx7giD1tBrOeVqkqsZGQJd2/kfnL7LdIsr9FT/AtkBK9XeDTov+gxprBqdEg=="],
|
||||||
|
|
||||||
"estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
|
"estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
|
||||||
|
|
||||||
@ -689,7 +705,7 @@
|
|||||||
|
|
||||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||||
|
|
||||||
"fdir": ["fdir@6.4.4", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg=="],
|
"fdir": ["fdir@6.4.5", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw=="],
|
||||||
|
|
||||||
"fecha": ["fecha@4.2.3", "", {}, "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="],
|
"fecha": ["fecha@4.2.3", "", {}, "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="],
|
||||||
|
|
||||||
@ -709,11 +725,13 @@
|
|||||||
|
|
||||||
"fn.name": ["fn.name@1.1.0", "", {}, "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="],
|
"fn.name": ["fn.name@1.1.0", "", {}, "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="],
|
||||||
|
|
||||||
|
"fontace": ["fontace@0.3.0", "", { "dependencies": { "@types/fontkit": "^2.0.8", "fontkit": "^2.0.4" } }, "sha512-czoqATrcnxgWb/nAkfyIrRp6Q8biYj7nGnL6zfhTcX+JKKpWHFBnb8uNMw/kZr7u++3Y3wYSYoZgHkCcsuBpBg=="],
|
||||||
|
|
||||||
"fontkit": ["fontkit@2.0.4", "", { "dependencies": { "@swc/helpers": "^0.5.12", "brotli": "^1.3.2", "clone": "^2.1.2", "dfa": "^1.2.0", "fast-deep-equal": "^3.1.3", "restructure": "^3.0.0", "tiny-inflate": "^1.0.3", "unicode-properties": "^1.4.0", "unicode-trie": "^2.0.0" } }, "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g=="],
|
"fontkit": ["fontkit@2.0.4", "", { "dependencies": { "@swc/helpers": "^0.5.12", "brotli": "^1.3.2", "clone": "^2.1.2", "dfa": "^1.2.0", "fast-deep-equal": "^3.1.3", "restructure": "^3.0.0", "tiny-inflate": "^1.0.3", "unicode-properties": "^1.4.0", "unicode-trie": "^2.0.0" } }, "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g=="],
|
||||||
|
|
||||||
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
|
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
|
||||||
|
|
||||||
"form-data": ["form-data@4.0.2", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" } }, "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w=="],
|
"form-data": ["form-data@4.0.3", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA=="],
|
||||||
|
|
||||||
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
|
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
|
||||||
|
|
||||||
@ -793,7 +811,7 @@
|
|||||||
|
|
||||||
"he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="],
|
"he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="],
|
||||||
|
|
||||||
"hono": ["hono@4.7.8", "", {}, "sha512-PCibtFdxa7/Ldud9yddl1G81GjYaeMYYTq4ywSaNsYbB1Lug4mwtOMJf2WXykL0pntYwmpRJeOI3NmoDgD+Jxw=="],
|
"hono": ["hono@4.7.11", "", {}, "sha512-rv0JMwC0KALbbmwJDEnxvQCeJh+xbS3KEWW5PC9cMJ08Ur9xgatI0HmtgYZfOdOSOeYsp5LO2cOhdI8cLEbDEQ=="],
|
||||||
|
|
||||||
"hono-rate-limiter": ["hono-rate-limiter@0.4.2", "", { "peerDependencies": { "hono": "^4.1.1" } }, "sha512-AAtFqgADyrmbDijcRTT/HJfwqfvhalya2Zo+MgfdrMPas3zSMD8SU03cv+ZsYwRU1swv7zgVt0shwN059yzhjw=="],
|
"hono-rate-limiter": ["hono-rate-limiter@0.4.2", "", { "peerDependencies": { "hono": "^4.1.1" } }, "sha512-AAtFqgADyrmbDijcRTT/HJfwqfvhalya2Zo+MgfdrMPas3zSMD8SU03cv+ZsYwRU1swv7zgVt0shwN059yzhjw=="],
|
||||||
|
|
||||||
@ -801,7 +819,7 @@
|
|||||||
|
|
||||||
"html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="],
|
"html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="],
|
||||||
|
|
||||||
"http-cache-semantics": ["http-cache-semantics@4.1.1", "", {}, "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="],
|
"http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="],
|
||||||
|
|
||||||
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
|
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
|
||||||
|
|
||||||
@ -867,27 +885,27 @@
|
|||||||
|
|
||||||
"kuler": ["kuler@2.0.0", "", {}, "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="],
|
"kuler": ["kuler@2.0.0", "", {}, "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="],
|
||||||
|
|
||||||
"lightningcss": ["lightningcss@1.29.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.29.2", "lightningcss-darwin-x64": "1.29.2", "lightningcss-freebsd-x64": "1.29.2", "lightningcss-linux-arm-gnueabihf": "1.29.2", "lightningcss-linux-arm64-gnu": "1.29.2", "lightningcss-linux-arm64-musl": "1.29.2", "lightningcss-linux-x64-gnu": "1.29.2", "lightningcss-linux-x64-musl": "1.29.2", "lightningcss-win32-arm64-msvc": "1.29.2", "lightningcss-win32-x64-msvc": "1.29.2" } }, "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA=="],
|
"lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="],
|
||||||
|
|
||||||
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.29.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA=="],
|
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="],
|
||||||
|
|
||||||
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.29.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w=="],
|
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="],
|
||||||
|
|
||||||
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.29.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg=="],
|
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="],
|
||||||
|
|
||||||
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.29.2", "", { "os": "linux", "cpu": "arm" }, "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg=="],
|
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="],
|
||||||
|
|
||||||
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.29.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ=="],
|
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="],
|
||||||
|
|
||||||
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.29.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ=="],
|
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="],
|
||||||
|
|
||||||
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.29.2", "", { "os": "linux", "cpu": "x64" }, "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg=="],
|
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="],
|
||||||
|
|
||||||
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.29.2", "", { "os": "linux", "cpu": "x64" }, "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w=="],
|
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="],
|
||||||
|
|
||||||
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.29.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw=="],
|
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="],
|
||||||
|
|
||||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.29.2", "", { "os": "win32", "cpu": "x64" }, "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA=="],
|
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="],
|
||||||
|
|
||||||
"limiter": ["limiter@3.0.0", "", {}, "sha512-hev7DuXojsTFl2YwyzUJMDnZ/qBDd3yZQLSH3aD4tdL1cqfc3TMnoecEJtWFaQFdErZsKoFMBTxF/FBSkgDbEg=="],
|
"limiter": ["limiter@3.0.0", "", {}, "sha512-hev7DuXojsTFl2YwyzUJMDnZ/qBDd3yZQLSH3aD4tdL1cqfc3TMnoecEJtWFaQFdErZsKoFMBTxF/FBSkgDbEg=="],
|
||||||
|
|
||||||
@ -1037,7 +1055,7 @@
|
|||||||
|
|
||||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
|
|
||||||
"msgpackr": ["msgpackr@1.11.2", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g=="],
|
"msgpackr": ["msgpackr@1.11.4", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-uaff7RG9VIC4jacFW9xzL3jc0iM32DNHe4jYVycBcjUePT/Klnfj7pqtWJt9khvDFizmjN2TlYniYmSS2LIaZg=="],
|
||||||
|
|
||||||
"msgpackr-extract": ["msgpackr-extract@3.0.3", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA=="],
|
"msgpackr-extract": ["msgpackr-extract@3.0.3", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA=="],
|
||||||
|
|
||||||
@ -1075,8 +1093,6 @@
|
|||||||
|
|
||||||
"object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="],
|
"object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="],
|
||||||
|
|
||||||
"obuf": ["obuf@1.1.2", "", {}, "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="],
|
|
||||||
|
|
||||||
"ofetch": ["ofetch@1.4.1", "", { "dependencies": { "destr": "^2.0.3", "node-fetch-native": "^1.6.4", "ufo": "^1.5.4" } }, "sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw=="],
|
"ofetch": ["ofetch@1.4.1", "", { "dependencies": { "destr": "^2.0.3", "node-fetch-native": "^1.6.4", "ufo": "^1.5.4" } }, "sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw=="],
|
||||||
|
|
||||||
"ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="],
|
"ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="],
|
||||||
@ -1087,9 +1103,9 @@
|
|||||||
|
|
||||||
"one-time": ["one-time@1.0.0", "", { "dependencies": { "fn.name": "1.x.x" } }, "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g=="],
|
"one-time": ["one-time@1.0.0", "", { "dependencies": { "fn.name": "1.x.x" } }, "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g=="],
|
||||||
|
|
||||||
"oniguruma-parser": ["oniguruma-parser@0.12.0", "", {}, "sha512-fD9o5ebCmEAA9dLysajdQvuKzLL7cj+w7DQjuO3Cb6IwafENfx6iL+RGkmyW82pVRsvgzixsWinHvgxTMJvdIA=="],
|
"oniguruma-parser": ["oniguruma-parser@0.12.1", "", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="],
|
||||||
|
|
||||||
"oniguruma-to-es": ["oniguruma-to-es@4.3.1", "", { "dependencies": { "oniguruma-parser": "^0.12.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-VtX1kepWO+7HG7IWV5v72JhiqofK7XsiHmtgnvurnNOTdIvE5mrdWYtsOrQyrXCv1L2Ckm08hywp+MFO7rC4Ug=="],
|
"oniguruma-to-es": ["oniguruma-to-es@4.3.3", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg=="],
|
||||||
|
|
||||||
"onnxruntime-common": ["onnxruntime-common@1.19.2", "", {}, "sha512-a4R7wYEVFbZBlp0BfhpbFWqe4opCor3KM+5Wm22Az3NGDcQMiU2hfG/0MfnBs+1ZrlSGmlgWeMcXQkDk1UFb8Q=="],
|
"onnxruntime-common": ["onnxruntime-common@1.19.2", "", {}, "sha512-a4R7wYEVFbZBlp0BfhpbFWqe4opCor3KM+5Wm22Az3NGDcQMiU2hfG/0MfnBs+1ZrlSGmlgWeMcXQkDk1UFb8Q=="],
|
||||||
|
|
||||||
@ -1107,7 +1123,7 @@
|
|||||||
|
|
||||||
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
|
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
|
||||||
|
|
||||||
"package-manager-detector": ["package-manager-detector@1.2.0", "", {}, "sha512-PutJepsOtsqVfUsxCzgTTpyXmiAgvKptIgY4th5eq5UXXFhj5PxfQ9hnGkypMeovpAvVshFRItoFHYO18TCOqA=="],
|
"package-manager-detector": ["package-manager-detector@1.3.0", "", {}, "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ=="],
|
||||||
|
|
||||||
"pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="],
|
"pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="],
|
||||||
|
|
||||||
@ -1131,21 +1147,19 @@
|
|||||||
|
|
||||||
"pathval": ["pathval@2.0.0", "", {}, "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA=="],
|
"pathval": ["pathval@2.0.0", "", {}, "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA=="],
|
||||||
|
|
||||||
"pg": ["pg@8.15.6", "", { "dependencies": { "pg-connection-string": "^2.8.5", "pg-pool": "^3.9.6", "pg-protocol": "^1.9.5", "pg-types": "^2.1.0", "pgpass": "1.x" }, "optionalDependencies": { "pg-cloudflare": "^1.2.5" }, "peerDependencies": { "pg-native": ">=3.0.1" }, "optionalPeers": ["pg-native"] }, "sha512-yvao7YI3GdmmrslNVsZgx9PfntfWrnXwtR+K/DjI0I/sTKif4Z623um+sjVZ1hk5670B+ODjvHDAckKdjmPTsg=="],
|
"pg": ["pg@8.16.0", "", { "dependencies": { "pg-connection-string": "^2.9.0", "pg-pool": "^3.10.0", "pg-protocol": "^1.10.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, "optionalDependencies": { "pg-cloudflare": "^1.2.5" }, "peerDependencies": { "pg-native": ">=3.0.1" }, "optionalPeers": ["pg-native"] }, "sha512-7SKfdvP8CTNXjMUzfcVTaI+TDzBEeaUnVwiVGZQD1Hh33Kpev7liQba9uLd4CfN8r9mCVsD0JIpq03+Unpz+kg=="],
|
||||||
|
|
||||||
"pg-cloudflare": ["pg-cloudflare@1.2.5", "", {}, "sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg=="],
|
"pg-cloudflare": ["pg-cloudflare@1.2.5", "", {}, "sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg=="],
|
||||||
|
|
||||||
"pg-connection-string": ["pg-connection-string@2.8.5", "", {}, "sha512-Ni8FuZ8yAF+sWZzojvtLE2b03cqjO5jNULcHFfM9ZZ0/JXrgom5pBREbtnAw7oxsxJqHw9Nz/XWORUEL3/IFow=="],
|
"pg-connection-string": ["pg-connection-string@2.9.0", "", {}, "sha512-P2DEBKuvh5RClafLngkAuGe9OUlFV7ebu8w1kmaaOgPcpJd1RIFh7otETfI6hAR8YupOLFTY7nuvvIn7PLciUQ=="],
|
||||||
|
|
||||||
"pg-int8": ["pg-int8@1.0.1", "", {}, "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="],
|
"pg-int8": ["pg-int8@1.0.1", "", {}, "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="],
|
||||||
|
|
||||||
"pg-numeric": ["pg-numeric@1.0.2", "", {}, "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw=="],
|
"pg-pool": ["pg-pool@3.10.0", "", { "peerDependencies": { "pg": ">=8.0" } }, "sha512-DzZ26On4sQ0KmqnO34muPcmKbhrjmyiO4lCCR0VwEd7MjmiKf5NTg/6+apUEu0NF7ESa37CGzFxH513CoUmWnA=="],
|
||||||
|
|
||||||
"pg-pool": ["pg-pool@3.9.6", "", { "peerDependencies": { "pg": ">=8.0" } }, "sha512-rFen0G7adh1YmgvrmE5IPIqbb+IgEzENUm+tzm6MLLDSlPRoZVhzU1WdML9PV2W5GOdRA9qBKURlbt1OsXOsPw=="],
|
"pg-protocol": ["pg-protocol@1.10.0", "", {}, "sha512-IpdytjudNuLv8nhlHs/UrVBhU0e78J0oIS/0AVdTbWxSOkFUVdsHC/NrorO6nXsQNDTT1kzDSOMJubBQviX18Q=="],
|
||||||
|
|
||||||
"pg-protocol": ["pg-protocol@1.9.5", "", {}, "sha512-DYTWtWpfd5FOro3UnAfwvhD8jh59r2ig8bPtc9H8Ds7MscE/9NYruUQWFAOuraRl29jwcT2kyMFQ3MxeaVjUhg=="],
|
"pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="],
|
||||||
|
|
||||||
"pg-types": ["pg-types@4.0.2", "", { "dependencies": { "pg-int8": "1.0.1", "pg-numeric": "1.0.2", "postgres-array": "~3.0.1", "postgres-bytea": "~3.0.0", "postgres-date": "~2.1.0", "postgres-interval": "^3.0.0", "postgres-range": "^1.1.1" } }, "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng=="],
|
|
||||||
|
|
||||||
"pgpass": ["pgpass@1.0.5", "", { "dependencies": { "split2": "^4.1.0" } }, "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug=="],
|
"pgpass": ["pgpass@1.0.5", "", { "dependencies": { "split2": "^4.1.0" } }, "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug=="],
|
||||||
|
|
||||||
@ -1157,21 +1171,19 @@
|
|||||||
|
|
||||||
"platform": ["platform@1.3.6", "", {}, "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="],
|
"platform": ["platform@1.3.6", "", {}, "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="],
|
||||||
|
|
||||||
"postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="],
|
"postcss": ["postcss@8.5.4", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w=="],
|
||||||
|
|
||||||
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
|
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
|
||||||
|
|
||||||
"postgres": ["postgres@3.4.5", "", {}, "sha512-cDWgoah1Gez9rN3H4165peY9qfpEo+SA61oQv65O3cRUE1pOEoJWwddwcqKE8XZYjbblOJlYDlLV4h67HrEVDg=="],
|
"postgres": ["postgres@3.4.7", "", {}, "sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw=="],
|
||||||
|
|
||||||
"postgres-array": ["postgres-array@3.0.4", "", {}, "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ=="],
|
"postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="],
|
||||||
|
|
||||||
"postgres-bytea": ["postgres-bytea@3.0.0", "", { "dependencies": { "obuf": "~1.1.2" } }, "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw=="],
|
"postgres-bytea": ["postgres-bytea@1.0.0", "", {}, "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w=="],
|
||||||
|
|
||||||
"postgres-date": ["postgres-date@2.1.0", "", {}, "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA=="],
|
"postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="],
|
||||||
|
|
||||||
"postgres-interval": ["postgres-interval@3.0.0", "", {}, "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw=="],
|
"postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="],
|
||||||
|
|
||||||
"postgres-range": ["postgres-range@1.1.4", "", {}, "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w=="],
|
|
||||||
|
|
||||||
"prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
|
"prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
|
||||||
|
|
||||||
@ -1181,9 +1193,9 @@
|
|||||||
|
|
||||||
"property-expr": ["property-expr@2.0.6", "", {}, "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA=="],
|
"property-expr": ["property-expr@2.0.6", "", {}, "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA=="],
|
||||||
|
|
||||||
"property-information": ["property-information@7.0.0", "", {}, "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg=="],
|
"property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
|
||||||
|
|
||||||
"protobufjs": ["protobufjs@7.5.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-Z2E/kOY1QjoMlCytmexzYfDm/w5fKAiRwpSzGtdnXW1zC88Z2yXazHHrOtwCzn+7wSxyE8PYM4rvVcMphF9sOA=="],
|
"protobufjs": ["protobufjs@7.5.3", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw=="],
|
||||||
|
|
||||||
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
|
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
|
||||||
|
|
||||||
@ -1195,7 +1207,7 @@
|
|||||||
|
|
||||||
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
|
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
|
||||||
|
|
||||||
"rate-limit-redis": ["rate-limit-redis@4.2.0", "", { "peerDependencies": { "express-rate-limit": ">= 6" } }, "sha512-wV450NQyKC24NmPosJb2131RoczLdfIJdKCReNwtVpm5998U8SgKrAZrIHaN/NfQgqOHaan8Uq++B4sa5REwjA=="],
|
"rate-limit-redis": ["rate-limit-redis@4.2.1", "", { "peerDependencies": { "express-rate-limit": ">= 6" } }, "sha512-JsUsVmRVI6G/XrlYtfGV1NMCbGS/CVYayHkxD5Ism5FaL8qpFHCXbFkUeIi5WJ/onJOKWCgtB/xtCLa6qSXb4g=="],
|
||||||
|
|
||||||
"raw-body": ["raw-body@3.0.0", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.6.3", "unpipe": "1.0.0" } }, "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g=="],
|
"raw-body": ["raw-body@3.0.0", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.6.3", "unpipe": "1.0.0" } }, "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g=="],
|
||||||
|
|
||||||
@ -1249,7 +1261,7 @@
|
|||||||
|
|
||||||
"roarr": ["roarr@2.15.4", "", { "dependencies": { "boolean": "^3.0.1", "detect-node": "^2.0.4", "globalthis": "^1.0.1", "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" } }, "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="],
|
"roarr": ["roarr@2.15.4", "", { "dependencies": { "boolean": "^3.0.1", "detect-node": "^2.0.4", "globalthis": "^1.0.1", "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" } }, "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="],
|
||||||
|
|
||||||
"rollup": ["rollup@4.40.1", "", { "dependencies": { "@types/estree": "1.0.7" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.40.1", "@rollup/rollup-android-arm64": "4.40.1", "@rollup/rollup-darwin-arm64": "4.40.1", "@rollup/rollup-darwin-x64": "4.40.1", "@rollup/rollup-freebsd-arm64": "4.40.1", "@rollup/rollup-freebsd-x64": "4.40.1", "@rollup/rollup-linux-arm-gnueabihf": "4.40.1", "@rollup/rollup-linux-arm-musleabihf": "4.40.1", "@rollup/rollup-linux-arm64-gnu": "4.40.1", "@rollup/rollup-linux-arm64-musl": "4.40.1", "@rollup/rollup-linux-loongarch64-gnu": "4.40.1", "@rollup/rollup-linux-powerpc64le-gnu": "4.40.1", "@rollup/rollup-linux-riscv64-gnu": "4.40.1", "@rollup/rollup-linux-riscv64-musl": "4.40.1", "@rollup/rollup-linux-s390x-gnu": "4.40.1", "@rollup/rollup-linux-x64-gnu": "4.40.1", "@rollup/rollup-linux-x64-musl": "4.40.1", "@rollup/rollup-win32-arm64-msvc": "4.40.1", "@rollup/rollup-win32-ia32-msvc": "4.40.1", "@rollup/rollup-win32-x64-msvc": "4.40.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw=="],
|
"rollup": ["rollup@4.41.1", "", { "dependencies": { "@types/estree": "1.0.7" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.41.1", "@rollup/rollup-android-arm64": "4.41.1", "@rollup/rollup-darwin-arm64": "4.41.1", "@rollup/rollup-darwin-x64": "4.41.1", "@rollup/rollup-freebsd-arm64": "4.41.1", "@rollup/rollup-freebsd-x64": "4.41.1", "@rollup/rollup-linux-arm-gnueabihf": "4.41.1", "@rollup/rollup-linux-arm-musleabihf": "4.41.1", "@rollup/rollup-linux-arm64-gnu": "4.41.1", "@rollup/rollup-linux-arm64-musl": "4.41.1", "@rollup/rollup-linux-loongarch64-gnu": "4.41.1", "@rollup/rollup-linux-powerpc64le-gnu": "4.41.1", "@rollup/rollup-linux-riscv64-gnu": "4.41.1", "@rollup/rollup-linux-riscv64-musl": "4.41.1", "@rollup/rollup-linux-s390x-gnu": "4.41.1", "@rollup/rollup-linux-x64-gnu": "4.41.1", "@rollup/rollup-linux-x64-musl": "4.41.1", "@rollup/rollup-win32-arm64-msvc": "4.41.1", "@rollup/rollup-win32-ia32-msvc": "4.41.1", "@rollup/rollup-win32-x64-msvc": "4.41.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw=="],
|
||||||
|
|
||||||
"router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
|
"router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
|
||||||
|
|
||||||
@ -1261,7 +1273,7 @@
|
|||||||
|
|
||||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||||
|
|
||||||
"semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
||||||
|
|
||||||
"semver-compare": ["semver-compare@1.0.0", "", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="],
|
"semver-compare": ["semver-compare@1.0.0", "", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="],
|
||||||
|
|
||||||
@ -1277,15 +1289,15 @@
|
|||||||
|
|
||||||
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
|
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
|
||||||
|
|
||||||
"sharp": ["sharp@0.34.1", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.7.1" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.1", "@img/sharp-darwin-x64": "0.34.1", "@img/sharp-libvips-darwin-arm64": "1.1.0", "@img/sharp-libvips-darwin-x64": "1.1.0", "@img/sharp-libvips-linux-arm": "1.1.0", "@img/sharp-libvips-linux-arm64": "1.1.0", "@img/sharp-libvips-linux-ppc64": "1.1.0", "@img/sharp-libvips-linux-s390x": "1.1.0", "@img/sharp-libvips-linux-x64": "1.1.0", "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", "@img/sharp-libvips-linuxmusl-x64": "1.1.0", "@img/sharp-linux-arm": "0.34.1", "@img/sharp-linux-arm64": "0.34.1", "@img/sharp-linux-s390x": "0.34.1", "@img/sharp-linux-x64": "0.34.1", "@img/sharp-linuxmusl-arm64": "0.34.1", "@img/sharp-linuxmusl-x64": "0.34.1", "@img/sharp-wasm32": "0.34.1", "@img/sharp-win32-ia32": "0.34.1", "@img/sharp-win32-x64": "0.34.1" } }, "sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg=="],
|
"sharp": ["sharp@0.34.2", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.4", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.2", "@img/sharp-darwin-x64": "0.34.2", "@img/sharp-libvips-darwin-arm64": "1.1.0", "@img/sharp-libvips-darwin-x64": "1.1.0", "@img/sharp-libvips-linux-arm": "1.1.0", "@img/sharp-libvips-linux-arm64": "1.1.0", "@img/sharp-libvips-linux-ppc64": "1.1.0", "@img/sharp-libvips-linux-s390x": "1.1.0", "@img/sharp-libvips-linux-x64": "1.1.0", "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", "@img/sharp-libvips-linuxmusl-x64": "1.1.0", "@img/sharp-linux-arm": "0.34.2", "@img/sharp-linux-arm64": "0.34.2", "@img/sharp-linux-s390x": "0.34.2", "@img/sharp-linux-x64": "0.34.2", "@img/sharp-linuxmusl-arm64": "0.34.2", "@img/sharp-linuxmusl-x64": "0.34.2", "@img/sharp-wasm32": "0.34.2", "@img/sharp-win32-arm64": "0.34.2", "@img/sharp-win32-ia32": "0.34.2", "@img/sharp-win32-x64": "0.34.2" } }, "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg=="],
|
||||||
|
|
||||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||||
|
|
||||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||||
|
|
||||||
"shell-quote": ["shell-quote@1.8.2", "", {}, "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA=="],
|
"shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="],
|
||||||
|
|
||||||
"shiki": ["shiki@3.3.0", "", { "dependencies": { "@shikijs/core": "3.3.0", "@shikijs/engine-javascript": "3.3.0", "@shikijs/engine-oniguruma": "3.3.0", "@shikijs/langs": "3.3.0", "@shikijs/themes": "3.3.0", "@shikijs/types": "3.3.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-j0Z1tG5vlOFGW8JVj0Cpuatzvshes7VJy5ncDmmMaYcmnGW0Js1N81TOW98ivTFNZfKRn9uwEg/aIm638o368g=="],
|
"shiki": ["shiki@3.5.0", "", { "dependencies": { "@shikijs/core": "3.5.0", "@shikijs/engine-javascript": "3.5.0", "@shikijs/engine-oniguruma": "3.5.0", "@shikijs/langs": "3.5.0", "@shikijs/themes": "3.5.0", "@shikijs/types": "3.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-1lyPuqIPPAlmR1BKtDkxiuoZTB2IKSyr+GeHXu4ReOyHoEMhCnUoGZDUv4SJRH0Bi4QmsEPsrkQCRSOgnVRC+g=="],
|
||||||
|
|
||||||
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
|
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
|
||||||
|
|
||||||
@ -1345,13 +1357,13 @@
|
|||||||
|
|
||||||
"supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
|
"supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
|
||||||
|
|
||||||
"svelte": ["svelte@5.28.2", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^1.4.6", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-FbWBxgWOpQfhKvoGJv/TFwzqb4EhJbwCD17dB0tEpQiw1XyUEKZJtgm4nA4xq3LLsMo7hu5UY/BOFmroAxKTMg=="],
|
"svelte": ["svelte@5.33.14", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^1.4.6", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-kRlbhIlMTijbFmVDQFDeKXPLlX1/ovXwV0I162wRqQhRcygaqDIcu1d/Ese3H2uI+yt3uT8E7ndgDthQv5v5BA=="],
|
||||||
|
|
||||||
"svelte2tsx": ["svelte2tsx@0.7.36", "", { "dependencies": { "dedent-js": "^1.0.1", "pascal-case": "^3.1.1" }, "peerDependencies": { "svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0", "typescript": "^4.9.4 || ^5.0.0" } }, "sha512-nBlERuCZRwmpebC8m0vDqZ9oaKsqW8frQS2l3zwFQW1voQIkItYtHxh1F5OTZEmE0meDIH6cxU36eIOQVOxlCw=="],
|
"svelte2tsx": ["svelte2tsx@0.7.39", "", { "dependencies": { "dedent-js": "^1.0.1", "pascal-case": "^3.1.1" }, "peerDependencies": { "svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0", "typescript": "^4.9.4 || ^5.0.0" } }, "sha512-NX8a7eSqF1hr6WKArvXr7TV7DeE+y0kDFD7L5JP7TWqlwFidzGKaG415p992MHREiiEWOv2xIWXJ+mlONofs0A=="],
|
||||||
|
|
||||||
"tailwindcss": ["tailwindcss@4.1.4", "", {}, "sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A=="],
|
"tailwindcss": ["tailwindcss@4.1.8", "", {}, "sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og=="],
|
||||||
|
|
||||||
"tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="],
|
"tapable": ["tapable@2.2.2", "", {}, "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg=="],
|
||||||
|
|
||||||
"tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="],
|
"tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="],
|
||||||
|
|
||||||
@ -1369,13 +1381,13 @@
|
|||||||
|
|
||||||
"tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="],
|
"tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="],
|
||||||
|
|
||||||
"tinyglobby": ["tinyglobby@0.2.13", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw=="],
|
"tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
|
||||||
|
|
||||||
"tinypool": ["tinypool@1.0.2", "", {}, "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA=="],
|
"tinypool": ["tinypool@1.1.0", "", {}, "sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ=="],
|
||||||
|
|
||||||
"tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="],
|
"tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="],
|
||||||
|
|
||||||
"tinyspy": ["tinyspy@3.0.2", "", {}, "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q=="],
|
"tinyspy": ["tinyspy@4.0.3", "", {}, "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A=="],
|
||||||
|
|
||||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||||
|
|
||||||
@ -1395,7 +1407,7 @@
|
|||||||
|
|
||||||
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
|
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
|
||||||
|
|
||||||
"tsconfck": ["tsconfck@3.1.5", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg=="],
|
"tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="],
|
||||||
|
|
||||||
"tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
|
"tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
|
||||||
|
|
||||||
@ -1427,7 +1439,7 @@
|
|||||||
|
|
||||||
"unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="],
|
"unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="],
|
||||||
|
|
||||||
"unifont": ["unifont@0.4.1", "", { "dependencies": { "css-tree": "^3.0.0", "ohash": "^2.0.0" } }, "sha512-zKSY9qO8svWYns+FGKjyVdLvpGPwqmsCjeJLN1xndMiqxHWBAhoWDMYMG960MxeV48clBmG+fDP59dHY1VoZvg=="],
|
"unifont": ["unifont@0.5.0", "", { "dependencies": { "css-tree": "^3.0.0", "ohash": "^2.0.0" } }, "sha512-4DueXMP5Hy4n607sh+vJ+rajoLu778aU3GzqeTCqsD/EaUcvqZT9wPC8kgK6Vjh22ZskrxyRCR71FwNOaYn6jA=="],
|
||||||
|
|
||||||
"unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="],
|
"unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="],
|
||||||
|
|
||||||
@ -1465,15 +1477,15 @@
|
|||||||
|
|
||||||
"vfile-message": ["vfile-message@4.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="],
|
"vfile-message": ["vfile-message@4.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="],
|
||||||
|
|
||||||
"vite": ["vite@6.3.3", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw=="],
|
"vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="],
|
||||||
|
|
||||||
"vite-node": ["vite-node@3.1.2", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.0", "es-module-lexer": "^1.6.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA=="],
|
"vite-node": ["vite-node@3.2.2", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-Xj/jovjZvDXOq2FgLXu8NsY4uHUMWtzVmMC2LkCu9HWdr9Qu1Is5sanX3Z4jOFKdohfaWDnEJWp9pRP0vVpAcA=="],
|
||||||
|
|
||||||
"vite-tsconfig-paths": ["vite-tsconfig-paths@5.1.4", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w=="],
|
"vite-tsconfig-paths": ["vite-tsconfig-paths@5.1.4", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w=="],
|
||||||
|
|
||||||
"vitefu": ["vitefu@1.0.6", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" }, "optionalPeers": ["vite"] }, "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA=="],
|
"vitefu": ["vitefu@1.0.6", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" }, "optionalPeers": ["vite"] }, "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA=="],
|
||||||
|
|
||||||
"vitest": ["vitest@3.1.2", "", { "dependencies": { "@vitest/expect": "3.1.2", "@vitest/mocker": "3.1.2", "@vitest/pretty-format": "^3.1.2", "@vitest/runner": "3.1.2", "@vitest/snapshot": "3.1.2", "@vitest/spy": "3.1.2", "@vitest/utils": "3.1.2", "chai": "^5.2.0", "debug": "^4.4.0", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.13", "tinypool": "^1.0.2", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0", "vite-node": "3.1.2", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.1.2", "@vitest/ui": "3.1.2", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-WaxpJe092ID1C0mr+LH9MmNrhfzi8I65EX/NRU/Ld016KqQNRgxSOlGNP1hHN+a/F8L15Mh8klwaF77zR3GeDQ=="],
|
"vitest": ["vitest@3.2.2", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.2", "@vitest/mocker": "3.2.2", "@vitest/pretty-format": "^3.2.2", "@vitest/runner": "3.2.2", "@vitest/snapshot": "3.2.2", "@vitest/spy": "3.2.2", "@vitest/utils": "3.2.2", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.0", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.2", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.2", "@vitest/ui": "3.2.2", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-fyNn/Rp016Bt5qvY0OQvIUCwW2vnaEBLxP42PmKbNIoasSYjML+8xyeADOPvBe+Xfl/ubIw4og7Lt9jflRsCNw=="],
|
||||||
|
|
||||||
"vitest-tsconfig-paths": ["vitest-tsconfig-paths@3.4.1", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "recrawl-sync": "^2.0.3", "tsconfig-paths": "^3.9.0" } }, "sha512-CnRpA/jcqgZfnkk0yvwFW92UmIpf03wX/wLiQBNWAcOG7nv6Sdz3GsPESAMEqbVy8kHBoWB3XeNamu6PUrFZLA=="],
|
"vitest-tsconfig-paths": ["vitest-tsconfig-paths@3.4.1", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "recrawl-sync": "^2.0.3", "tsconfig-paths": "^3.9.0" } }, "sha512-CnRpA/jcqgZfnkk0yvwFW92UmIpf03wX/wLiQBNWAcOG7nv6Sdz3GsPESAMEqbVy8kHBoWB3XeNamu6PUrFZLA=="],
|
||||||
|
|
||||||
@ -1519,7 +1531,7 @@
|
|||||||
|
|
||||||
"yocto-queue": ["yocto-queue@1.2.1", "", {}, "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg=="],
|
"yocto-queue": ["yocto-queue@1.2.1", "", {}, "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg=="],
|
||||||
|
|
||||||
"yocto-spinner": ["yocto-spinner@0.2.2", "", { "dependencies": { "yoctocolors": "^2.1.1" } }, "sha512-21rPcM3e4vCpOXThiFRByX8amU5By1R0wNS8Oex+DP3YgC8xdU0vEJ/K8cbPLiIJVosSSysgcFof6s6MSD5/Vw=="],
|
"yocto-spinner": ["yocto-spinner@0.2.3", "", { "dependencies": { "yoctocolors": "^2.1.1" } }, "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ=="],
|
||||||
|
|
||||||
"yoctocolors": ["yoctocolors@2.1.1", "", {}, "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ=="],
|
"yoctocolors": ["yoctocolors@2.1.1", "", {}, "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ=="],
|
||||||
|
|
||||||
@ -1527,7 +1539,7 @@
|
|||||||
|
|
||||||
"zimmerframe": ["zimmerframe@1.1.2", "", {}, "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="],
|
"zimmerframe": ["zimmerframe@1.1.2", "", {}, "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="],
|
||||||
|
|
||||||
"zod": ["zod@3.24.3", "", {}, "sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg=="],
|
"zod": ["zod@3.25.51", "", {}, "sha512-TQSnBldh+XSGL+opiSIq0575wvDPqu09AqWe1F7JhUMKY+M91/aGlK4MhpVNO7MgYfHcVCB1ffwAUTJzllKJqg=="],
|
||||||
|
|
||||||
"zod-to-json-schema": ["zod-to-json-schema@3.24.5", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g=="],
|
"zod-to-json-schema": ["zod-to-json-schema@3.24.5", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g=="],
|
||||||
|
|
||||||
@ -1543,6 +1555,8 @@
|
|||||||
|
|
||||||
"@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
|
"@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
|
||||||
|
|
||||||
|
"@koshnic/ratelimit/@types/chai": ["@types/chai@4.3.20", "", {}, "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ=="],
|
||||||
|
|
||||||
"@koshnic/ratelimit/chai": ["chai@4.5.0", "", { "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", "deep-eql": "^4.1.3", "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", "type-detect": "^4.1.0" } }, "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw=="],
|
"@koshnic/ratelimit/chai": ["chai@4.5.0", "", { "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", "deep-eql": "^4.1.3", "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", "type-detect": "^4.1.0" } }, "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw=="],
|
||||||
|
|
||||||
"@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
"@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
@ -1553,7 +1567,7 @@
|
|||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.9", "", { "dependencies": { "@emnapi/core": "^1.4.0", "@emnapi/runtime": "^1.4.0", "@tybys/wasm-util": "^0.9.0" }, "bundled": true }, "sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg=="],
|
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.10", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.9.0" }, "bundled": true }, "sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
|
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
|
||||||
|
|
||||||
@ -1567,7 +1581,7 @@
|
|||||||
|
|
||||||
"boxen/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
"boxen/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
||||||
|
|
||||||
"boxen/type-fest": ["type-fest@4.40.1", "", {}, "sha512-9YvLNnORDpI+vghLU/Nf+zSv0kL47KbVJ1o3sKgoTefl6i+zebxbiDQWoe/oWWqPhIgQdRZRT1KA9sCPL810SA=="],
|
"boxen/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
|
||||||
|
|
||||||
"cliui/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=="],
|
"cliui/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=="],
|
||||||
|
|
||||||
@ -1595,8 +1609,6 @@
|
|||||||
|
|
||||||
"p-locate/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
"p-locate/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||||
|
|
||||||
"pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="],
|
|
||||||
|
|
||||||
"prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
|
"prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
|
||||||
|
|
||||||
"readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
@ -1697,14 +1709,6 @@
|
|||||||
|
|
||||||
"p-locate/p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
"p-locate/p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||||
|
|
||||||
"pg/pg-types/postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="],
|
|
||||||
|
|
||||||
"pg/pg-types/postgres-bytea": ["postgres-bytea@1.0.0", "", {}, "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w=="],
|
|
||||||
|
|
||||||
"pg/pg-types/postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="],
|
|
||||||
|
|
||||||
"pg/pg-types/postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="],
|
|
||||||
|
|
||||||
"sucrase/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"sucrase/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
|
|
||||||
"unstorage/chokidar/readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
"unstorage/chokidar/readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
||||||
|
39
package.json
39
package.json
@ -1,20 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "cvsa",
|
"name": "cvsa",
|
||||||
"version": "2.13.22",
|
"version": "3.15.34",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/frontend",
|
"packages/frontend",
|
||||||
"packages/core",
|
"packages/core",
|
||||||
"packages/backend",
|
"packages/backend",
|
||||||
"packages/crawler"
|
"packages/crawler"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"postgres": "^3.4.5"
|
"arg": "^5.0.2",
|
||||||
},
|
"postgres": "^3.4.5"
|
||||||
"devDependencies": {
|
},
|
||||||
"vite-tsconfig-paths": "^5.1.4",
|
"devDependencies": {
|
||||||
"vitest": "^3.1.2",
|
"@types/bun": "^1.2.15",
|
||||||
"vitest-tsconfig-paths": "^3.4.1"
|
"prettier": "^3.5.3",
|
||||||
}
|
"vite-tsconfig-paths": "^5.1.4",
|
||||||
|
"vitest": "^3.1.2",
|
||||||
|
"vitest-tsconfig-paths": "^3.4.1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,10 @@ export const getJWTsecret = () => {
|
|||||||
if (!secret) {
|
if (!secret) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: "JWT_SECRET is not set",
|
message: "JWT_SECRET is not set",
|
||||||
code: "SERVER_ERROR"
|
code: "SERVER_ERROR",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return [response, true];
|
return [response, true];
|
||||||
}
|
}
|
||||||
return [secret, null];
|
return [secret, null];
|
||||||
}
|
};
|
||||||
|
@ -4,7 +4,7 @@ import { SlidingWindow } from "@core/mq/slidingWindow.ts";
|
|||||||
import { getCaptchaConfigMaxDuration, getCurrentCaptchaDifficulty } from "@/lib/auth/captchaDifficulty.ts";
|
import { getCaptchaConfigMaxDuration, getCurrentCaptchaDifficulty } from "@/lib/auth/captchaDifficulty.ts";
|
||||||
import { sqlCred } from "@core/db/dbNew.ts";
|
import { sqlCred } from "@core/db/dbNew.ts";
|
||||||
import { redis } from "@core/db/redis.ts";
|
import { redis } from "@core/db/redis.ts";
|
||||||
import { verify } from 'hono/jwt';
|
import { verify } from "hono/jwt";
|
||||||
import { JwtTokenInvalid, JwtTokenExpired } from "hono/utils/jwt/types";
|
import { JwtTokenInvalid, JwtTokenExpired } from "hono/utils/jwt/types";
|
||||||
import { getJWTsecret } from "@/lib/auth/getJWTsecret.ts";
|
import { getJWTsecret } from "@/lib/auth/getJWTsecret.ts";
|
||||||
import { lockManager } from "@core/mq/lockManager.ts";
|
import { lockManager } from "@core/mq/lockManager.ts";
|
||||||
@ -23,7 +23,8 @@ export const captchaMiddleware = async (c: Context, next: Next) => {
|
|||||||
if (!authHeader) {
|
if (!authHeader) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: "'Authorization' header is missing.",
|
message: "'Authorization' header is missing.",
|
||||||
code: "UNAUTHORIZED"
|
code: "UNAUTHORIZED",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 401);
|
return c.json<ErrorResponse>(response, 401);
|
||||||
}
|
}
|
||||||
@ -32,7 +33,8 @@ export const captchaMiddleware = async (c: Context, next: Next) => {
|
|||||||
if (!authIsBearer || authHeader.length < 8) {
|
if (!authIsBearer || authHeader.length < 8) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: "'Authorization' header is invalid.",
|
message: "'Authorization' header is invalid.",
|
||||||
code: "INVALID_HEADER"
|
code: "INVALID_HEADER",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 400);
|
return c.json<ErrorResponse>(response, 400);
|
||||||
}
|
}
|
||||||
@ -60,47 +62,48 @@ export const captchaMiddleware = async (c: Context, next: Next) => {
|
|||||||
if (consumed) {
|
if (consumed) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: "Token has already been used.",
|
message: "Token has already been used.",
|
||||||
code: "INVALID_CREDENTIALS"
|
code: "INVALID_CREDENTIALS",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 401);
|
return c.json<ErrorResponse>(response, 401);
|
||||||
}
|
}
|
||||||
if (difficulty < requiredDifficulty) {
|
if (difficulty < requiredDifficulty) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: "Token too weak.",
|
message: "Token too weak.",
|
||||||
code: "UNAUTHORIZED"
|
code: "UNAUTHORIZED",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 401);
|
return c.json<ErrorResponse>(response, 401);
|
||||||
}
|
}
|
||||||
const EXPIRE_FIVE_MINUTES = 300;
|
const EXPIRE_FIVE_MINUTES = 300;
|
||||||
await lockManager.acquireLock(tokenID, EXPIRE_FIVE_MINUTES);
|
await lockManager.acquireLock(tokenID, EXPIRE_FIVE_MINUTES);
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
if (e instanceof JwtTokenInvalid) {
|
if (e instanceof JwtTokenInvalid) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: "Failed to verify the token.",
|
message: "Failed to verify the token.",
|
||||||
code: "INVALID_CREDENTIALS"
|
code: "INVALID_CREDENTIALS",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 400);
|
return c.json<ErrorResponse>(response, 400);
|
||||||
}
|
} else if (e instanceof JwtTokenExpired) {
|
||||||
else if (e instanceof JwtTokenExpired) {
|
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: "Token expired.",
|
message: "Token expired.",
|
||||||
code: "INVALID_CREDENTIALS"
|
code: "INVALID_CREDENTIALS",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 400);
|
return c.json<ErrorResponse>(response, 400);
|
||||||
}
|
} else if (e instanceof ValidationError) {
|
||||||
else if (e instanceof ValidationError) {
|
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
code: "INVALID_QUERY_PARAMS",
|
code: "INVALID_QUERY_PARAMS",
|
||||||
message: "Invalid query parameters",
|
message: "Invalid query parameters",
|
||||||
errors: e.errors
|
errors: e.errors
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 400);
|
return c.json<ErrorResponse>(response, 400);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: "Unknown error.",
|
message: "Unknown error.",
|
||||||
code: "UNKNOWN_ERROR"
|
code: "UNKNOWN_ERROR",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 500);
|
return c.json<ErrorResponse>(response, 500);
|
||||||
}
|
}
|
||||||
@ -114,4 +117,4 @@ export const captchaMiddleware = async (c: Context, next: Next) => {
|
|||||||
await window.event(`captcha-${identifierWithIP}`);
|
await window.event(`captcha-${identifierWithIP}`);
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
};
|
};
|
||||||
|
14
packages/backend/middleware/cors.ts
Normal file
14
packages/backend/middleware/cors.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { cors } from "hono/cors";
|
||||||
|
import { Context, Next } from "hono";
|
||||||
|
|
||||||
|
export const corsMiddleware = async (c: Context, next: Next) => {
|
||||||
|
if (c.req.path.startsWith("/user") || c.req.path.startsWith("/login")) {
|
||||||
|
const corsMiddlewareHandler = cors({
|
||||||
|
origin: c.req.header("Origin"),
|
||||||
|
credentials: true
|
||||||
|
});
|
||||||
|
return corsMiddlewareHandler(c, next);
|
||||||
|
}
|
||||||
|
const corsMiddlewareHandler = cors();
|
||||||
|
return corsMiddlewareHandler(c, next);
|
||||||
|
};
|
@ -6,8 +6,8 @@ import { RateLimiter } from "@koshnic/ratelimit";
|
|||||||
import { ErrorResponse } from "@/src/schema";
|
import { ErrorResponse } from "@/src/schema";
|
||||||
import { redis } from "@core/db/redis.ts";
|
import { redis } from "@core/db/redis.ts";
|
||||||
|
|
||||||
export const getIdentifier = (c: Context, includeIP: boolean = true) => {
|
export const getUserIP = (c: Context) => {
|
||||||
let ipAddr = generateRandomId(6);
|
let ipAddr = null;
|
||||||
const info = getConnInfo(c);
|
const info = getConnInfo(c);
|
||||||
if (info.remote && info.remote.address) {
|
if (info.remote && info.remote.address) {
|
||||||
ipAddr = info.remote.address;
|
ipAddr = info.remote.address;
|
||||||
@ -16,6 +16,14 @@ export const getIdentifier = (c: Context, includeIP: boolean = true) => {
|
|||||||
if (forwardedFor) {
|
if (forwardedFor) {
|
||||||
ipAddr = forwardedFor.split(",")[0];
|
ipAddr = forwardedFor.split(",")[0];
|
||||||
}
|
}
|
||||||
|
return ipAddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getIdentifier = (c: Context, includeIP: boolean = true) => {
|
||||||
|
let ipAddr = generateRandomId(6);
|
||||||
|
if (getUserIP(c)) {
|
||||||
|
ipAddr = getUserIP(c);
|
||||||
|
}
|
||||||
const path = c.req.path;
|
const path = c.req.path;
|
||||||
const method = c.req.method;
|
const method = c.req.method;
|
||||||
const ipIdentifier = includeIP ? `@${ipAddr}` : "";
|
const ipIdentifier = includeIP ? `@${ipAddr}` : "";
|
||||||
@ -35,10 +43,11 @@ export const registerRateLimiter = async (c: Context<BlankEnv, "/user", {}>, nex
|
|||||||
if (!allowed) {
|
if (!allowed) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: `Too many requests, please retry after ${Math.round(retryAfter)} seconds.`,
|
message: `Too many requests, please retry after ${Math.round(retryAfter)} seconds.`,
|
||||||
code: "RATE_LIMIT_EXCEEDED"
|
code: "RATE_LIMIT_EXCEEDED",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 429);
|
return c.json<ErrorResponse>(response, 429);
|
||||||
}
|
}
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "backend",
|
"name": "@cvsa/backend",
|
||||||
|
"private": false,
|
||||||
|
"version": "0.5.3",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"dev": "NODE_ENV=development bun run --hot src/main.ts",
|
"dev": "NODE_ENV=development bun run --hot src/main.ts",
|
||||||
"start": "NODE_ENV=production bun run src/main.ts"
|
"start": "NODE_ENV=production bun run src/main.ts",
|
||||||
|
"build": "bun build ./src/main.ts --target bun --outdir ./dist"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@koshnic/ratelimit": "^1.0.3",
|
||||||
"@rabbit-company/argon2id": "^2.1.0",
|
"@rabbit-company/argon2id": "^2.1.0",
|
||||||
|
"chalk": "^5.4.1",
|
||||||
"hono": "^4.7.8",
|
"hono": "^4.7.8",
|
||||||
"hono-rate-limiter": "^0.4.2",
|
"hono-rate-limiter": "^0.4.2",
|
||||||
"ioredis": "^5.6.1",
|
"ioredis": "^5.6.1",
|
||||||
@ -19,5 +24,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "^1.2.11",
|
"@types/bun": "^1.2.11",
|
||||||
"prettier": "^3.5.3"
|
"prettier": "^3.5.3"
|
||||||
}
|
},
|
||||||
|
"main": "./dist/main.js",
|
||||||
|
"types": "./src/types.d.ts"
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { Context } from "hono";
|
|||||||
import { Bindings, BlankEnv } from "hono/types";
|
import { Bindings, BlankEnv } from "hono/types";
|
||||||
import { ErrorResponse } from "src/schema";
|
import { ErrorResponse } from "src/schema";
|
||||||
import { createHandlers } from "src/utils.ts";
|
import { createHandlers } from "src/utils.ts";
|
||||||
import { sign } from 'hono/jwt'
|
import { sign } from "hono/jwt";
|
||||||
import { generateRandomId } from "@core/lib/randomID.ts";
|
import { generateRandomId } from "@core/lib/randomID.ts";
|
||||||
import { getJWTsecret } from "lib/auth/getJWTsecret.ts";
|
import { getJWTsecret } from "lib/auth/getJWTsecret.ts";
|
||||||
|
|
||||||
@ -34,7 +34,8 @@ export const verifyChallengeHandler = createHandlers(
|
|||||||
if (!ans) {
|
if (!ans) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: "Missing required query parameter: ans",
|
message: "Missing required query parameter: ans",
|
||||||
code: "INVALID_QUERY_PARAMS"
|
code: "INVALID_QUERY_PARAMS",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 400);
|
return c.json<ErrorResponse>(response, 400);
|
||||||
}
|
}
|
||||||
@ -43,26 +44,33 @@ export const verifyChallengeHandler = createHandlers(
|
|||||||
if (data.error && res.status === 404) {
|
if (data.error && res.status === 404) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: data.error,
|
message: data.error,
|
||||||
code: "ENTITY_NOT_FOUND"
|
code: "ENTITY_NOT_FOUND",
|
||||||
|
i18n: {
|
||||||
|
key: "backend.error.captcha_not_found"
|
||||||
|
},
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 401);
|
return c.json<ErrorResponse>(response, 401);
|
||||||
} else if (data.error && res.status === 400) {
|
} else if (data.error && res.status === 400) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: data.error,
|
message: data.error,
|
||||||
code: "INVALID_QUERY_PARAMS"
|
code: "INVALID_QUERY_PARAMS",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 400);
|
return c.json<ErrorResponse>(response, 400);
|
||||||
} else if (data.error) {
|
} else if (data.error) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: data.error,
|
message: data.error,
|
||||||
code: "UNKNOWN_ERROR"
|
code: "UNKNOWN_ERROR",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 500);
|
return c.json<ErrorResponse>(response, 500);
|
||||||
}
|
}
|
||||||
if (!data.success) {
|
if (!data.success) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
message: "Incorrect answer",
|
message: "Incorrect answer",
|
||||||
code: "INVALID_CREDENTIALS"
|
code: "INVALID_CREDENTIALS",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 401);
|
return c.json<ErrorResponse>(response, 401);
|
||||||
}
|
}
|
||||||
@ -74,13 +82,16 @@ export const verifyChallengeHandler = createHandlers(
|
|||||||
const jwtSecret = r as string;
|
const jwtSecret = r as string;
|
||||||
|
|
||||||
const tokenID = generateRandomId(6);
|
const tokenID = generateRandomId(6);
|
||||||
const NOW = Math.floor(Date.now() / 1000)
|
const NOW = Math.floor(Date.now() / 1000);
|
||||||
const FIVE_MINUTES_LATER = NOW + 60 * 5;
|
const FIVE_MINUTES_LATER = NOW + 60 * 5;
|
||||||
const jwt = await sign({
|
const jwt = await sign(
|
||||||
difficulty: data.difficulty!,
|
{
|
||||||
id: tokenID,
|
difficulty: data.difficulty!,
|
||||||
exp: FIVE_MINUTES_LATER
|
id: tokenID,
|
||||||
}, jwtSecret);
|
exp: FIVE_MINUTES_LATER
|
||||||
|
},
|
||||||
|
jwtSecret
|
||||||
|
);
|
||||||
return c.json({
|
return c.json({
|
||||||
token: jwt
|
token: jwt
|
||||||
});
|
});
|
||||||
|
@ -16,12 +16,13 @@ export const getCaptchaDifficultyHandler = createHandlers(async (c) => {
|
|||||||
if (!difficulty) {
|
if (!difficulty) {
|
||||||
const response: ErrorResponse<unknown> = {
|
const response: ErrorResponse<unknown> = {
|
||||||
code: "ENTITY_NOT_FOUND",
|
code: "ENTITY_NOT_FOUND",
|
||||||
message: "No difficulty configs found for this route."
|
message: "No difficulty configs found for this route.",
|
||||||
|
errors: []
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse<unknown>>(response, 404);
|
return c.json<ErrorResponse<unknown>>(response, 404);
|
||||||
}
|
}
|
||||||
return c.json({
|
return c.json({
|
||||||
"difficulty": difficulty
|
difficulty: difficulty
|
||||||
});
|
});
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
if (e instanceof ValidationError) {
|
if (e instanceof ValidationError) {
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
export * from "./session/POST.ts";
|
export * from "./session/POST.ts";
|
||||||
export * from "./[id]/result/GET.ts";
|
export * from "./[id]/result/GET.ts";
|
||||||
|
@ -2,58 +2,50 @@ import { createHandlers } from "src/utils.ts";
|
|||||||
import { getCurrentCaptchaDifficulty } from "@/lib/auth/captchaDifficulty.ts";
|
import { getCurrentCaptchaDifficulty } from "@/lib/auth/captchaDifficulty.ts";
|
||||||
import { sqlCred } from "@core/db/dbNew.ts";
|
import { sqlCred } from "@core/db/dbNew.ts";
|
||||||
import { object, string, ValidationError } from "yup";
|
import { object, string, ValidationError } from "yup";
|
||||||
import { ErrorResponse } from "@/src/schema";
|
import { CaptchaSessionResponse, ErrorResponse } from "@/src/schema";
|
||||||
import type { ContentfulStatusCode } from "hono/utils/http-status";
|
import type { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
|
||||||
const bodySchema = object({
|
const bodySchema = object({
|
||||||
route: string().matches(/(?:GET|POST|PUT|PATCH|DELETE)-\/.*/g)
|
route: string().matches(/(?:GET|POST|PUT|PATCH|DELETE)-\/.*/g)
|
||||||
});
|
});
|
||||||
|
|
||||||
interface CaptchaSessionResponse {
|
|
||||||
success: boolean;
|
|
||||||
id: string;
|
|
||||||
g: string;
|
|
||||||
n: string;
|
|
||||||
t: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const createNewChallenge = async (difficulty: number) => {
|
const createNewChallenge = async (difficulty: number) => {
|
||||||
const baseURL = process.env["UCAPTCHA_URL"];
|
const baseURL = process.env["UCAPTCHA_URL"];
|
||||||
const url = new URL(baseURL);
|
const url = new URL(baseURL);
|
||||||
url.pathname = "/challenge";
|
url.pathname = "/challenge";
|
||||||
return await fetch(url.toString(), {
|
return await fetch(url.toString(), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json"
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
difficulty: difficulty,
|
difficulty: difficulty
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const createCaptchaSessionHandler = createHandlers(async (c) => {
|
export const createCaptchaSessionHandler = createHandlers(async (c) => {
|
||||||
try {
|
try {
|
||||||
const requestBody = await bodySchema.validate(await c.req.json());
|
const requestBody = await bodySchema.validate(await c.req.json());
|
||||||
const { route } = requestBody;
|
const { route } = requestBody;
|
||||||
const difficuly = await getCurrentCaptchaDifficulty(sqlCred, route)
|
const difficuly = await getCurrentCaptchaDifficulty(sqlCred, route);
|
||||||
const res = await createNewChallenge(difficuly);
|
const res = await createNewChallenge(difficuly);
|
||||||
return c.json<CaptchaSessionResponse|unknown>(await res.json(), res.status as ContentfulStatusCode);
|
return c.json<CaptchaSessionResponse | unknown>(await res.json(), res.status as ContentfulStatusCode);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
if (e instanceof ValidationError) {
|
if (e instanceof ValidationError) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
code: "INVALID_QUERY_PARAMS",
|
code: "INVALID_QUERY_PARAMS",
|
||||||
message: "Invalid query parameters",
|
message: "Invalid query parameters",
|
||||||
errors: e.errors
|
errors: e.errors
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse>(response, 400);
|
return c.json<ErrorResponse>(response, 400);
|
||||||
} else {
|
} else {
|
||||||
const response: ErrorResponse<unknown> = {
|
const response: ErrorResponse<unknown> = {
|
||||||
code: "UNKNOWN_ERROR",
|
code: "UNKNOWN_ERROR",
|
||||||
message: "Unknown error",
|
message: "Unknown error",
|
||||||
errors: [e]
|
errors: [e]
|
||||||
};
|
};
|
||||||
return c.json<ErrorResponse<unknown>>(response, 500);
|
return c.json<ErrorResponse<unknown>>(response, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
105
packages/backend/routes/login/session/POST.ts
Normal file
105
packages/backend/routes/login/session/POST.ts
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import { Context } from "hono";
|
||||||
|
import { Bindings, BlankEnv } from "hono/types";
|
||||||
|
import { ErrorResponse, LoginResponse } from "src/schema";
|
||||||
|
import { createHandlers } from "src/utils.ts";
|
||||||
|
import { sqlCred } from "@core/db/dbNew";
|
||||||
|
import { object, string, ValidationError } from "yup";
|
||||||
|
import { setCookie } from "hono/cookie";
|
||||||
|
import Argon2id from "@rabbit-company/argon2id";
|
||||||
|
import { createLoginSession } from "routes/user/POST";
|
||||||
|
import { UserType } from "@core/db/schema";
|
||||||
|
|
||||||
|
const LoginBodySchema = object({
|
||||||
|
username: string().trim().required("Username is required").max(50, "Username cannot exceed 50 characters"),
|
||||||
|
password: string().required("Password is required")
|
||||||
|
});
|
||||||
|
|
||||||
|
export const loginHandler = createHandlers(
|
||||||
|
async (c: Context<BlankEnv & { Bindings: Bindings }, "/user/session/:id">) => {
|
||||||
|
try {
|
||||||
|
const body = await LoginBodySchema.validate(await c.req.json());
|
||||||
|
const { username, password: submittedPassword } = body;
|
||||||
|
|
||||||
|
const result = await sqlCred<UserType[]>`
|
||||||
|
SELECT *
|
||||||
|
FROM users
|
||||||
|
WHERE username = ${username}
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (result.length === 0) {
|
||||||
|
const response: ErrorResponse<string> = {
|
||||||
|
message: `User does not exist.`,
|
||||||
|
errors: [`User ${username} does not exist.`],
|
||||||
|
code: "ENTITY_NOT_FOUND"
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse<string>>(response, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const storedPassword = result[0].password;
|
||||||
|
const uid = result[0].id;
|
||||||
|
const nickname = result[0].nickname;
|
||||||
|
const role = result[0].role;
|
||||||
|
|
||||||
|
const passwordAreSame = await Argon2id.verify(storedPassword, submittedPassword);
|
||||||
|
|
||||||
|
if (!passwordAreSame) {
|
||||||
|
const response: ErrorResponse<string> = {
|
||||||
|
message: "Incorrect password.",
|
||||||
|
errors: [],
|
||||||
|
i18n: {
|
||||||
|
key: "backend.error.incorrect_password"
|
||||||
|
},
|
||||||
|
code: "INVALID_CREDENTIALS"
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse<string>>(response, 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionID = await createLoginSession(uid, c);
|
||||||
|
|
||||||
|
const response: LoginResponse = {
|
||||||
|
uid: uid,
|
||||||
|
username: username,
|
||||||
|
nickname: nickname,
|
||||||
|
role: role,
|
||||||
|
token: sessionID
|
||||||
|
};
|
||||||
|
|
||||||
|
const A_YEAR = 365 * 86400;
|
||||||
|
const isDev = process.env.NODE_ENV === "development";
|
||||||
|
|
||||||
|
setCookie(c, "session_id", sessionID, {
|
||||||
|
path: "/",
|
||||||
|
maxAge: A_YEAR,
|
||||||
|
domain: process.env.DOMAIN,
|
||||||
|
secure: isDev ? true : true,
|
||||||
|
sameSite: isDev ? "None" : "Lax",
|
||||||
|
httpOnly: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return c.json<LoginResponse>(response, 200);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof ValidationError) {
|
||||||
|
const response: ErrorResponse<string> = {
|
||||||
|
message: "Invalid registration data.",
|
||||||
|
errors: e.errors,
|
||||||
|
code: "INVALID_PAYLOAD"
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse<string>>(response, 400);
|
||||||
|
} else if (e instanceof SyntaxError) {
|
||||||
|
const response: ErrorResponse<string> = {
|
||||||
|
message: "Invalid JSON payload.",
|
||||||
|
errors: [e.message],
|
||||||
|
code: "INVALID_FORMAT"
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse<string>>(response, 400);
|
||||||
|
} else {
|
||||||
|
const response: ErrorResponse<string> = {
|
||||||
|
message: "Unknown error.",
|
||||||
|
errors: [(e as Error).message],
|
||||||
|
code: "UNKNOWN_ERROR"
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse<string>>(response, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
140
packages/backend/routes/user/POST.ts
Normal file
140
packages/backend/routes/user/POST.ts
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
import { createHandlers } from "src/utils.ts";
|
||||||
|
import Argon2id from "@rabbit-company/argon2id";
|
||||||
|
import { object, string, ValidationError } from "yup";
|
||||||
|
import type { Context } from "hono";
|
||||||
|
import type { Bindings, BlankEnv, BlankInput } from "hono/types";
|
||||||
|
import { sqlCred } from "@core/db/dbNew.ts";
|
||||||
|
import { ErrorResponse, SignUpResponse } from "src/schema";
|
||||||
|
import { generateRandomId } from "@core/lib/randomID";
|
||||||
|
import { getUserIP } from "@/middleware/rateLimiters";
|
||||||
|
import { setCookie } from "hono/cookie";
|
||||||
|
|
||||||
|
const RegistrationBodySchema = object({
|
||||||
|
username: string().trim().required("Username is required").max(50, "Username cannot exceed 50 characters"),
|
||||||
|
password: string().required("Password is required"),
|
||||||
|
nickname: string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
type ContextType = Context<BlankEnv & { Bindings: Bindings }, "/user", BlankInput>;
|
||||||
|
|
||||||
|
export const userExists = async (username: string) => {
|
||||||
|
const result = await sqlCred`
|
||||||
|
SELECT 1
|
||||||
|
FROM users
|
||||||
|
WHERE username = ${username}
|
||||||
|
`;
|
||||||
|
return result.length > 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createLoginSession = async (uid: number, c: Context): Promise<string> => {
|
||||||
|
const ipAddress = getUserIP(c) || null;
|
||||||
|
const userAgent = c.req.header("User-Agent") || null;
|
||||||
|
const id = generateRandomId(24);
|
||||||
|
await sqlCred`
|
||||||
|
INSERT INTO login_sessions (id, uid, expire_at, ip_address, user_agent)
|
||||||
|
VALUES (${id}, ${uid}, CURRENT_TIMESTAMP + INTERVAL '1 year', ${ipAddress}, ${userAgent})
|
||||||
|
`;
|
||||||
|
return id;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUserIDByName = async (username: string) => {
|
||||||
|
const result = await sqlCred<{ id: number }[]>`
|
||||||
|
SELECT id
|
||||||
|
FROM users
|
||||||
|
WHERE username = ${username}
|
||||||
|
`;
|
||||||
|
if (result.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return result[0].id;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const registerHandler = createHandlers(async (c: ContextType) => {
|
||||||
|
try {
|
||||||
|
const body = await RegistrationBodySchema.validate(await c.req.json());
|
||||||
|
const { username, password, nickname } = body;
|
||||||
|
|
||||||
|
if (await userExists(username)) {
|
||||||
|
const response: ErrorResponse = {
|
||||||
|
message: `User "${username}" already exists.`,
|
||||||
|
code: "ENTITY_EXISTS",
|
||||||
|
errors: [],
|
||||||
|
i18n: {
|
||||||
|
key: "backend.error.user_exists",
|
||||||
|
values: {
|
||||||
|
username: username
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse>(response, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const hash = await Argon2id.hashEncoded(password);
|
||||||
|
|
||||||
|
await sqlCred`
|
||||||
|
INSERT INTO users (username, password, nickname)
|
||||||
|
VALUES (${username}, ${hash}, ${nickname ? nickname : null})
|
||||||
|
`;
|
||||||
|
|
||||||
|
const uid = await getUserIDByName(username);
|
||||||
|
|
||||||
|
if (!uid) {
|
||||||
|
const response: ErrorResponse<string> = {
|
||||||
|
message: "Cannot find registered user.",
|
||||||
|
errors: [`Cannot find user ${username} in table 'users'.`],
|
||||||
|
code: "ENTITY_NOT_FOUND",
|
||||||
|
i18n: {
|
||||||
|
key: "backend.error.user_not_found_after_register",
|
||||||
|
values: {
|
||||||
|
username: username
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse<string>>(response, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionID = await createLoginSession(uid, c);
|
||||||
|
|
||||||
|
const response: SignUpResponse = {
|
||||||
|
username: username,
|
||||||
|
token: sessionID
|
||||||
|
};
|
||||||
|
|
||||||
|
const A_YEAR = 365 * 86400;
|
||||||
|
const isDev = process.env.NODE_ENV === "development";
|
||||||
|
|
||||||
|
setCookie(c, "session_id", sessionID, {
|
||||||
|
path: "/",
|
||||||
|
maxAge: A_YEAR,
|
||||||
|
domain: process.env.DOMAIN,
|
||||||
|
secure: isDev ? false : true,
|
||||||
|
sameSite: "Lax",
|
||||||
|
httpOnly: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return c.json<SignUpResponse>(response, 201);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof ValidationError) {
|
||||||
|
const response: ErrorResponse<string> = {
|
||||||
|
message: "Invalid registration data.",
|
||||||
|
errors: e.errors,
|
||||||
|
code: "INVALID_PAYLOAD"
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse<string>>(response, 400);
|
||||||
|
} else if (e instanceof SyntaxError) {
|
||||||
|
const response: ErrorResponse<string> = {
|
||||||
|
message: "Invalid JSON payload.",
|
||||||
|
errors: [e.message],
|
||||||
|
code: "INVALID_FORMAT"
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse<string>>(response, 400);
|
||||||
|
} else {
|
||||||
|
const response: ErrorResponse<string> = {
|
||||||
|
message: "Unknown error.",
|
||||||
|
errors: [(e as Error).message],
|
||||||
|
code: "UNKNOWN_ERROR"
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse<string>>(response, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -1 +1,2 @@
|
|||||||
export * from "./register.ts";
|
export * from "./POST.ts";
|
||||||
|
export * from "./session/[id]/GET.ts";
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
import { createHandlers } from "src/utils.ts";
|
|
||||||
import Argon2id from "@rabbit-company/argon2id";
|
|
||||||
import { object, string, ValidationError } from "yup";
|
|
||||||
import type { Context } from "hono";
|
|
||||||
import type { Bindings, BlankEnv, BlankInput } from "hono/types";
|
|
||||||
import { sqlCred } from "@core/db/dbNew.ts";
|
|
||||||
import { ErrorResponse, StatusResponse } from "src/schema";
|
|
||||||
|
|
||||||
const RegistrationBodySchema = object({
|
|
||||||
username: string().trim().required("Username is required").max(50, "Username cannot exceed 50 characters"),
|
|
||||||
password: string().required("Password is required"),
|
|
||||||
nickname: string().optional()
|
|
||||||
});
|
|
||||||
|
|
||||||
type ContextType = Context<BlankEnv & { Bindings: Bindings }, "/user", BlankInput>;
|
|
||||||
|
|
||||||
export const userExists = async (username: string) => {
|
|
||||||
const result = await sqlCred`
|
|
||||||
SELECT 1
|
|
||||||
FROM users
|
|
||||||
WHERE username = ${username}
|
|
||||||
`;
|
|
||||||
return result.length > 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const registerHandler = createHandlers(async (c: ContextType) => {
|
|
||||||
try {
|
|
||||||
const body = await RegistrationBodySchema.validate(await c.req.json());
|
|
||||||
const { username, password, nickname } = body;
|
|
||||||
|
|
||||||
if (await userExists(username)) {
|
|
||||||
const response: StatusResponse = {
|
|
||||||
message: `User "${username}" already exists.`
|
|
||||||
};
|
|
||||||
return c.json<StatusResponse>(response, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
const hash = await Argon2id.hashEncoded(password);
|
|
||||||
|
|
||||||
await sqlCred`
|
|
||||||
INSERT INTO users (username, password, nickname)
|
|
||||||
VALUES (${username}, ${hash}, ${nickname ? nickname : null})
|
|
||||||
`;
|
|
||||||
|
|
||||||
const response: StatusResponse = {
|
|
||||||
message: `User '${username}' registered successfully.`
|
|
||||||
};
|
|
||||||
|
|
||||||
return c.json<StatusResponse>(response, 201);
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof ValidationError) {
|
|
||||||
const response: ErrorResponse<string> = {
|
|
||||||
message: "Invalid registration data.",
|
|
||||||
errors: e.errors,
|
|
||||||
code: "INVALID_PAYLOAD"
|
|
||||||
};
|
|
||||||
return c.json<ErrorResponse<string>>(response, 400);
|
|
||||||
} else if (e instanceof SyntaxError) {
|
|
||||||
const response: ErrorResponse<string> = {
|
|
||||||
message: "Invalid JSON payload.",
|
|
||||||
errors: [e.message],
|
|
||||||
code: "INVALID_FORMAT"
|
|
||||||
};
|
|
||||||
return c.json<ErrorResponse<string>>(response, 400);
|
|
||||||
} else {
|
|
||||||
const response: ErrorResponse<string> = {
|
|
||||||
message: "Unknown error.",
|
|
||||||
errors: [(e as Error).message],
|
|
||||||
code: "UNKNOWN_ERROR"
|
|
||||||
};
|
|
||||||
return c.json<ErrorResponse<string>>(response, 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
32
packages/backend/routes/user/session/[id]/GET.ts
Normal file
32
packages/backend/routes/user/session/[id]/GET.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { Context } from "hono";
|
||||||
|
import { Bindings, BlankEnv } from "hono/types";
|
||||||
|
import { ErrorResponse } from "src/schema";
|
||||||
|
import { createHandlers } from "src/utils.ts";
|
||||||
|
import { sqlCred } from "@core/db/dbNew";
|
||||||
|
import { UserType } from "@core/db/schema";
|
||||||
|
|
||||||
|
export const getUserByLoginSessionHandler = createHandlers(
|
||||||
|
async (c: Context<BlankEnv & { Bindings: Bindings }, "/user/session/:id">) => {
|
||||||
|
const id = c.req.param("id");
|
||||||
|
const users = await sqlCred<UserType[]>`
|
||||||
|
SELECT u.*
|
||||||
|
FROM users u
|
||||||
|
JOIN login_sessions ls ON u.id = ls.uid
|
||||||
|
WHERE ls.id = ${id};
|
||||||
|
`;
|
||||||
|
if (users.length === 0) {
|
||||||
|
const response: ErrorResponse = {
|
||||||
|
message: "Cannot find user",
|
||||||
|
code: "ENTITY_NOT_FOUND",
|
||||||
|
errors: []
|
||||||
|
};
|
||||||
|
return c.json<ErrorResponse>(response, 404);
|
||||||
|
}
|
||||||
|
const user = users[0];
|
||||||
|
return c.json({
|
||||||
|
username: user.username,
|
||||||
|
nickname: user.nickname,
|
||||||
|
role: user.role
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
@ -2,7 +2,7 @@ import { Hono } from "hono";
|
|||||||
import type { TimingVariables } from "hono/timing";
|
import type { TimingVariables } from "hono/timing";
|
||||||
import { startServer } from "./startServer.ts";
|
import { startServer } from "./startServer.ts";
|
||||||
import { configureRoutes } from "./routing.ts";
|
import { configureRoutes } from "./routing.ts";
|
||||||
import { configureMiddleWares } from "middleware";
|
import { configureMiddleWares } from "./middleware.ts";
|
||||||
import { notFoundRoute } from "routes/404.ts";
|
import { notFoundRoute } from "routes/404.ts";
|
||||||
|
|
||||||
type Variables = TimingVariables;
|
type Variables = TimingVariables;
|
||||||
@ -15,4 +15,4 @@ configureRoutes(app);
|
|||||||
|
|
||||||
await startServer(app);
|
await startServer(app);
|
||||||
|
|
||||||
export const VERSION = "0.4.6";
|
export const VERSION = "0.5.3";
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { Variables } from "hono/types";
|
|
||||||
import { bodyLimitForPing } from "./bodyLimits.ts";
|
|
||||||
import { pingHandler } from "routes/ping";
|
|
||||||
import { registerRateLimiter } from "./rateLimiters.ts";
|
|
||||||
import { preetifyResponse } from "./preetifyResponse.ts";
|
|
||||||
import { logger } from "./logger.ts";
|
|
||||||
import { timing } from "hono/timing";
|
import { timing } from "hono/timing";
|
||||||
import { contentType } from "./contentType.ts";
|
import { Variables } from "hono/types";
|
||||||
import { captchaMiddleware } from "./captcha.ts";
|
import { pingHandler } from "routes/ping";
|
||||||
import { cors } from 'hono/cors';
|
import { logger } from "middleware/logger.ts";
|
||||||
|
import { corsMiddleware } from "@/middleware/cors";
|
||||||
|
import { contentType } from "middleware/contentType.ts";
|
||||||
|
import { captchaMiddleware } from "middleware/captcha.ts";
|
||||||
|
import { bodyLimitForPing } from "middleware/bodyLimits.ts";
|
||||||
|
import { registerRateLimiter } from "middleware/rateLimiters.ts";
|
||||||
|
import { preetifyResponse } from "middleware/preetifyResponse.ts";
|
||||||
|
|
||||||
export function configureMiddleWares(app: Hono<{ Variables: Variables }>) {
|
export function configureMiddleWares(app: Hono<{ Variables: Variables }>) {
|
||||||
app.all("*", cors());
|
app.use("*", corsMiddleware);
|
||||||
|
|
||||||
app.use("*", contentType);
|
app.use("*", contentType);
|
||||||
app.use(timing());
|
app.use(timing());
|
||||||
app.use("*", preetifyResponse);
|
app.use("*", preetifyResponse);
|
@ -1,23 +1,26 @@
|
|||||||
import { rootHandler } from "routes";
|
import { rootHandler } from "routes";
|
||||||
import { pingHandler } from "routes/ping";
|
import { pingHandler } from "routes/ping";
|
||||||
import { registerHandler } from "routes/user";
|
import { getUserByLoginSessionHandler, registerHandler } from "routes/user";
|
||||||
import { videoInfoHandler, getSnapshotsHanlder } from "routes/video";
|
import { videoInfoHandler, getSnapshotsHanlder } from "routes/video";
|
||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { Variables } from "hono/types";
|
import { Variables } from "hono/types";
|
||||||
import { createCaptchaSessionHandler, verifyChallengeHandler } from "routes/captcha";
|
import { createCaptchaSessionHandler, verifyChallengeHandler } from "routes/captcha";
|
||||||
import { getCaptchaDifficultyHandler } from "../routes/captcha/difficulty/GET.ts";
|
import { getCaptchaDifficultyHandler } from "routes/captcha/difficulty/GET.ts";
|
||||||
|
import { loginHandler } from "@/routes/login/session/POST";
|
||||||
|
|
||||||
export function configureRoutes(app: Hono<{ Variables: Variables }>) {
|
export function configureRoutes(app: Hono<{ Variables: Variables }>) {
|
||||||
app.get("/", ...rootHandler);
|
app.get("/", ...rootHandler);
|
||||||
app.all("/ping", ...pingHandler);
|
app.all("/ping", ...pingHandler);
|
||||||
|
|
||||||
app.get("/video/:id/snapshots", ...getSnapshotsHanlder);
|
app.get("/video/:id/snapshots", ...getSnapshotsHanlder);
|
||||||
app.post("/user", ...registerHandler);
|
|
||||||
|
|
||||||
app.get("/video/:id/info", ...videoInfoHandler);
|
app.get("/video/:id/info", ...videoInfoHandler);
|
||||||
|
|
||||||
|
app.post("/login/session", ...loginHandler);
|
||||||
|
|
||||||
|
app.post("/user", ...registerHandler);
|
||||||
|
app.get("/user/session/:id", ...getUserByLoginSessionHandler);
|
||||||
|
|
||||||
app.post("/captcha/session", ...createCaptchaSessionHandler);
|
app.post("/captcha/session", ...createCaptchaSessionHandler);
|
||||||
app.get("/captcha/:id/result", ...verifyChallengeHandler);
|
app.get("/captcha/:id/result", ...verifyChallengeHandler);
|
||||||
|
app.get("/captcha/difficulty", ...getCaptchaDifficultyHandler);
|
||||||
app.get("/captcha/difficulty", ...getCaptchaDifficultyHandler)
|
|
||||||
}
|
}
|
||||||
|
52
packages/backend/src/schema.d.ts
vendored
52
packages/backend/src/schema.d.ts
vendored
@ -1,4 +1,4 @@
|
|||||||
type ErrorCode =
|
export type ErrorCode =
|
||||||
| "INVALID_QUERY_PARAMS"
|
| "INVALID_QUERY_PARAMS"
|
||||||
| "UNKNOWN_ERROR"
|
| "UNKNOWN_ERROR"
|
||||||
| "INVALID_PAYLOAD"
|
| "INVALID_PAYLOAD"
|
||||||
@ -9,14 +9,58 @@ type ErrorCode =
|
|||||||
| "INVALID_CREDENTIALS"
|
| "INVALID_CREDENTIALS"
|
||||||
| "ENTITY_NOT_FOUND"
|
| "ENTITY_NOT_FOUND"
|
||||||
| "SERVER_ERROR"
|
| "SERVER_ERROR"
|
||||||
| "RATE_LIMIT_EXCEEDED";
|
| "RATE_LIMIT_EXCEEDED"
|
||||||
|
| "ENTITY_EXISTS";
|
||||||
|
|
||||||
export interface ErrorResponse<E=string> {
|
export interface ErrorResponse<E = string> {
|
||||||
code: ErrorCode;
|
code: ErrorCode;
|
||||||
message: string;
|
message: string;
|
||||||
errors?: E[];
|
errors: E[] = [];
|
||||||
|
i18n?: {
|
||||||
|
key: string;
|
||||||
|
values?: {
|
||||||
|
[key: string]: string | number | Date;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StatusResponse {
|
export interface StatusResponse {
|
||||||
message: string;
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CaptchaSessionResponse = ErrorResponse | CaptchaSessionRawResponse;
|
||||||
|
|
||||||
|
interface CaptchaSessionRawResponse {
|
||||||
|
success: boolean;
|
||||||
|
id: string;
|
||||||
|
g: string;
|
||||||
|
n: string;
|
||||||
|
t: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoginResponse {
|
||||||
|
uid: number;
|
||||||
|
username: string;
|
||||||
|
nickname: string | null;
|
||||||
|
role: string;
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SignUpResponse {
|
||||||
|
username: string;
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserResponse {
|
||||||
|
username: string;
|
||||||
|
nickname: string | null;
|
||||||
|
role: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CaptchaVerificationRawResponse = {
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CaptchaVerificationResponse =
|
||||||
|
| ErrorResponse
|
||||||
|
| CaptchaVerificationRawResponse;
|
||||||
|
1
packages/backend/src/types.d.ts
vendored
Normal file
1
packages/backend/src/types.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./schema";
|
@ -1,8 +1,8 @@
|
|||||||
const requiredEnvVars = ["DB_HOST", "DB_NAME", "DB_USER", "DB_PASSWORD", "DB_PORT", "DB_NAME_CRED"];
|
const requiredEnvVars = ["DB_HOST", "DB_NAME", "DB_USER", "DB_PASSWORD", "DB_PORT", "DB_NAME_CRED"];
|
||||||
|
|
||||||
const getEnvVar = (key: string) => {
|
const getEnvVar = (key: string) => {
|
||||||
return process.env[key] || import.meta.env[key];
|
return process.env[key] || import.meta.env[key];
|
||||||
}
|
};
|
||||||
|
|
||||||
const unsetVars = requiredEnvVars.filter((key) => getEnvVar(key) === undefined);
|
const unsetVars = requiredEnvVars.filter((key) => getEnvVar(key) === undefined);
|
||||||
|
|
||||||
|
37
packages/core/db/schema.d.ts
vendored
37
packages/core/db/schema.d.ts
vendored
@ -1,16 +1,3 @@
|
|||||||
export interface AllDataType {
|
|
||||||
id: number;
|
|
||||||
aid: number;
|
|
||||||
bvid: string | null;
|
|
||||||
description: string | null;
|
|
||||||
uid: number | null;
|
|
||||||
tags: string | null;
|
|
||||||
title: string | null;
|
|
||||||
published_at: string | null;
|
|
||||||
duration: number;
|
|
||||||
created_at: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BiliUserType {
|
export interface BiliUserType {
|
||||||
id: number;
|
id: number;
|
||||||
uid: number;
|
uid: number;
|
||||||
@ -53,3 +40,27 @@ export interface SnapshotScheduleType {
|
|||||||
finished_at?: string;
|
finished_at?: string;
|
||||||
status: string;
|
status: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UserType {
|
||||||
|
id: number;
|
||||||
|
username: string;
|
||||||
|
nickname: string | null;
|
||||||
|
password: string;
|
||||||
|
unq_id: string;
|
||||||
|
role: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BiliVideoMetadataType {
|
||||||
|
id: number;
|
||||||
|
aid: number;
|
||||||
|
bvid: string | null;
|
||||||
|
description: string | null;
|
||||||
|
uid: number | null;
|
||||||
|
tags: string | null;
|
||||||
|
title: string | null;
|
||||||
|
published_at: Date | null;
|
||||||
|
duration: number | null;
|
||||||
|
created_at: Date;
|
||||||
|
status: number;
|
||||||
|
cover_url: string | null;
|
||||||
|
}
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
import type { Client } from "https://deno.land/x/postgres@v0.19.3/mod.ts";
|
|
||||||
import type { VideoSnapshotType } from "./schema.d.ts";
|
|
||||||
|
|
||||||
export async function getVideoSnapshots(
|
|
||||||
client: Client,
|
|
||||||
aid: number,
|
|
||||||
limit: number,
|
|
||||||
pageOrOffset: number,
|
|
||||||
reverse: boolean,
|
|
||||||
mode: "page" | "offset" = "page",
|
|
||||||
) {
|
|
||||||
const offset = mode === "page" ? (pageOrOffset - 1) * limit : pageOrOffset;
|
|
||||||
const queryDesc: string = `
|
|
||||||
SELECT *
|
|
||||||
FROM video_snapshot
|
|
||||||
WHERE aid = $1
|
|
||||||
ORDER BY created_at DESC
|
|
||||||
LIMIT $2
|
|
||||||
OFFSET $3
|
|
||||||
`;
|
|
||||||
const queryAsc: string = `
|
|
||||||
SELECT *
|
|
||||||
FROM video_snapshot
|
|
||||||
WHERE aid = $1
|
|
||||||
ORDER BY created_at
|
|
||||||
LIMIT $2 OFFSET $3
|
|
||||||
`;
|
|
||||||
const query = reverse ? queryAsc : queryDesc;
|
|
||||||
const queryResult = await client.queryObject<VideoSnapshotType>(query, [aid, limit, offset]);
|
|
||||||
return queryResult.rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getVideoSnapshotsByBV(
|
|
||||||
client: Client,
|
|
||||||
bv: string,
|
|
||||||
limit: number,
|
|
||||||
pageOrOffset: number,
|
|
||||||
reverse: boolean,
|
|
||||||
mode: "page" | "offset" = "page",
|
|
||||||
) {
|
|
||||||
const offset = mode === "page" ? (pageOrOffset - 1) * limit : pageOrOffset;
|
|
||||||
const queryAsc = `
|
|
||||||
SELECT vs.*
|
|
||||||
FROM video_snapshot vs
|
|
||||||
JOIN bilibili_metadata bm ON vs.aid = bm.aid
|
|
||||||
WHERE bm.bvid = $1
|
|
||||||
ORDER BY vs.created_at
|
|
||||||
LIMIT $2
|
|
||||||
OFFSET $3
|
|
||||||
`;
|
|
||||||
const queryDesc: string = `
|
|
||||||
SELECT *
|
|
||||||
FROM video_snapshot vs
|
|
||||||
JOIN bilibili_metadata bm ON vs.aid = bm.aid
|
|
||||||
WHERE bm.bvid = $1
|
|
||||||
ORDER BY vs.created_at DESC
|
|
||||||
LIMIT $2 OFFSET $3
|
|
||||||
`;
|
|
||||||
const query = reverse ? queryAsc : queryDesc;
|
|
||||||
const queryResult = await client.queryObject<VideoSnapshotType>(query, [bv, limit, offset]);
|
|
||||||
return queryResult.rows;
|
|
||||||
}
|
|
1
packages/core/index.ts
Normal file
1
packages/core/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./db/dbNew";
|
@ -1 +0,0 @@
|
|||||||
export const DB_VERSION = 10;
|
|
4
packages/core/net/bilibili.d.ts
vendored
4
packages/core/net/bilibili.d.ts
vendored
@ -38,6 +38,10 @@ interface VideoInfoData {
|
|||||||
ctime: number;
|
ctime: number;
|
||||||
desc: string;
|
desc: string;
|
||||||
desc_v2: string;
|
desc_v2: string;
|
||||||
|
tname: string;
|
||||||
|
tid: number;
|
||||||
|
tid_v2: number;
|
||||||
|
tname_v2: string;
|
||||||
state: number;
|
state: number;
|
||||||
duration: number;
|
duration: number;
|
||||||
owner: {
|
owner: {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "core",
|
"name": "@cvsa/core",
|
||||||
|
"private": false,
|
||||||
|
"version": "0.0.7",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "bun --env-file=.env.test run vitest"
|
"test": "bun --env-file=.env.test run vitest",
|
||||||
|
"build": "bun build ./index.ts --target node --outdir ./dist"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@koshnic/ratelimit": "^1.0.3",
|
"@koshnic/ratelimit": "^1.0.3",
|
||||||
@ -13,5 +16,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/ioredis": "^5.0.0"
|
"@types/ioredis": "^5.0.0"
|
||||||
}
|
},
|
||||||
|
"main": "./dist/index.js",
|
||||||
|
"types": "./types.d.ts"
|
||||||
}
|
}
|
||||||
|
3
packages/core/types.d.ts
vendored
Normal file
3
packages/core/types.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export * from "./db/schema";
|
||||||
|
export * from "./index";
|
||||||
|
export * from "./net/bilibili";
|
@ -1,77 +1,77 @@
|
|||||||
import type { Psql } from "@core/db/psql.d.ts";
|
import type { Psql } from "@core/db/psql.d.ts";
|
||||||
import { AllDataType, BiliUserType } from "@core/db/schema";
|
import { BiliVideoMetadataType, BiliUserType } from "@core/db/schema";
|
||||||
import { AkariModelVersion } from "ml/const";
|
import { AkariModelVersion } from "ml/const";
|
||||||
|
|
||||||
export async function videoExistsInAllData(sql: Psql, aid: number) {
|
export async function videoExistsInAllData(sql: Psql, aid: number) {
|
||||||
const rows = await sql<{ exists: boolean }[]>`
|
const rows = await sql<{ exists: boolean }[]>`
|
||||||
SELECT EXISTS(SELECT 1 FROM bilibili_metadata WHERE aid = ${aid})
|
SELECT EXISTS(SELECT 1 FROM bilibili_metadata WHERE aid = ${aid})
|
||||||
`;
|
`;
|
||||||
return rows[0].exists;
|
return rows[0].exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function userExistsInBiliUsers(sql: Psql, uid: number) {
|
export async function userExistsInBiliUsers(sql: Psql, uid: number) {
|
||||||
const rows = await sql<{ exists: boolean }[]>`
|
const rows = await sql<{ exists: boolean }[]>`
|
||||||
SELECT EXISTS(SELECT 1 FROM bilibili_user WHERE uid = ${uid})
|
SELECT EXISTS(SELECT 1 FROM bilibili_user WHERE uid = ${uid})
|
||||||
`;
|
`;
|
||||||
return rows[0].exists;
|
return rows[0].exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUnlabelledVideos(sql: Psql) {
|
export async function getUnlabelledVideos(sql: Psql) {
|
||||||
const rows = await sql<{ aid: number }[]>`
|
const rows = await sql<{ aid: number }[]>`
|
||||||
SELECT a.aid FROM bilibili_metadata a LEFT JOIN labelling_result l ON a.aid = l.aid WHERE l.aid IS NULL
|
SELECT a.aid FROM bilibili_metadata a LEFT JOIN labelling_result l ON a.aid = l.aid WHERE l.aid IS NULL
|
||||||
`;
|
`;
|
||||||
return rows.map((row) => row.aid);
|
return rows.map((row) => row.aid);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function insertVideoLabel(sql: Psql, aid: number, label: number) {
|
export async function insertVideoLabel(sql: Psql, aid: number, label: number) {
|
||||||
await sql`
|
await sql`
|
||||||
INSERT INTO labelling_result (aid, label, model_version) VALUES (${aid}, ${label}, ${AkariModelVersion}) ON CONFLICT (aid, model_version) DO NOTHING
|
INSERT INTO labelling_result (aid, label, model_version) VALUES (${aid}, ${label}, ${AkariModelVersion}) ON CONFLICT (aid, model_version) DO NOTHING
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getVideoInfoFromAllData(sql: Psql, aid: number) {
|
export async function getVideoInfoFromAllData(sql: Psql, aid: number) {
|
||||||
const rows = await sql<AllDataType[]>`
|
const rows = await sql<AllDataType[]>`
|
||||||
SELECT * FROM bilibili_metadata WHERE aid = ${aid}
|
SELECT * FROM bilibili_metadata WHERE aid = ${aid}
|
||||||
`;
|
`;
|
||||||
const row = rows[0];
|
const row = rows[0];
|
||||||
let authorInfo = "";
|
let authorInfo = "";
|
||||||
if (row.uid && await userExistsInBiliUsers(sql, row.uid)) {
|
if (row.uid && (await userExistsInBiliUsers(sql, row.uid))) {
|
||||||
const userRows = await sql<BiliUserType[]>`
|
const userRows = await sql<BiliUserType[]>`
|
||||||
SELECT * FROM bilibili_user WHERE uid = ${row.uid}
|
SELECT * FROM bilibili_user WHERE uid = ${row.uid}
|
||||||
`;
|
`;
|
||||||
const userRow = userRows[0];
|
const userRow = userRows[0];
|
||||||
if (userRow) {
|
if (userRow) {
|
||||||
authorInfo = userRow.desc;
|
authorInfo = userRow.desc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
title: row.title,
|
title: row.title,
|
||||||
description: row.description,
|
description: row.description,
|
||||||
tags: row.tags,
|
tags: row.tags,
|
||||||
author_info: authorInfo,
|
author_info: authorInfo
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUnArchivedBiliUsers(sql: Psql) {
|
export async function getUnArchivedBiliUsers(sql: Psql) {
|
||||||
const rows = await sql<{ uid: number }[]>`
|
const rows = await sql<{ uid: number }[]>`
|
||||||
SELECT ad.uid
|
SELECT ad.uid
|
||||||
FROM bilibili_metadata ad
|
FROM bilibili_metadata ad
|
||||||
LEFT JOIN bilibili_user bu ON ad.uid = bu.uid
|
LEFT JOIN bilibili_user bu ON ad.uid = bu.uid
|
||||||
WHERE bu.uid IS NULL;
|
WHERE bu.uid IS NULL;
|
||||||
`;
|
`;
|
||||||
return rows.map((row) => row.uid);
|
return rows.map((row) => row.uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setBiliVideoStatus(sql: Psql, aid: number, status: number) {
|
export async function setBiliVideoStatus(sql: Psql, aid: number, status: number) {
|
||||||
await sql`
|
await sql`
|
||||||
UPDATE bilibili_metadata SET status = ${status} WHERE aid = ${aid}
|
UPDATE bilibili_metadata SET status = ${status} WHERE aid = ${aid}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getBiliVideoStatus(sql: Psql, aid: number) {
|
export async function getBiliVideoStatus(sql: Psql, aid: number) {
|
||||||
const rows = await sql<{ status: number }[]>`
|
const rows = await sql<{ status: number }[]>`
|
||||||
SELECT status FROM bilibili_metadata WHERE aid = ${aid}
|
SELECT status FROM bilibili_metadata WHERE aid = ${aid}
|
||||||
`;
|
`;
|
||||||
if (rows.length === 0) return 0;
|
if (rows.length === 0) return 0;
|
||||||
return rows[0].status;
|
return rows[0].status;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ export async function getVideosNearMilestone(sql: Psql) {
|
|||||||
return queryResult.map((row) => {
|
return queryResult.map((row) => {
|
||||||
return {
|
return {
|
||||||
...row,
|
...row,
|
||||||
aid: Number(row.aid),
|
aid: Number(row.aid)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ export async function getLatestVideoSnapshot(sql: Psql, aid: number): Promise<nu
|
|||||||
return {
|
return {
|
||||||
...row,
|
...row,
|
||||||
aid: Number(row.aid),
|
aid: Number(row.aid),
|
||||||
time: new Date(row.time).getTime(),
|
time: new Date(row.time).getTime()
|
||||||
};
|
};
|
||||||
})[0];
|
})[0];
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ export async function refreshSnapshotWindowCounts(sql: Psql, redisClient: Redis)
|
|||||||
const startTime = now.getTime();
|
const startTime = now.getTime();
|
||||||
|
|
||||||
const result = await sql<{ window_start: Date; count: number }[]>`
|
const result = await sql<{ window_start: Date; count: number }[]>`
|
||||||
SELECT
|
SELECT
|
||||||
date_trunc('hour', started_at) +
|
date_trunc('hour', started_at) +
|
||||||
(EXTRACT(minute FROM started_at)::int / 5 * INTERVAL '5 minutes') AS window_start,
|
(EXTRACT(minute FROM started_at)::int / 5 * INTERVAL '5 minutes') AS window_start,
|
||||||
COUNT(*) AS count
|
COUNT(*) AS count
|
||||||
FROM snapshot_schedule
|
FROM snapshot_schedule
|
||||||
@ -56,30 +56,18 @@ async function getWindowCount(redisClient: Redis, offset: number): Promise<numbe
|
|||||||
|
|
||||||
export async function snapshotScheduleExists(sql: Psql, id: number) {
|
export async function snapshotScheduleExists(sql: Psql, id: number) {
|
||||||
const rows = await sql<{ id: number }[]>`
|
const rows = await sql<{ id: number }[]>`
|
||||||
SELECT id
|
SELECT id
|
||||||
FROM snapshot_schedule
|
FROM snapshot_schedule
|
||||||
WHERE id = ${id}
|
WHERE id = ${id}
|
||||||
`;
|
`;
|
||||||
return rows.length > 0;
|
return rows.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function videoHasActiveSchedule(sql: Psql, aid: number) {
|
|
||||||
const rows = await sql<{ status: string }[]>`
|
|
||||||
SELECT status
|
|
||||||
FROM snapshot_schedule
|
|
||||||
WHERE aid = ${aid}
|
|
||||||
AND (status = 'pending'
|
|
||||||
OR status = 'processing'
|
|
||||||
)
|
|
||||||
`
|
|
||||||
return rows.length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function videoHasActiveScheduleWithType(sql: Psql, aid: number, type: string) {
|
export async function videoHasActiveScheduleWithType(sql: Psql, aid: number, type: string) {
|
||||||
const rows = await sql<{ status: string }[]>`
|
const rows = await sql<{ status: string }[]>`
|
||||||
SELECT status FROM snapshot_schedule
|
SELECT status FROM snapshot_schedule
|
||||||
WHERE aid = ${aid}
|
WHERE aid = ${aid}
|
||||||
AND (status = 'pending' OR status = 'processing')
|
AND (status = 'pending' OR status = 'processing')
|
||||||
AND type = ${type}
|
AND type = ${type}
|
||||||
`;
|
`;
|
||||||
return rows.length > 0;
|
return rows.length > 0;
|
||||||
@ -88,10 +76,10 @@ export async function videoHasActiveScheduleWithType(sql: Psql, aid: number, typ
|
|||||||
export async function videoHasProcessingSchedule(sql: Psql, aid: number) {
|
export async function videoHasProcessingSchedule(sql: Psql, aid: number) {
|
||||||
const rows = await sql<{ status: string }[]>`
|
const rows = await sql<{ status: string }[]>`
|
||||||
SELECT status
|
SELECT status
|
||||||
FROM snapshot_schedule
|
FROM snapshot_schedule
|
||||||
WHERE aid = ${aid}
|
WHERE aid = ${aid}
|
||||||
AND status = 'processing'
|
AND status = 'processing'
|
||||||
`
|
`;
|
||||||
return rows.length > 0;
|
return rows.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,9 +88,9 @@ export async function bulkGetVideosWithoutProcessingSchedules(sql: Psql, aids: n
|
|||||||
SELECT aid
|
SELECT aid
|
||||||
FROM snapshot_schedule
|
FROM snapshot_schedule
|
||||||
WHERE aid = ANY(${aids})
|
WHERE aid = ANY(${aids})
|
||||||
AND status != 'processing'
|
AND status != 'processing'
|
||||||
GROUP BY aid
|
GROUP BY aid
|
||||||
`
|
`;
|
||||||
return rows.map((row) => Number(row.aid));
|
return rows.map((row) => Number(row.aid));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,8 +134,8 @@ export async function findSnapshotBefore(sql: Psql, aid: number, targetTime: Dat
|
|||||||
|
|
||||||
export async function hasAtLeast2Snapshots(sql: Psql, aid: number) {
|
export async function hasAtLeast2Snapshots(sql: Psql, aid: number) {
|
||||||
const res = await sql<{ count: number }[]>`
|
const res = await sql<{ count: number }[]>`
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM video_snapshot
|
FROM video_snapshot
|
||||||
WHERE aid = ${aid}
|
WHERE aid = ${aid}
|
||||||
`;
|
`;
|
||||||
return res[0].count >= 2;
|
return res[0].count >= 2;
|
||||||
@ -155,10 +143,10 @@ export async function hasAtLeast2Snapshots(sql: Psql, aid: number) {
|
|||||||
|
|
||||||
export async function getLatestSnapshot(sql: Psql, aid: number): Promise<Snapshot | null> {
|
export async function getLatestSnapshot(sql: Psql, aid: number): Promise<Snapshot | null> {
|
||||||
const res = await sql<{ created_at: string; views: number }[]>`
|
const res = await sql<{ created_at: string; views: number }[]>`
|
||||||
SELECT created_at, views
|
SELECT created_at, views
|
||||||
FROM video_snapshot
|
FROM video_snapshot
|
||||||
WHERE aid = ${aid}
|
WHERE aid = ${aid}
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
`;
|
`;
|
||||||
if (res.length === 0) return null;
|
if (res.length === 0) return null;
|
||||||
@ -194,7 +182,8 @@ export async function scheduleSnapshot(
|
|||||||
aid: number,
|
aid: number,
|
||||||
type: string,
|
type: string,
|
||||||
targetTime: number,
|
targetTime: number,
|
||||||
force: boolean = false
|
force: boolean = false,
|
||||||
|
adjustTime: boolean = true
|
||||||
) {
|
) {
|
||||||
let adjustedTime = new Date(targetTime);
|
let adjustedTime = new Date(targetTime);
|
||||||
const hashActiveSchedule = await videoHasActiveScheduleWithType(sql, aid, type);
|
const hashActiveSchedule = await videoHasActiveScheduleWithType(sql, aid, type);
|
||||||
@ -216,16 +205,16 @@ export async function scheduleSnapshot(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hashActiveSchedule && !force) return;
|
if (hashActiveSchedule && !force) return;
|
||||||
if (type !== "milestone" && type !== "new") {
|
if (type !== "milestone" && type !== "new" && adjustTime) {
|
||||||
adjustedTime = await adjustSnapshotTime(new Date(targetTime), 2000, redis);
|
adjustedTime = await adjustSnapshotTime(new Date(targetTime), 2000, redis);
|
||||||
}
|
}
|
||||||
logger.log(`Scheduled snapshot for ${aid} at ${adjustedTime.toISOString()}`, "mq", "fn:scheduleSnapshot");
|
logger.log(`Scheduled snapshot for ${aid} at ${adjustedTime.toISOString()}`, "mq", "fn:scheduleSnapshot");
|
||||||
return sql`
|
return sql`
|
||||||
INSERT INTO snapshot_schedule
|
INSERT INTO snapshot_schedule
|
||||||
(aid, type, started_at)
|
(aid, type, started_at)
|
||||||
VALUES (
|
VALUES (
|
||||||
${aid},
|
${aid},
|
||||||
${type},
|
${type},
|
||||||
${adjustedTime.toISOString()}
|
${adjustedTime.toISOString()}
|
||||||
)
|
)
|
||||||
`;
|
`;
|
||||||
@ -236,10 +225,11 @@ export async function bulkScheduleSnapshot(
|
|||||||
aids: number[],
|
aids: number[],
|
||||||
type: string,
|
type: string,
|
||||||
targetTime: number,
|
targetTime: number,
|
||||||
force: boolean = false
|
force: boolean = false,
|
||||||
|
adjustTime: boolean = true
|
||||||
) {
|
) {
|
||||||
for (const aid of aids) {
|
for (const aid of aids) {
|
||||||
await scheduleSnapshot(sql, aid, type, targetTime, force);
|
await scheduleSnapshot(sql, aid, type, targetTime, force, adjustTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,23 +282,23 @@ export async function adjustSnapshotTime(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getSnapshotsInNextSecond(sql: Psql) {
|
export async function getSnapshotsInNextSecond(sql: Psql) {
|
||||||
const rows = await sql<SnapshotScheduleType[]>`
|
return sql<SnapshotScheduleType[]>`
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM snapshot_schedule
|
FROM snapshot_schedule
|
||||||
WHERE started_at <= NOW() + INTERVAL '1 seconds' AND status = 'pending' AND type != 'normal'
|
WHERE started_at <= NOW() + INTERVAL '1 seconds'
|
||||||
ORDER BY
|
AND status = 'pending'
|
||||||
CASE
|
AND type != 'normal'
|
||||||
WHEN type = 'milestone' THEN 0
|
ORDER BY CASE
|
||||||
ELSE 1
|
WHEN type = 'milestone' THEN 0
|
||||||
END,
|
ELSE 1
|
||||||
started_at
|
END,
|
||||||
LIMIT 10;
|
started_at
|
||||||
`
|
LIMIT 10;
|
||||||
return rows;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getBulkSnapshotsInNextSecond(sql: Psql) {
|
export async function getBulkSnapshotsInNextSecond(sql: Psql) {
|
||||||
const rows = await sql<SnapshotScheduleType[]>`
|
return sql<SnapshotScheduleType[]>`
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM snapshot_schedule
|
FROM snapshot_schedule
|
||||||
WHERE (started_at <= NOW() + INTERVAL '15 seconds')
|
WHERE (started_at <= NOW() + INTERVAL '15 seconds')
|
||||||
@ -320,38 +310,34 @@ export async function getBulkSnapshotsInNextSecond(sql: Psql) {
|
|||||||
END,
|
END,
|
||||||
started_at
|
started_at
|
||||||
LIMIT 1000;
|
LIMIT 1000;
|
||||||
`
|
`;
|
||||||
return rows;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setSnapshotStatus(sql: Psql, id: number, status: string) {
|
export async function setSnapshotStatus(sql: Psql, id: number, status: string) {
|
||||||
return await sql`
|
return sql`
|
||||||
UPDATE snapshot_schedule SET status = ${status} WHERE id = ${id}
|
UPDATE snapshot_schedule
|
||||||
|
SET status = ${status}
|
||||||
|
WHERE id = ${id}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function bulkSetSnapshotStatus(sql: Psql, ids: number[], status: string) {
|
export async function bulkSetSnapshotStatus(sql: Psql, ids: number[], status: string) {
|
||||||
return await sql`
|
return sql`
|
||||||
UPDATE snapshot_schedule SET status = ${status} WHERE id = ANY(${ids})
|
UPDATE snapshot_schedule
|
||||||
|
SET status = ${status}
|
||||||
|
WHERE id = ANY (${ids})
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getVideosWithoutActiveSnapshotSchedule(sql: Psql) {
|
export async function getVideosWithoutActiveSnapshotScheduleByType(sql: Psql, type: string) {
|
||||||
const rows = await sql<{ aid: string }[]>`
|
const rows = await sql<{ aid: string }[]>`
|
||||||
SELECT s.aid
|
SELECT s.aid
|
||||||
FROM songs s
|
FROM songs s
|
||||||
LEFT JOIN snapshot_schedule ss ON s.aid = ss.aid AND (ss.status = 'pending' OR ss.status = 'processing')
|
LEFT JOIN snapshot_schedule ss ON
|
||||||
|
s.aid = ss.aid AND
|
||||||
|
(ss.status = 'pending' OR ss.status = 'processing') AND
|
||||||
|
ss.type = ${type}
|
||||||
WHERE ss.aid IS NULL
|
WHERE ss.aid IS NULL
|
||||||
`;
|
`;
|
||||||
return rows.map((r) => Number(r.aid));
|
return rows.map((r) => Number(r.aid));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAllVideosWithoutActiveSnapshotSchedule(psql: Psql) {
|
|
||||||
const rows = await psql<{ aid: number }[]>`
|
|
||||||
SELECT s.aid
|
|
||||||
FROM bilibili_metadata s
|
|
||||||
LEFT JOIN snapshot_schedule ss ON s.aid = ss.aid AND (ss.status = 'pending' OR ss.status = 'processing')
|
|
||||||
WHERE ss.aid IS NULL
|
|
||||||
`
|
|
||||||
return rows.map((r) => Number(r.aid));
|
|
||||||
}
|
|
||||||
|
@ -2,7 +2,7 @@ import type { Psql } from "@core/db/psql.d.ts";
|
|||||||
import { parseTimestampFromPsql } from "utils/formatTimestampToPostgre.ts";
|
import { parseTimestampFromPsql } from "utils/formatTimestampToPostgre.ts";
|
||||||
|
|
||||||
export async function getNotCollectedSongs(sql: Psql) {
|
export async function getNotCollectedSongs(sql: Psql) {
|
||||||
const rows = await sql<{ aid: number }[]>`
|
const rows = await sql<{ aid: number }[]>`
|
||||||
SELECT lr.aid
|
SELECT lr.aid
|
||||||
FROM labelling_result lr
|
FROM labelling_result lr
|
||||||
WHERE lr.label != 0
|
WHERE lr.label != 0
|
||||||
@ -12,28 +12,28 @@ export async function getNotCollectedSongs(sql: Psql) {
|
|||||||
WHERE s.aid = lr.aid
|
WHERE s.aid = lr.aid
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
return rows.map((row) => row.aid);
|
return rows.map((row) => row.aid);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function aidExistsInSongs(sql: Psql, aid: number) {
|
export async function aidExistsInSongs(sql: Psql, aid: number) {
|
||||||
const rows = await sql<{ exists: boolean }[]>`
|
const rows = await sql<{ exists: boolean }[]>`
|
||||||
SELECT EXISTS (
|
SELECT EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM songs
|
FROM songs
|
||||||
WHERE aid = ${aid}
|
WHERE aid = ${aid}
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
return rows[0].exists;
|
return rows[0].exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getSongsPublihsedAt(sql: Psql, aid: number) {
|
export async function getSongsPublihsedAt(sql: Psql, aid: number) {
|
||||||
const rows = await sql<{ published_at: string }[]>`
|
const rows = await sql<{ published_at: string }[]>`
|
||||||
SELECT published_at
|
SELECT published_at
|
||||||
FROM songs
|
FROM songs
|
||||||
WHERE aid = ${aid};
|
WHERE aid = ${aid};
|
||||||
`;
|
`;
|
||||||
if (rows.length === 0) {
|
if (rows.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return parseTimestampFromPsql(rows[0].published_at);
|
return parseTimestampFromPsql(rows[0].published_at);
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@ class AkariProto extends AIManager {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.models = {
|
this.models = {
|
||||||
"classifier": onnxClassifierPath,
|
classifier: onnxClassifierPath,
|
||||||
"embedding": onnxEmbeddingPath,
|
embedding: onnxEmbeddingPath
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ class AkariProto extends AIManager {
|
|||||||
|
|
||||||
const { input_ids } = await tokenizer(texts, {
|
const { input_ids } = await tokenizer(texts, {
|
||||||
add_special_tokens: false,
|
add_special_tokens: false,
|
||||||
return_tensor: false,
|
return_tensor: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const cumsum = (arr: number[]): number[] =>
|
const cumsum = (arr: number[]): number[] =>
|
||||||
@ -66,9 +66,9 @@ class AkariProto extends AIManager {
|
|||||||
|
|
||||||
const inputs = {
|
const inputs = {
|
||||||
input_ids: new ort.Tensor("int64", new BigInt64Array(flattened_input_ids.map(BigInt)), [
|
input_ids: new ort.Tensor("int64", new BigInt64Array(flattened_input_ids.map(BigInt)), [
|
||||||
flattened_input_ids.length,
|
flattened_input_ids.length
|
||||||
]),
|
]),
|
||||||
offsets: new ort.Tensor("int64", new BigInt64Array(offsets.map(BigInt)), [offsets.length]),
|
offsets: new ort.Tensor("int64", new BigInt64Array(offsets.map(BigInt)), [offsets.length])
|
||||||
};
|
};
|
||||||
|
|
||||||
const { embeddings } = await session.run(inputs);
|
const { embeddings } = await session.run(inputs);
|
||||||
@ -77,21 +77,14 @@ class AkariProto extends AIManager {
|
|||||||
|
|
||||||
private async runClassification(embeddings: number[]): Promise<number[]> {
|
private async runClassification(embeddings: number[]): Promise<number[]> {
|
||||||
const session = this.getModelSession("classifier");
|
const session = this.getModelSession("classifier");
|
||||||
const inputTensor = new ort.Tensor(
|
const inputTensor = new ort.Tensor(Float32Array.from(embeddings), [1, 3, 1024]);
|
||||||
Float32Array.from(embeddings),
|
|
||||||
[1, 3, 1024],
|
|
||||||
);
|
|
||||||
|
|
||||||
const { logits } = await session.run({ channel_features: inputTensor });
|
const { logits } = await session.run({ channel_features: inputTensor });
|
||||||
return this.softmax(logits.data as Float32Array);
|
return this.softmax(logits.data as Float32Array);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async classifyVideo(title: string, description: string, tags: string, aid?: number): Promise<number> {
|
public async classifyVideo(title: string, description: string, tags: string, aid?: number): Promise<number> {
|
||||||
const embeddings = await this.getJinaEmbeddings1024([
|
const embeddings = await this.getJinaEmbeddings1024([title, description, tags]);
|
||||||
title,
|
|
||||||
description,
|
|
||||||
tags,
|
|
||||||
]);
|
|
||||||
const probabilities = await this.runClassification(embeddings);
|
const probabilities = await this.runClassification(embeddings);
|
||||||
if (aid) {
|
if (aid) {
|
||||||
logger.log(`Prediction result for aid: ${aid}: [${probabilities.map((p) => p.toFixed(5))}]`, "ml");
|
logger.log(`Prediction result for aid: ${aid}: [${probabilities.map((p) => p.toFixed(5))}]`, "ml");
|
||||||
|
@ -1,179 +0,0 @@
|
|||||||
import { AutoTokenizer, PreTrainedTokenizer } from "@huggingface/transformers";
|
|
||||||
import * as ort from "onnxruntime";
|
|
||||||
|
|
||||||
function softmax(logits: Float32Array): number[] {
|
|
||||||
const maxLogit = Math.max(...logits);
|
|
||||||
const exponents = logits.map((logit) => Math.exp(logit - maxLogit));
|
|
||||||
const sumOfExponents = exponents.reduce((sum, exp) => sum + exp, 0);
|
|
||||||
return Array.from(exponents.map((exp) => exp / sumOfExponents));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置参数
|
|
||||||
const sentenceTransformerModelName = "alikia2x/jina-embedding-v3-m2v-1024";
|
|
||||||
const onnxClassifierPath = "./model/video_classifier_v3_17.onnx";
|
|
||||||
const onnxEmbeddingPath = "./model/embedding_original.onnx";
|
|
||||||
const testDataPath = "./data/filter/test1.jsonl";
|
|
||||||
|
|
||||||
// 初始化会话
|
|
||||||
const [sessionClassifier, sessionEmbedding] = await Promise.all([
|
|
||||||
ort.InferenceSession.create(onnxClassifierPath),
|
|
||||||
ort.InferenceSession.create(onnxEmbeddingPath),
|
|
||||||
]);
|
|
||||||
|
|
||||||
let tokenizer: PreTrainedTokenizer;
|
|
||||||
|
|
||||||
// 初始化分词器
|
|
||||||
async function loadTokenizer() {
|
|
||||||
const tokenizerConfig = { local_files_only: true };
|
|
||||||
tokenizer = await AutoTokenizer.from_pretrained(sentenceTransformerModelName, tokenizerConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新的嵌入生成函数(使用ONNX)
|
|
||||||
async function getONNXEmbeddings(texts: string[], session: ort.InferenceSession): Promise<number[]> {
|
|
||||||
const { input_ids } = await tokenizer(texts, {
|
|
||||||
add_special_tokens: false,
|
|
||||||
return_tensor: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 构造输入参数
|
|
||||||
const cumsum = (arr: number[]): number[] =>
|
|
||||||
arr.reduce((acc: number[], num: number, i: number) => [...acc, num + (acc[i - 1] || 0)], []);
|
|
||||||
|
|
||||||
const offsets: number[] = [0, ...cumsum(input_ids.slice(0, -1).map((x: string) => x.length))];
|
|
||||||
const flattened_input_ids = input_ids.flat();
|
|
||||||
|
|
||||||
// 准备ONNX输入
|
|
||||||
const inputs = {
|
|
||||||
input_ids: new ort.Tensor("int64", new BigInt64Array(flattened_input_ids.map(BigInt)), [
|
|
||||||
flattened_input_ids.length,
|
|
||||||
]),
|
|
||||||
offsets: new ort.Tensor("int64", new BigInt64Array(offsets.map(BigInt)), [offsets.length]),
|
|
||||||
};
|
|
||||||
|
|
||||||
// 执行推理
|
|
||||||
const { embeddings } = await session.run(inputs);
|
|
||||||
return Array.from(embeddings.data as Float32Array);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分类推理函数
|
|
||||||
async function runClassification(embeddings: number[]): Promise<number[]> {
|
|
||||||
const inputTensor = new ort.Tensor(
|
|
||||||
Float32Array.from(embeddings),
|
|
||||||
[1, 3, 1024],
|
|
||||||
);
|
|
||||||
|
|
||||||
const { logits } = await sessionClassifier.run({ channel_features: inputTensor });
|
|
||||||
return softmax(logits.data as Float32Array);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 指标计算函数
|
|
||||||
function calculateMetrics(labels: number[], predictions: number[], elapsedTime: number): {
|
|
||||||
accuracy: number;
|
|
||||||
precision: number;
|
|
||||||
recall: number;
|
|
||||||
f1: number;
|
|
||||||
"Class 0 Prec": number;
|
|
||||||
speed: string;
|
|
||||||
} {
|
|
||||||
// 输出label和prediction不一样的index列表
|
|
||||||
const arr = [];
|
|
||||||
for (let i = 0; i < labels.length; i++) {
|
|
||||||
if (labels[i] !== predictions[i] && predictions[i] == 0) {
|
|
||||||
arr.push([i + 1, labels[i], predictions[i]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(arr);
|
|
||||||
// 初始化混淆矩阵
|
|
||||||
const classCount = Math.max(...labels, ...predictions) + 1;
|
|
||||||
const matrix = Array.from({ length: classCount }, () => Array.from({ length: classCount }, () => 0));
|
|
||||||
|
|
||||||
// 填充矩阵
|
|
||||||
labels.forEach((trueLabel, i) => {
|
|
||||||
matrix[trueLabel][predictions[i]]++;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 计算各指标
|
|
||||||
let totalTP = 0, totalFP = 0, totalFN = 0;
|
|
||||||
|
|
||||||
for (let c = 0; c < classCount; c++) {
|
|
||||||
const TP = matrix[c][c];
|
|
||||||
const FP = matrix.flatMap((row, i) => i === c ? [] : [row[c]]).reduce((a, b) => a + b, 0);
|
|
||||||
const FN = matrix[c].filter((_, i) => i !== c).reduce((a, b) => a + b, 0);
|
|
||||||
|
|
||||||
totalTP += TP;
|
|
||||||
totalFP += FP;
|
|
||||||
totalFN += FN;
|
|
||||||
}
|
|
||||||
|
|
||||||
const precision = totalTP / (totalTP + totalFP);
|
|
||||||
const recall = totalTP / (totalTP + totalFN);
|
|
||||||
const f1 = 2 * (precision * recall) / (precision + recall) || 0;
|
|
||||||
|
|
||||||
// 计算Class 0 Precision
|
|
||||||
const class0TP = matrix[0][0];
|
|
||||||
const class0FP = matrix.flatMap((row, i) => i === 0 ? [] : [row[0]]).reduce((a, b) => a + b, 0);
|
|
||||||
const class0Precision = class0TP / (class0TP + class0FP) || 0;
|
|
||||||
|
|
||||||
return {
|
|
||||||
accuracy: labels.filter((l, i) => l === predictions[i]).length / labels.length,
|
|
||||||
precision,
|
|
||||||
recall,
|
|
||||||
f1,
|
|
||||||
speed: `${(labels.length / (elapsedTime / 1000)).toFixed(1)} samples/sec`,
|
|
||||||
"Class 0 Prec": class0Precision,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 改造后的评估函数
|
|
||||||
async function evaluateModel(session: ort.InferenceSession): Promise<{
|
|
||||||
accuracy: number;
|
|
||||||
precision: number;
|
|
||||||
recall: number;
|
|
||||||
f1: number;
|
|
||||||
"Class 0 Prec": number;
|
|
||||||
}> {
|
|
||||||
const data = await Deno.readTextFile(testDataPath);
|
|
||||||
const samples = data.split("\n")
|
|
||||||
.map((line) => {
|
|
||||||
try {
|
|
||||||
return JSON.parse(line);
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
const allPredictions: number[] = [];
|
|
||||||
const allLabels: number[] = [];
|
|
||||||
|
|
||||||
const t = new Date().getTime();
|
|
||||||
for (const sample of samples) {
|
|
||||||
try {
|
|
||||||
const embeddings = await getONNXEmbeddings([
|
|
||||||
sample.title,
|
|
||||||
sample.description,
|
|
||||||
sample.tags.join(","),
|
|
||||||
], session);
|
|
||||||
|
|
||||||
const probabilities = await runClassification(embeddings);
|
|
||||||
allPredictions.push(probabilities.indexOf(Math.max(...probabilities)));
|
|
||||||
allLabels.push(sample.label);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Processing error:", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const elapsed = new Date().getTime() - t;
|
|
||||||
|
|
||||||
return calculateMetrics(allLabels, allPredictions, elapsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 主函数
|
|
||||||
async function main() {
|
|
||||||
await loadTokenizer();
|
|
||||||
|
|
||||||
const metrics = await evaluateModel(sessionEmbedding);
|
|
||||||
console.log("Model Metrics:");
|
|
||||||
console.table(metrics);
|
|
||||||
}
|
|
||||||
|
|
||||||
await main();
|
|
@ -1 +1 @@
|
|||||||
export const AkariModelVersion = "3.17";
|
export const AkariModelVersion = "3.17";
|
||||||
|
@ -6,8 +6,7 @@ export class AIManager {
|
|||||||
public sessions: { [key: string]: ort.InferenceSession } = {};
|
public sessions: { [key: string]: ort.InferenceSession } = {};
|
||||||
public models: { [key: string]: string } = {};
|
public models: { [key: string]: string } = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {}
|
||||||
}
|
|
||||||
|
|
||||||
public async init() {
|
public async init() {
|
||||||
const modelKeys = Object.keys(this.models);
|
const modelKeys = Object.keys(this.models);
|
||||||
|
@ -1,171 +0,0 @@
|
|||||||
import { AutoTokenizer, PreTrainedTokenizer } from "@huggingface/transformers";
|
|
||||||
import * as ort from "onnxruntime";
|
|
||||||
|
|
||||||
function softmax(logits: Float32Array): number[] {
|
|
||||||
const maxLogit = Math.max(...logits);
|
|
||||||
const exponents = logits.map((logit) => Math.exp(logit - maxLogit));
|
|
||||||
const sumOfExponents = exponents.reduce((sum, exp) => sum + exp, 0);
|
|
||||||
return Array.from(exponents.map((exp) => exp / sumOfExponents));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置参数
|
|
||||||
const sentenceTransformerModelName = "alikia2x/jina-embedding-v3-m2v-1024";
|
|
||||||
const onnxClassifierPath = "./model/video_classifier_v3_11.onnx";
|
|
||||||
const onnxEmbeddingOriginalPath = "./model/embedding_original.onnx";
|
|
||||||
const onnxEmbeddingQuantizedPath = "./model/embedding_original.onnx";
|
|
||||||
|
|
||||||
// 初始化会话
|
|
||||||
const [sessionClassifier, sessionEmbeddingOriginal, sessionEmbeddingQuantized] = await Promise.all([
|
|
||||||
ort.InferenceSession.create(onnxClassifierPath),
|
|
||||||
ort.InferenceSession.create(onnxEmbeddingOriginalPath),
|
|
||||||
ort.InferenceSession.create(onnxEmbeddingQuantizedPath),
|
|
||||||
]);
|
|
||||||
|
|
||||||
let tokenizer: PreTrainedTokenizer;
|
|
||||||
|
|
||||||
// 初始化分词器
|
|
||||||
async function loadTokenizer() {
|
|
||||||
const tokenizerConfig = { local_files_only: true };
|
|
||||||
tokenizer = await AutoTokenizer.from_pretrained(sentenceTransformerModelName, tokenizerConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新的嵌入生成函数(使用ONNX)
|
|
||||||
async function getONNXEmbeddings(texts: string[], session: ort.InferenceSession): Promise<number[]> {
|
|
||||||
const { input_ids } = await tokenizer(texts, {
|
|
||||||
add_special_tokens: false,
|
|
||||||
return_tensor: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 构造输入参数
|
|
||||||
const cumsum = (arr: number[]): number[] =>
|
|
||||||
arr.reduce((acc: number[], num: number, i: number) => [...acc, num + (acc[i - 1] || 0)], []);
|
|
||||||
|
|
||||||
const offsets: number[] = [0, ...cumsum(input_ids.slice(0, -1).map((x: string) => x.length))];
|
|
||||||
const flattened_input_ids = input_ids.flat();
|
|
||||||
|
|
||||||
// 准备ONNX输入
|
|
||||||
const inputs = {
|
|
||||||
input_ids: new ort.Tensor("int64", new BigInt64Array(flattened_input_ids.map(BigInt)), [
|
|
||||||
flattened_input_ids.length,
|
|
||||||
]),
|
|
||||||
offsets: new ort.Tensor("int64", new BigInt64Array(offsets.map(BigInt)), [offsets.length]),
|
|
||||||
};
|
|
||||||
|
|
||||||
// 执行推理
|
|
||||||
const { embeddings } = await session.run(inputs);
|
|
||||||
return Array.from(embeddings.data as Float32Array);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分类推理函数
|
|
||||||
async function runClassification(embeddings: number[]): Promise<number[]> {
|
|
||||||
const inputTensor = new ort.Tensor(
|
|
||||||
Float32Array.from(embeddings),
|
|
||||||
[1, 4, 1024],
|
|
||||||
);
|
|
||||||
|
|
||||||
const { logits } = await sessionClassifier.run({ channel_features: inputTensor });
|
|
||||||
return softmax(logits.data as Float32Array);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 指标计算函数
|
|
||||||
function calculateMetrics(labels: number[], predictions: number[], elapsedTime: number): {
|
|
||||||
accuracy: number;
|
|
||||||
precision: number;
|
|
||||||
recall: number;
|
|
||||||
f1: number;
|
|
||||||
speed: string;
|
|
||||||
} {
|
|
||||||
// 初始化混淆矩阵
|
|
||||||
const classCount = Math.max(...labels, ...predictions) + 1;
|
|
||||||
const matrix = Array.from({ length: classCount }, () => Array.from({ length: classCount }, () => 0));
|
|
||||||
|
|
||||||
// 填充矩阵
|
|
||||||
labels.forEach((trueLabel, i) => {
|
|
||||||
matrix[trueLabel][predictions[i]]++;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 计算各指标
|
|
||||||
let totalTP = 0, totalFP = 0, totalFN = 0;
|
|
||||||
|
|
||||||
for (let c = 0; c < classCount; c++) {
|
|
||||||
const TP = matrix[c][c];
|
|
||||||
const FP = matrix.flatMap((row, i) => i === c ? [] : [row[c]]).reduce((a, b) => a + b, 0);
|
|
||||||
const FN = matrix[c].filter((_, i) => i !== c).reduce((a, b) => a + b, 0);
|
|
||||||
|
|
||||||
totalTP += TP;
|
|
||||||
totalFP += FP;
|
|
||||||
totalFN += FN;
|
|
||||||
}
|
|
||||||
|
|
||||||
const precision = totalTP / (totalTP + totalFP);
|
|
||||||
const recall = totalTP / (totalTP + totalFN);
|
|
||||||
const f1 = 2 * (precision * recall) / (precision + recall) || 0;
|
|
||||||
|
|
||||||
return {
|
|
||||||
accuracy: labels.filter((l, i) => l === predictions[i]).length / labels.length,
|
|
||||||
precision,
|
|
||||||
recall,
|
|
||||||
f1,
|
|
||||||
speed: `${(labels.length / (elapsedTime / 1000)).toFixed(1)} samples/sec`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 改造后的评估函数
|
|
||||||
async function evaluateModel(session: ort.InferenceSession): Promise<{
|
|
||||||
accuracy: number;
|
|
||||||
precision: number;
|
|
||||||
recall: number;
|
|
||||||
f1: number;
|
|
||||||
}> {
|
|
||||||
const data = await Deno.readTextFile("./data/filter/test1.jsonl");
|
|
||||||
const samples = data.split("\n")
|
|
||||||
.map((line) => {
|
|
||||||
try {
|
|
||||||
return JSON.parse(line);
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
const allPredictions: number[] = [];
|
|
||||||
const allLabels: number[] = [];
|
|
||||||
|
|
||||||
const t = new Date().getTime();
|
|
||||||
for (const sample of samples) {
|
|
||||||
try {
|
|
||||||
const embeddings = await getONNXEmbeddings([
|
|
||||||
sample.title,
|
|
||||||
sample.description,
|
|
||||||
sample.tags.join(","),
|
|
||||||
sample.author_info,
|
|
||||||
], session);
|
|
||||||
|
|
||||||
const probabilities = await runClassification(embeddings);
|
|
||||||
allPredictions.push(probabilities.indexOf(Math.max(...probabilities)));
|
|
||||||
allLabels.push(sample.label);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Processing error:", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const elapsed = new Date().getTime() - t;
|
|
||||||
|
|
||||||
return calculateMetrics(allLabels, allPredictions, elapsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 主函数
|
|
||||||
async function main() {
|
|
||||||
await loadTokenizer();
|
|
||||||
|
|
||||||
// 评估原始模型
|
|
||||||
const originalMetrics = await evaluateModel(sessionEmbeddingOriginal);
|
|
||||||
console.log("Original Model Metrics:");
|
|
||||||
console.table(originalMetrics);
|
|
||||||
|
|
||||||
// 评估量化模型
|
|
||||||
const quantizedMetrics = await evaluateModel(sessionEmbeddingQuantized);
|
|
||||||
console.log("Quantized Model Metrics:");
|
|
||||||
console.table(quantizedMetrics);
|
|
||||||
}
|
|
||||||
|
|
||||||
await main();
|
|
@ -1,11 +1,28 @@
|
|||||||
import { Job } from "bullmq";
|
import { Job } from "bullmq";
|
||||||
import { getAllVideosWithoutActiveSnapshotSchedule, scheduleSnapshot } from "db/snapshotSchedule.ts";
|
import { getVideosWithoutActiveSnapshotScheduleByType, scheduleSnapshot } from "db/snapshotSchedule.ts";
|
||||||
import logger from "@core/log/logger.ts";
|
import logger from "@core/log/logger.ts";
|
||||||
import { lockManager } from "@core/mq/lockManager.ts";
|
import { lockManager } from "@core/mq/lockManager.ts";
|
||||||
import { getLatestVideoSnapshot } from "db/snapshot.ts";
|
import { getLatestVideoSnapshot } from "db/snapshot.ts";
|
||||||
import { HOUR, MINUTE } from "@core/const/time.ts";
|
import { MINUTE } from "@core/const/time.ts";
|
||||||
import { sql } from "@core/db/dbNew";
|
import { sql } from "@core/db/dbNew";
|
||||||
|
|
||||||
|
function getNextSaturdayMidnightTimestamp(): number {
|
||||||
|
const now = new Date();
|
||||||
|
const currentDay = now.getDay();
|
||||||
|
|
||||||
|
let daysUntilNextSaturday = (6 - currentDay + 7) % 7;
|
||||||
|
|
||||||
|
if (daysUntilNextSaturday === 0) {
|
||||||
|
daysUntilNextSaturday = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextSaturday = new Date(now);
|
||||||
|
nextSaturday.setDate(nextSaturday.getDate() + daysUntilNextSaturday);
|
||||||
|
nextSaturday.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
return nextSaturday.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
export const archiveSnapshotsWorker = async (_job: Job) => {
|
export const archiveSnapshotsWorker = async (_job: Job) => {
|
||||||
try {
|
try {
|
||||||
const startedAt = Date.now();
|
const startedAt = Date.now();
|
||||||
@ -14,21 +31,22 @@ export const archiveSnapshotsWorker = async (_job: Job) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await lockManager.acquireLock("dispatchArchiveSnapshots", 30 * 60);
|
await lockManager.acquireLock("dispatchArchiveSnapshots", 30 * 60);
|
||||||
const aids = await getAllVideosWithoutActiveSnapshotSchedule(sql);
|
const aids = await getVideosWithoutActiveSnapshotScheduleByType(sql, "archive");
|
||||||
for (const rawAid of aids) {
|
for (const rawAid of aids) {
|
||||||
const aid = Number(rawAid);
|
const aid = Number(rawAid);
|
||||||
const latestSnapshot = await getLatestVideoSnapshot(sql, aid);
|
const latestSnapshot = await getLatestVideoSnapshot(sql, aid);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const lastSnapshotedAt = latestSnapshot?.time ?? now;
|
const lastSnapshotedAt = latestSnapshot?.time ?? now;
|
||||||
const interval = 168;
|
const nextSatMidnight = getNextSaturdayMidnightTimestamp();
|
||||||
|
const interval = nextSatMidnight - now;
|
||||||
logger.log(
|
logger.log(
|
||||||
`Scheduled archive snapshot for aid ${aid} in ${interval} hours.`,
|
`Scheduled archive snapshot for aid ${aid} in ${interval} hours.`,
|
||||||
"mq",
|
"mq",
|
||||||
"fn:archiveSnapshotsWorker"
|
"fn:archiveSnapshotsWorker"
|
||||||
);
|
);
|
||||||
const targetTime = lastSnapshotedAt + interval * HOUR;
|
const targetTime = lastSnapshotedAt + interval;
|
||||||
await scheduleSnapshot(sql, aid, "archive", targetTime);
|
await scheduleSnapshot(sql, aid, "archive", targetTime);
|
||||||
if (now - startedAt > 250 * MINUTE) {
|
if (now - startedAt > 30 * MINUTE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ export const classifyVideoWorker = async (job: Job) => {
|
|||||||
|
|
||||||
await job.updateData({
|
await job.updateData({
|
||||||
...job.data,
|
...job.data,
|
||||||
label: label,
|
label: label
|
||||||
});
|
});
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -46,19 +46,19 @@ export const classifyVideosWorker = async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await lockManager.acquireLock("classifyVideos");
|
await lockManager.acquireLock("classifyVideos", 5 * 60);
|
||||||
|
|
||||||
const videos = await getUnlabelledVideos(sql);
|
const videos = await getUnlabelledVideos(sql);
|
||||||
logger.log(`Found ${videos.length} unlabelled videos`);
|
logger.log(`Found ${videos.length} unlabelled videos`);
|
||||||
|
|
||||||
let i = 0;
|
const startTime = new Date().getTime();
|
||||||
for (const aid of videos) {
|
for (const aid of videos) {
|
||||||
if (i > 200) {
|
const now = new Date().getTime();
|
||||||
|
if (now - startTime > 4.2 * MINUTE) {
|
||||||
await lockManager.releaseLock("classifyVideos");
|
await lockManager.releaseLock("classifyVideos");
|
||||||
return 10000 + i;
|
return 1;
|
||||||
}
|
}
|
||||||
await ClassifyVideoQueue.add("classifyVideo", { aid: Number(aid) });
|
await ClassifyVideoQueue.add("classifyVideo", { aid: Number(aid) });
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
await lockManager.releaseLock("classifyVideos");
|
await lockManager.releaseLock("classifyVideos");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Job } from "bullmq";
|
import { Job } from "bullmq";
|
||||||
import { collectSongs } from "mq/task/collectSongs.ts";
|
import { collectSongs } from "mq/task/collectSongs.ts";
|
||||||
|
|
||||||
export const collectSongsWorker = async (_job: Job): Promise<void> =>{
|
export const collectSongsWorker = async (_job: Job): Promise<void> => {
|
||||||
await collectSongs();
|
await collectSongs();
|
||||||
return;
|
return;
|
||||||
}
|
};
|
||||||
|
@ -16,8 +16,8 @@ export const dispatchMilestoneSnapshotsWorker = async (_job: Job) => {
|
|||||||
if (eta > 144) continue;
|
if (eta > 144) continue;
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const scheduledNextSnapshotDelay = eta * HOUR;
|
const scheduledNextSnapshotDelay = eta * HOUR;
|
||||||
const maxInterval = 1 * HOUR;
|
const maxInterval = 1.2 * HOUR;
|
||||||
const minInterval = 1 * SECOND;
|
const minInterval = 2 * SECOND;
|
||||||
const delay = truncate(scheduledNextSnapshotDelay, minInterval, maxInterval);
|
const delay = truncate(scheduledNextSnapshotDelay, minInterval, maxInterval);
|
||||||
const targetTime = now + delay;
|
const targetTime = now + delay;
|
||||||
await scheduleSnapshot(sql, aid, "milestone", targetTime);
|
await scheduleSnapshot(sql, aid, "milestone", targetTime);
|
||||||
@ -25,5 +25,5 @@ export const dispatchMilestoneSnapshotsWorker = async (_job: Job) => {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(e as Error, "mq", "fn:dispatchMilestoneSnapshotsWorker");
|
logger.error(e as Error, "mq", "fn:dispatchMilestoneSnapshotsWorker");
|
||||||
};
|
}
|
||||||
}
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Job } from "bullmq";
|
import { Job } from "bullmq";
|
||||||
import { getLatestVideoSnapshot } from "db/snapshot.ts";
|
import { getLatestVideoSnapshot } from "db/snapshot.ts";
|
||||||
import { truncate } from "utils/truncate.ts";
|
import { truncate } from "utils/truncate.ts";
|
||||||
import { getVideosWithoutActiveSnapshotSchedule, scheduleSnapshot } from "db/snapshotSchedule.ts";
|
import { getVideosWithoutActiveSnapshotScheduleByType, scheduleSnapshot } from "db/snapshotSchedule.ts";
|
||||||
import logger from "@core/log/logger.ts";
|
import logger from "@core/log/logger.ts";
|
||||||
import { HOUR, MINUTE, WEEK } from "@core/const/time.ts";
|
import { HOUR, MINUTE, WEEK } from "@core/const/time.ts";
|
||||||
import { lockManager } from "@core/mq/lockManager.ts";
|
import { lockManager } from "@core/mq/lockManager.ts";
|
||||||
@ -17,7 +17,7 @@ export const dispatchRegularSnapshotsWorker = async (_job: Job): Promise<void> =
|
|||||||
}
|
}
|
||||||
await lockManager.acquireLock("dispatchRegularSnapshots", 30 * 60);
|
await lockManager.acquireLock("dispatchRegularSnapshots", 30 * 60);
|
||||||
|
|
||||||
const aids = await getVideosWithoutActiveSnapshotSchedule(sql);
|
const aids = await getVideosWithoutActiveSnapshotScheduleByType(sql, "normal");
|
||||||
for (const rawAid of aids) {
|
for (const rawAid of aids) {
|
||||||
const aid = Number(rawAid);
|
const aid = Number(rawAid);
|
||||||
const latestSnapshot = await getLatestVideoSnapshot(sql, aid);
|
const latestSnapshot = await getLatestVideoSnapshot(sql, aid);
|
||||||
|
@ -7,4 +7,4 @@ export * from "./dispatchMilestoneSnapshots.ts";
|
|||||||
export * from "./dispatchRegularSnapshots.ts";
|
export * from "./dispatchRegularSnapshots.ts";
|
||||||
export * from "./snapshotVideo.ts";
|
export * from "./snapshotVideo.ts";
|
||||||
export * from "./scheduleCleanup.ts";
|
export * from "./scheduleCleanup.ts";
|
||||||
export * from "./snapshotTick.ts";
|
export * from "./snapshotTick.ts";
|
||||||
|
@ -2,6 +2,6 @@ import { sql } from "@core/db/dbNew";
|
|||||||
import { Job } from "bullmq";
|
import { Job } from "bullmq";
|
||||||
import { queueLatestVideos } from "mq/task/queueLatestVideo.ts";
|
import { queueLatestVideos } from "mq/task/queueLatestVideo.ts";
|
||||||
|
|
||||||
export const getLatestVideosWorker = async (_job: Job): Promise<void> =>{
|
export const getLatestVideosWorker = async (_job: Job): Promise<void> => {
|
||||||
await queueLatestVideos(sql);
|
await queueLatestVideos(sql);
|
||||||
}
|
};
|
||||||
|
@ -10,4 +10,4 @@ export const getVideoInfoWorker = async (job: Job): Promise<void> => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await insertVideoInfo(sql, aid);
|
await insertVideoInfo(sql, aid);
|
||||||
}
|
};
|
||||||
|
@ -5,15 +5,15 @@ import {
|
|||||||
getBulkSnapshotsInNextSecond,
|
getBulkSnapshotsInNextSecond,
|
||||||
getSnapshotsInNextSecond,
|
getSnapshotsInNextSecond,
|
||||||
setSnapshotStatus,
|
setSnapshotStatus,
|
||||||
videoHasProcessingSchedule,
|
videoHasProcessingSchedule
|
||||||
} from "db/snapshotSchedule.ts";
|
} from "db/snapshotSchedule.ts";
|
||||||
import logger from "@core/log/logger.ts";
|
import logger from "@core/log/logger.ts";
|
||||||
import { SnapshotQueue } from "mq/index.ts";
|
import { SnapshotQueue } from "mq/index.ts";
|
||||||
import { sql } from "@core/db/dbNew";
|
import { sql } from "@core/db/dbNew";
|
||||||
|
|
||||||
const priorityMap: { [key: string]: number } = {
|
const priorityMap: { [key: string]: number } = {
|
||||||
"milestone": 1,
|
milestone: 1,
|
||||||
"normal": 3,
|
normal: 3
|
||||||
};
|
};
|
||||||
|
|
||||||
export const bulkSnapshotTickWorker = async (_job: Job) => {
|
export const bulkSnapshotTickWorker = async (_job: Job) => {
|
||||||
@ -35,12 +35,16 @@ export const bulkSnapshotTickWorker = async (_job: Job) => {
|
|||||||
created_at: schedule.created_at,
|
created_at: schedule.created_at,
|
||||||
started_at: schedule.started_at,
|
started_at: schedule.started_at,
|
||||||
finished_at: schedule.finished_at,
|
finished_at: schedule.finished_at,
|
||||||
status: schedule.status,
|
status: schedule.status
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
await SnapshotQueue.add("bulkSnapshotVideo", {
|
await SnapshotQueue.add(
|
||||||
schedules: schedulesData,
|
"bulkSnapshotVideo",
|
||||||
}, { priority: 3 });
|
{
|
||||||
|
schedules: schedulesData
|
||||||
|
},
|
||||||
|
{ priority: 3 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return `OK`;
|
return `OK`;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -61,11 +65,15 @@ export const snapshotTickWorker = async (_job: Job) => {
|
|||||||
}
|
}
|
||||||
const aid = Number(schedule.aid);
|
const aid = Number(schedule.aid);
|
||||||
await setSnapshotStatus(sql, schedule.id, "processing");
|
await setSnapshotStatus(sql, schedule.id, "processing");
|
||||||
await SnapshotQueue.add("snapshotVideo", {
|
await SnapshotQueue.add(
|
||||||
aid: Number(aid),
|
"snapshotVideo",
|
||||||
id: Number(schedule.id),
|
{
|
||||||
type: schedule.type ?? "normal",
|
aid: Number(aid),
|
||||||
}, { priority });
|
id: Number(schedule.id),
|
||||||
|
type: schedule.type ?? "normal"
|
||||||
|
},
|
||||||
|
{ priority }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return `OK`;
|
return `OK`;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -2,7 +2,6 @@ import { Job } from "bullmq";
|
|||||||
import { scheduleSnapshot, setSnapshotStatus, snapshotScheduleExists } from "db/snapshotSchedule.ts";
|
import { scheduleSnapshot, setSnapshotStatus, snapshotScheduleExists } from "db/snapshotSchedule.ts";
|
||||||
import logger from "@core/log/logger.ts";
|
import logger from "@core/log/logger.ts";
|
||||||
import { HOUR, MINUTE, SECOND } from "@core/const/time.ts";
|
import { HOUR, MINUTE, SECOND } from "@core/const/time.ts";
|
||||||
import { lockManager } from "@core/mq/lockManager.ts";
|
|
||||||
import { getBiliVideoStatus, setBiliVideoStatus } from "../../db/bilibili_metadata.ts";
|
import { getBiliVideoStatus, setBiliVideoStatus } from "../../db/bilibili_metadata.ts";
|
||||||
import { insertVideoSnapshot } from "mq/task/getVideoStats.ts";
|
import { insertVideoSnapshot } from "mq/task/getVideoStats.ts";
|
||||||
import { getSongsPublihsedAt } from "db/songs.ts";
|
import { getSongsPublihsedAt } from "db/songs.ts";
|
||||||
@ -11,9 +10,9 @@ import { NetSchedulerError } from "@core/net/delegate.ts";
|
|||||||
import { sql } from "@core/db/dbNew.ts";
|
import { sql } from "@core/db/dbNew.ts";
|
||||||
|
|
||||||
const snapshotTypeToTaskMap: { [key: string]: string } = {
|
const snapshotTypeToTaskMap: { [key: string]: string } = {
|
||||||
"milestone": "snapshotMilestoneVideo",
|
milestone: "snapshotMilestoneVideo",
|
||||||
"normal": "snapshotVideo",
|
normal: "snapshotVideo",
|
||||||
"new": "snapshotMilestoneVideo",
|
new: "snapshotMilestoneVideo"
|
||||||
};
|
};
|
||||||
|
|
||||||
export const snapshotVideoWorker = async (job: Job): Promise<void> => {
|
export const snapshotVideoWorker = async (job: Job): Promise<void> => {
|
||||||
@ -32,7 +31,7 @@ export const snapshotVideoWorker = async (job: Job): Promise<void> => {
|
|||||||
logger.warn(
|
logger.warn(
|
||||||
`Video ${aid} has status ${status} in the database. Abort snapshoting.`,
|
`Video ${aid} has status ${status} in the database. Abort snapshoting.`,
|
||||||
"mq",
|
"mq",
|
||||||
"fn:dispatchRegularSnapshotsWorker",
|
"fn:dispatchRegularSnapshotsWorker"
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -44,7 +43,7 @@ export const snapshotVideoWorker = async (job: Job): Promise<void> => {
|
|||||||
logger.warn(
|
logger.warn(
|
||||||
`Bilibili return status ${status} when snapshoting for ${aid}.`,
|
`Bilibili return status ${status} when snapshoting for ${aid}.`,
|
||||||
"mq",
|
"mq",
|
||||||
"fn:dispatchRegularSnapshotsWorker",
|
"fn:dispatchRegularSnapshotsWorker"
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -52,7 +51,7 @@ export const snapshotVideoWorker = async (job: Job): Promise<void> => {
|
|||||||
if (type === "new") {
|
if (type === "new") {
|
||||||
const publihsedAt = await getSongsPublihsedAt(sql, aid);
|
const publihsedAt = await getSongsPublihsedAt(sql, aid);
|
||||||
const timeSincePublished = stat.time - publihsedAt!;
|
const timeSincePublished = stat.time - publihsedAt!;
|
||||||
const viewsPerHour = stat.views / timeSincePublished * HOUR;
|
const viewsPerHour = (stat.views / timeSincePublished) * HOUR;
|
||||||
if (timeSincePublished > 48 * HOUR) {
|
if (timeSincePublished > 48 * HOUR) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -78,40 +77,31 @@ export const snapshotVideoWorker = async (job: Job): Promise<void> => {
|
|||||||
logger.warn(
|
logger.warn(
|
||||||
`ETA (${etaHoursString}) too long for milestone snapshot. aid: ${aid}.`,
|
`ETA (${etaHoursString}) too long for milestone snapshot. aid: ${aid}.`,
|
||||||
"mq",
|
"mq",
|
||||||
"fn:dispatchRegularSnapshotsWorker",
|
"fn:snapshotVideoWorker"
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const targetTime = now + eta * HOUR;
|
const targetTime = now + eta * HOUR;
|
||||||
await scheduleSnapshot(sql, aid, type, targetTime);
|
await scheduleSnapshot(sql, aid, type, targetTime);
|
||||||
await setSnapshotStatus(sql, id, "completed");
|
await setSnapshotStatus(sql, id, "completed");
|
||||||
return;
|
return;
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
if (e instanceof NetSchedulerError && e.code === "NO_PROXY_AVAILABLE") {
|
if (e instanceof NetSchedulerError && e.code === "NO_PROXY_AVAILABLE") {
|
||||||
logger.warn(
|
logger.warn(`No available proxy for aid ${job.data.aid}.`, "mq", "fn:snapshotVideoWorker");
|
||||||
`No available proxy for aid ${job.data.aid}.`,
|
|
||||||
"mq",
|
|
||||||
"fn:takeSnapshotForVideoWorker",
|
|
||||||
);
|
|
||||||
await setSnapshotStatus(sql, id, "no_proxy");
|
await setSnapshotStatus(sql, id, "no_proxy");
|
||||||
await scheduleSnapshot(sql, aid, type, Date.now() + retryInterval);
|
await scheduleSnapshot(sql, aid, type, Date.now() + retryInterval, false, true);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (e instanceof NetSchedulerError && e.code === "ALICLOUD_PROXY_ERR") {
|
||||||
else if (e instanceof NetSchedulerError && e.code === "ALICLOUD_PROXY_ERR") {
|
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`Failed to proxy request for aid ${job.data.aid}: ${e.message}`,
|
`Failed to proxy request for aid ${job.data.aid}: ${e.message}`,
|
||||||
"mq",
|
"mq",
|
||||||
"fn:takeSnapshotForVideoWorker",
|
"fn:snapshotVideoWorker"
|
||||||
);
|
);
|
||||||
await setSnapshotStatus(sql, id, "failed");
|
await setSnapshotStatus(sql, id, "failed");
|
||||||
await scheduleSnapshot(sql, aid, type, Date.now() + retryInterval);
|
await scheduleSnapshot(sql, aid, type, Date.now() + retryInterval);
|
||||||
}
|
}
|
||||||
logger.error(e as Error, "mq", "fn:takeSnapshotForVideoWorker");
|
logger.error(e as Error, "mq", "fn:snapshotVideoWorker");
|
||||||
await setSnapshotStatus(sql, id, "failed");
|
await setSnapshotStatus(sql, id, "failed");
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
await lockManager.releaseLock("dispatchRegularSnapshots");
|
|
||||||
};
|
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
bulkScheduleSnapshot,
|
bulkScheduleSnapshot,
|
||||||
bulkSetSnapshotStatus,
|
bulkSetSnapshotStatus,
|
||||||
scheduleSnapshot,
|
scheduleSnapshot,
|
||||||
snapshotScheduleExists,
|
snapshotScheduleExists
|
||||||
} from "db/snapshotSchedule.ts";
|
} from "db/snapshotSchedule.ts";
|
||||||
import { bulkGetVideoStats } from "net/bulkGetVideoStats.ts";
|
import { bulkGetVideoStats } from "net/bulkGetVideoStats.ts";
|
||||||
import logger from "@core/log/logger.ts";
|
import logger from "@core/log/logger.ts";
|
||||||
@ -46,16 +46,16 @@ export const takeBulkSnapshotForVideosWorker = async (job: Job) => {
|
|||||||
await sql`
|
await sql`
|
||||||
INSERT INTO video_snapshot (aid, views, danmakus, replies, likes, coins, shares, favorites)
|
INSERT INTO video_snapshot (aid, views, danmakus, replies, likes, coins, shares, favorites)
|
||||||
VALUES (
|
VALUES (
|
||||||
${aid},
|
${aid},
|
||||||
${views},
|
${views},
|
||||||
${danmakus},
|
${danmakus},
|
||||||
${replies},
|
${replies},
|
||||||
${likes},
|
${likes},
|
||||||
${coins},
|
${coins},
|
||||||
${shares},
|
${shares},
|
||||||
${favorites}
|
${favorites}
|
||||||
)
|
)
|
||||||
`
|
`;
|
||||||
|
|
||||||
logger.log(`Taken snapshot for video ${aid} in bulk.`, "net", "fn:takeBulkSnapshotForVideosWorker");
|
logger.log(`Taken snapshot for video ${aid} in bulk.`, "net", "fn:takeBulkSnapshotForVideosWorker");
|
||||||
}
|
}
|
||||||
@ -72,13 +72,16 @@ export const takeBulkSnapshotForVideosWorker = async (job: Job) => {
|
|||||||
return `DONE`;
|
return `DONE`;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof NetSchedulerError && e.code === "NO_PROXY_AVAILABLE") {
|
if (e instanceof NetSchedulerError && e.code === "NO_PROXY_AVAILABLE") {
|
||||||
logger.warn(
|
logger.warn(`No available proxy for bulk request now.`, "mq", "fn:takeBulkSnapshotForVideosWorker");
|
||||||
`No available proxy for bulk request now.`,
|
|
||||||
"mq",
|
|
||||||
"fn:takeBulkSnapshotForVideosWorker",
|
|
||||||
);
|
|
||||||
await bulkSetSnapshotStatus(sql, ids, "no_proxy");
|
await bulkSetSnapshotStatus(sql, ids, "no_proxy");
|
||||||
await bulkScheduleSnapshot(sql, aidsToFetch, "normal", Date.now() + 20 * MINUTE * Math.random());
|
await bulkScheduleSnapshot(
|
||||||
|
sql,
|
||||||
|
aidsToFetch,
|
||||||
|
"normal",
|
||||||
|
Date.now() + 20 * MINUTE * Math.random(),
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.error(e as Error, "mq", "fn:takeBulkSnapshotForVideosWorker");
|
logger.error(e as Error, "mq", "fn:takeBulkSnapshotForVideosWorker");
|
||||||
|
@ -2,13 +2,13 @@ import { Queue, ConnectionOptions } from "bullmq";
|
|||||||
import { redis } from "@core/db/redis.ts";
|
import { redis } from "@core/db/redis.ts";
|
||||||
|
|
||||||
export const LatestVideosQueue = new Queue("latestVideos", {
|
export const LatestVideosQueue = new Queue("latestVideos", {
|
||||||
connection: redis as ConnectionOptions
|
connection: redis as ConnectionOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ClassifyVideoQueue = new Queue("classifyVideo", {
|
export const ClassifyVideoQueue = new Queue("classifyVideo", {
|
||||||
connection: redis as ConnectionOptions
|
connection: redis as ConnectionOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
export const SnapshotQueue = new Queue("snapshot", {
|
export const SnapshotQueue = new Queue("snapshot", {
|
||||||
connection: redis as ConnectionOptions
|
connection: redis as ConnectionOptions
|
||||||
});
|
});
|
||||||
|
@ -62,8 +62,8 @@ export async function initMQ() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await SnapshotQueue.upsertJobScheduler("dispatchArchiveSnapshots", {
|
await SnapshotQueue.upsertJobScheduler("dispatchArchiveSnapshots", {
|
||||||
every: 6 * HOUR,
|
every: 2 * HOUR,
|
||||||
immediately: true
|
immediately: false
|
||||||
});
|
});
|
||||||
|
|
||||||
await SnapshotQueue.upsertJobScheduler("scheduleCleanup", {
|
await SnapshotQueue.upsertJobScheduler("scheduleCleanup", {
|
||||||
|
@ -2,7 +2,7 @@ import { findClosestSnapshot, getLatestSnapshot, hasAtLeast2Snapshots } from "db
|
|||||||
import { truncate } from "utils/truncate.ts";
|
import { truncate } from "utils/truncate.ts";
|
||||||
import { closetMilestone } from "./exec/snapshotTick.ts";
|
import { closetMilestone } from "./exec/snapshotTick.ts";
|
||||||
import { HOUR, MINUTE } from "@core/const/time.ts";
|
import { HOUR, MINUTE } from "@core/const/time.ts";
|
||||||
import type { Psql } from "@core/db/global.d.ts";
|
import type { Psql } from "@core/db/psql.d.ts";
|
||||||
|
|
||||||
const log = (value: number, base: number = 10) => Math.log(value) / Math.log(base);
|
const log = (value: number, base: number = 10) => Math.log(value) / Math.log(base);
|
||||||
|
|
||||||
@ -12,13 +12,12 @@ const getFactor = (x: number) => {
|
|||||||
const c = 100;
|
const c = 100;
|
||||||
const u = 0.601;
|
const u = 0.601;
|
||||||
const g = 455;
|
const g = 455;
|
||||||
if (x>g) {
|
if (x > g) {
|
||||||
return log(b/log(x+1),a);
|
return log(b / log(x + 1), a);
|
||||||
|
} else {
|
||||||
|
return log(b / log(x + c), a) + u;
|
||||||
}
|
}
|
||||||
else {
|
};
|
||||||
return log(b/log(x+c),a)+u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the minimum ETA in hours for the next snapshot
|
* Returns the minimum ETA in hours for the next snapshot
|
||||||
@ -34,7 +33,7 @@ export const getAdjustedShortTermETA = async (sql: Psql, aid: number) => {
|
|||||||
if (!snapshotsEnough) return 0;
|
if (!snapshotsEnough) return 0;
|
||||||
|
|
||||||
const currentTimestamp = new Date().getTime();
|
const currentTimestamp = new Date().getTime();
|
||||||
const timeIntervals = [3 * MINUTE, 20 * MINUTE, 1 * HOUR, 3 * HOUR, 6 * HOUR, 72 * HOUR];
|
const timeIntervals = [3 * MINUTE, 20 * MINUTE, HOUR, 3 * HOUR, 6 * HOUR, 72 * HOUR];
|
||||||
const DELTA = 0.00001;
|
const DELTA = 0.00001;
|
||||||
let minETAHours = Infinity;
|
let minETAHours = Infinity;
|
||||||
|
|
||||||
|
@ -25,5 +25,5 @@ export async function insertIntoSongs(sql: Psql, aid: number) {
|
|||||||
(SELECT duration FROM bilibili_metadata WHERE aid = ${aid})
|
(SELECT duration FROM bilibili_metadata WHERE aid = ${aid})
|
||||||
)
|
)
|
||||||
ON CONFLICT DO NOTHING
|
ON CONFLICT DO NOTHING
|
||||||
`
|
`;
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,9 @@ export async function insertVideoInfo(sql: Psql, aid: number) {
|
|||||||
const bvid = data.View.bvid;
|
const bvid = data.View.bvid;
|
||||||
const desc = data.View.desc;
|
const desc = data.View.desc;
|
||||||
const uid = data.View.owner.mid;
|
const uid = data.View.owner.mid;
|
||||||
const tags = data.Tags
|
const tags = data.Tags.filter((tag) => !["old_channel", "topic"].indexOf(tag.tag_type))
|
||||||
.filter((tag) => !["old_channel", "topic"].indexOf(tag.tag_type))
|
.map((tag) => tag.tag_name)
|
||||||
.map((tag) => tag.tag_name).join(",");
|
.join(",");
|
||||||
const title = data.View.title;
|
const title = data.View.title;
|
||||||
const published_at = formatTimestampToPsql(data.View.pubdate * SECOND + 8 * HOUR);
|
const published_at = formatTimestampToPsql(data.View.pubdate * SECOND + 8 * HOUR);
|
||||||
const duration = data.View.duration;
|
const duration = data.View.duration;
|
||||||
@ -55,7 +55,7 @@ export async function insertVideoInfo(sql: Psql, aid: number) {
|
|||||||
${stat.share},
|
${stat.share},
|
||||||
${stat.favorite}
|
${stat.favorite}
|
||||||
)
|
)
|
||||||
`
|
`;
|
||||||
|
|
||||||
logger.log(`Inserted video metadata for aid: ${aid}`, "mq");
|
logger.log(`Inserted video metadata for aid: ${aid}`, "mq");
|
||||||
await ClassifyVideoQueue.add("classifyVideo", { aid });
|
await ClassifyVideoQueue.add("classifyVideo", { aid });
|
||||||
|
@ -24,11 +24,7 @@ export interface SnapshotNumber {
|
|||||||
* - The native `fetch` function threw an error: with error code `FETCH_ERROR`
|
* - The native `fetch` function threw an error: with error code `FETCH_ERROR`
|
||||||
* - The alicloud-fc threw an error: with error code `ALICLOUD_FC_ERROR`
|
* - The alicloud-fc threw an error: with error code `ALICLOUD_FC_ERROR`
|
||||||
*/
|
*/
|
||||||
export async function insertVideoSnapshot(
|
export async function insertVideoSnapshot(sql: Psql, aid: number, task: string): Promise<number | SnapshotNumber> {
|
||||||
sql: Psql,
|
|
||||||
aid: number,
|
|
||||||
task: string,
|
|
||||||
): Promise<number | SnapshotNumber> {
|
|
||||||
const data = await getVideoInfo(aid, task);
|
const data = await getVideoInfo(aid, task);
|
||||||
if (typeof data == "number") {
|
if (typeof data == "number") {
|
||||||
return data;
|
return data;
|
||||||
@ -42,10 +38,10 @@ export async function insertVideoSnapshot(
|
|||||||
const shares = data.stat.share;
|
const shares = data.stat.share;
|
||||||
const favorites = data.stat.favorite;
|
const favorites = data.stat.favorite;
|
||||||
|
|
||||||
await sql`
|
await sql`
|
||||||
INSERT INTO video_snapshot (aid, views, danmakus, replies, likes, coins, shares, favorites)
|
INSERT INTO video_snapshot (aid, views, danmakus, replies, likes, coins, shares, favorites)
|
||||||
VALUES (${aid}, ${views}, ${danmakus}, ${replies}, ${likes}, ${coins}, ${shares}, ${favorites})
|
VALUES (${aid}, ${views}, ${danmakus}, ${replies}, ${likes}, ${coins}, ${shares}, ${favorites})
|
||||||
`
|
`;
|
||||||
|
|
||||||
logger.log(`Taken snapshot for video ${aid}.`, "net", "fn:insertVideoSnapshot");
|
logger.log(`Taken snapshot for video ${aid}.`, "net", "fn:insertVideoSnapshot");
|
||||||
|
|
||||||
@ -58,6 +54,6 @@ export async function insertVideoSnapshot(
|
|||||||
coins,
|
coins,
|
||||||
shares,
|
shares,
|
||||||
favorites,
|
favorites,
|
||||||
time,
|
time
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,7 @@ import logger from "@core/log/logger.ts";
|
|||||||
import { LatestVideosQueue } from "mq/index.ts";
|
import { LatestVideosQueue } from "mq/index.ts";
|
||||||
import type { Psql } from "@core/db/psql.d.ts";
|
import type { Psql } from "@core/db/psql.d.ts";
|
||||||
|
|
||||||
export async function queueLatestVideos(
|
export async function queueLatestVideos(sql: Psql): Promise<number | null> {
|
||||||
sql: Psql,
|
|
||||||
): Promise<number | null> {
|
|
||||||
let page = 1;
|
let page = 1;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
const videosFound = new Set();
|
const videosFound = new Set();
|
||||||
@ -26,14 +24,18 @@ export async function queueLatestVideos(
|
|||||||
if (videoExists) {
|
if (videoExists) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
await LatestVideosQueue.add("getVideoInfo", { aid }, {
|
await LatestVideosQueue.add(
|
||||||
delay,
|
"getVideoInfo",
|
||||||
attempts: 100,
|
{ aid },
|
||||||
backoff: {
|
{
|
||||||
type: "fixed",
|
delay,
|
||||||
delay: SECOND * 5,
|
attempts: 100,
|
||||||
},
|
backoff: {
|
||||||
});
|
type: "fixed",
|
||||||
|
delay: SECOND * 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
videosFound.add(aid);
|
videosFound.add(aid);
|
||||||
allExists = false;
|
allExists = false;
|
||||||
delay += Math.random() * SECOND * 1.5;
|
delay += Math.random() * SECOND * 1.5;
|
||||||
@ -42,7 +44,7 @@ export async function queueLatestVideos(
|
|||||||
logger.log(
|
logger.log(
|
||||||
`Page ${page} crawled, total: ${videosFound.size}/${i} videos added/observed.`,
|
`Page ${page} crawled, total: ${videosFound.size}/${i} videos added/observed.`,
|
||||||
"net",
|
"net",
|
||||||
"fn:queueLatestVideos()",
|
"fn:queueLatestVideos()"
|
||||||
);
|
);
|
||||||
if (allExists) {
|
if (allExists) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { findClosestSnapshot, findSnapshotBefore, getLatestSnapshot } from "db/snapshotSchedule.ts";
|
import { findClosestSnapshot, findSnapshotBefore, getLatestSnapshot } from "db/snapshotSchedule.ts";
|
||||||
import { HOUR } from "@core/const/time.ts";
|
import { HOUR } from "@core/const/time.ts";
|
||||||
import type { Psql } from "@core/db/global.d.ts";
|
import type { Psql } from "@core/db/psql.d.ts";
|
||||||
|
|
||||||
export const getRegularSnapshotInterval = async (sql: Psql, aid: number) => {
|
export const getRegularSnapshotInterval = async (sql: Psql, aid: number) => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
@ -14,7 +14,7 @@ export const getRegularSnapshotInterval = async (sql: Psql, aid: number) => {
|
|||||||
if (hoursDiff < 8) return 24;
|
if (hoursDiff < 8) return 24;
|
||||||
const viewsDiff = latestSnapshot.views - oldSnapshot.views;
|
const viewsDiff = latestSnapshot.views - oldSnapshot.views;
|
||||||
if (viewsDiff === 0) return 72;
|
if (viewsDiff === 0) return 72;
|
||||||
const speedPerDay = viewsDiff / (hoursDiff + 0.001) * 24;
|
const speedPerDay = (viewsDiff / (hoursDiff + 0.001)) * 24;
|
||||||
if (speedPerDay < 6) return 36;
|
if (speedPerDay < 6) return 36;
|
||||||
if (speedPerDay < 120) return 24;
|
if (speedPerDay < 120) return 24;
|
||||||
if (speedPerDay < 320) return 12;
|
if (speedPerDay < 320) return 12;
|
||||||
|
@ -2,14 +2,10 @@ import { sql } from "@core/db/dbNew";
|
|||||||
import logger from "@core/log/logger.ts";
|
import logger from "@core/log/logger.ts";
|
||||||
|
|
||||||
export async function removeAllTimeoutSchedules() {
|
export async function removeAllTimeoutSchedules() {
|
||||||
logger.log(
|
logger.log("Too many timeout schedules, directly removing these schedules...", "mq", "fn:scheduleCleanupWorker");
|
||||||
"Too many timeout schedules, directly removing these schedules...",
|
|
||||||
"mq",
|
|
||||||
"fn:scheduleCleanupWorker",
|
|
||||||
);
|
|
||||||
return await sql`
|
return await sql`
|
||||||
DELETE FROM snapshot_schedule
|
DELETE FROM snapshot_schedule
|
||||||
WHERE status IN ('pending', 'processing')
|
WHERE status IN ('pending', 'processing')
|
||||||
AND started_at < NOW() - INTERVAL '30 minutes'
|
AND started_at < NOW() - INTERVAL '30 minutes'
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "crawler",
|
"name": "crawler",
|
||||||
|
"version": "1.2.26",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "bun --env-file=.env.test run vitest",
|
"test": "bun --env-file=.env.test run vitest",
|
||||||
"worker:main": "bun run ./src/worker.ts",
|
"worker:main": "bun run ./src/worker.ts",
|
||||||
@ -7,7 +8,8 @@
|
|||||||
"worker:filter": "bun run ./build/filterWorker.js",
|
"worker:filter": "bun run ./build/filterWorker.js",
|
||||||
"adder": "bun run ./src/jobAdder.ts",
|
"adder": "bun run ./src/jobAdder.ts",
|
||||||
"bullui": "bun run ./src/bullui.ts",
|
"bullui": "bun run ./src/bullui.ts",
|
||||||
"all": "bun run concurrently --restart-tries -1 'bun run worker:main' 'bun run adder' 'bun run bullui' 'bun run worker:filter'"
|
"all": "bun run concurrently --restart-tries -1 'bun run worker:main' 'bun run adder' 'bun run worker:filter'",
|
||||||
|
"format": "prettier --write ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"concurrently": "^9.1.2"
|
"concurrently": "^9.1.2"
|
||||||
@ -19,6 +21,7 @@
|
|||||||
"bullmq": "^5.52.1",
|
"bullmq": "^5.52.1",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
"ioredis": "^5.6.1",
|
"ioredis": "^5.6.1",
|
||||||
|
"postgres": "^3.4.5",
|
||||||
"onnxruntime-node": "1.19.2"
|
"onnxruntime-node": "1.19.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,12 @@ import Bun from "bun";
|
|||||||
await Bun.build({
|
await Bun.build({
|
||||||
entrypoints: ["./src/filterWorker.ts"],
|
entrypoints: ["./src/filterWorker.ts"],
|
||||||
outdir: "./build",
|
outdir: "./build",
|
||||||
target: "node"
|
target: "node"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const file = Bun.file("./build/filterWorker.js");
|
const file = Bun.file("./build/filterWorker.js");
|
||||||
const code = await file.text();
|
const code = await file.text();
|
||||||
|
|
||||||
const modifiedCode = code.replaceAll("../bin/napi-v3/", "../../../node_modules/onnxruntime-node/bin/napi-v3/");
|
const modifiedCode = code.replaceAll("../bin/napi-v3/", "../../../node_modules/onnxruntime-node/bin/napi-v3/");
|
||||||
|
|
||||||
await Bun.write("./build/filterWorker.js", modifiedCode);
|
await Bun.write("./build/filterWorker.js", modifiedCode);
|
||||||
|
@ -11,9 +11,9 @@ createBullBoard({
|
|||||||
queues: [
|
queues: [
|
||||||
new BullMQAdapter(LatestVideosQueue),
|
new BullMQAdapter(LatestVideosQueue),
|
||||||
new BullMQAdapter(ClassifyVideoQueue),
|
new BullMQAdapter(ClassifyVideoQueue),
|
||||||
new BullMQAdapter(SnapshotQueue),
|
new BullMQAdapter(SnapshotQueue)
|
||||||
],
|
],
|
||||||
serverAdapter: serverAdapter,
|
serverAdapter: serverAdapter
|
||||||
});
|
});
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
@ -7,13 +7,13 @@ import { lockManager } from "@core/mq/lockManager.ts";
|
|||||||
import Akari from "ml/akari.ts";
|
import Akari from "ml/akari.ts";
|
||||||
|
|
||||||
const shutdown = async (signal: string) => {
|
const shutdown = async (signal: string) => {
|
||||||
logger.log(`${signal} Received: Shutting down workers...`, "mq");
|
logger.log(`${signal} Received: Shutting down workers...`, "mq");
|
||||||
await filterWorker.close(true);
|
await filterWorker.close(true);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
process.on('SIGINT', () => shutdown('SIGINT'));
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
||||||
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
||||||
|
|
||||||
await Akari.init();
|
await Akari.init();
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ const filterWorker = new Worker(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ connection: redis as ConnectionOptions, concurrency: 2, removeOnComplete: { count: 1000 } },
|
{ connection: redis as ConnectionOptions, concurrency: 2, removeOnComplete: { count: 1000 } }
|
||||||
);
|
);
|
||||||
|
|
||||||
filterWorker.on("active", () => {
|
filterWorker.on("active", () => {
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
scheduleCleanupWorker,
|
scheduleCleanupWorker,
|
||||||
snapshotTickWorker,
|
snapshotTickWorker,
|
||||||
snapshotVideoWorker,
|
snapshotVideoWorker,
|
||||||
takeBulkSnapshotForVideosWorker,
|
takeBulkSnapshotForVideosWorker
|
||||||
} from "mq/exec/executors.ts";
|
} from "mq/exec/executors.ts";
|
||||||
import { redis } from "@core/db/redis.ts";
|
import { redis } from "@core/db/redis.ts";
|
||||||
import logger from "@core/log/logger.ts";
|
import logger from "@core/log/logger.ts";
|
||||||
@ -30,15 +30,15 @@ const releaseAllLocks = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const shutdown = async (signal: string) => {
|
const shutdown = async (signal: string) => {
|
||||||
logger.log(`${signal} Received: Shutting down workers...`, "mq");
|
logger.log(`${signal} Received: Shutting down workers...`, "mq");
|
||||||
await releaseAllLocks();
|
await releaseAllLocks();
|
||||||
await latestVideoWorker.close(true);
|
await latestVideoWorker.close(true);
|
||||||
await snapshotWorker.close(true);
|
await snapshotWorker.close(true);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
process.on('SIGINT', () => shutdown('SIGINT'));
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
||||||
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
||||||
|
|
||||||
const latestVideoWorker = new Worker(
|
const latestVideoWorker = new Worker(
|
||||||
"latestVideos",
|
"latestVideos",
|
||||||
@ -58,8 +58,8 @@ const latestVideoWorker = new Worker(
|
|||||||
connection: redis as ConnectionOptions,
|
connection: redis as ConnectionOptions,
|
||||||
concurrency: 6,
|
concurrency: 6,
|
||||||
removeOnComplete: { count: 1440 },
|
removeOnComplete: { count: 1440 },
|
||||||
removeOnFail: { count: 0 },
|
removeOnFail: { count: 0 }
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
latestVideoWorker.on("active", () => {
|
latestVideoWorker.on("active", () => {
|
||||||
@ -95,7 +95,7 @@ const snapshotWorker = new Worker(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ connection: redis as ConnectionOptions, concurrency: 50, removeOnComplete: { count: 2000 } },
|
{ connection: redis as ConnectionOptions, concurrency: 50, removeOnComplete: { count: 2000 } }
|
||||||
);
|
);
|
||||||
|
|
||||||
snapshotWorker.on("error", (err) => {
|
snapshotWorker.on("error", (err) => {
|
||||||
|
@ -56,65 +56,65 @@ const databasePreparationQuery = `
|
|||||||
CREATE INDEX idx_snapshot_schedule_status ON snapshot_schedule USING btree (status);
|
CREATE INDEX idx_snapshot_schedule_status ON snapshot_schedule USING btree (status);
|
||||||
CREATE INDEX idx_snapshot_schedule_type ON snapshot_schedule USING btree (type);
|
CREATE INDEX idx_snapshot_schedule_type ON snapshot_schedule USING btree (type);
|
||||||
CREATE UNIQUE INDEX snapshot_schedule_pkey ON snapshot_schedule USING btree (id);
|
CREATE UNIQUE INDEX snapshot_schedule_pkey ON snapshot_schedule USING btree (id);
|
||||||
`
|
`;
|
||||||
|
|
||||||
const cleanUpQuery = `
|
const cleanUpQuery = `
|
||||||
DROP SEQUENCE IF EXISTS "snapshot_schedule_id_seq" CASCADE;
|
DROP SEQUENCE IF EXISTS "snapshot_schedule_id_seq" CASCADE;
|
||||||
DROP TABLE IF EXISTS "snapshot_schedule" CASCADE;
|
DROP TABLE IF EXISTS "snapshot_schedule" CASCADE;
|
||||||
`
|
`;
|
||||||
|
|
||||||
async function testMocking() {
|
async function testMocking() {
|
||||||
await sql.begin(async tx => {
|
await sql.begin(async (tx) => {
|
||||||
await tx.unsafe(cleanUpQuery).simple();
|
await tx.unsafe(cleanUpQuery).simple();
|
||||||
await tx.unsafe(databasePreparationQuery).simple();
|
await tx.unsafe(databasePreparationQuery).simple();
|
||||||
|
|
||||||
await tx`
|
await tx`
|
||||||
INSERT INTO snapshot_schedule
|
INSERT INTO snapshot_schedule
|
||||||
${sql(mockSnapshotSchedules, 'aid', 'created_at', 'finished_at', 'id', 'started_at', 'status', 'type')}
|
${sql(mockSnapshotSchedules, "aid", "created_at", "finished_at", "id", "started_at", "status", "type")}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
await tx`
|
await tx`
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
`
|
`;
|
||||||
|
|
||||||
await tx.unsafe(cleanUpQuery).simple();
|
await tx.unsafe(cleanUpQuery).simple();
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testBulkSetSnapshotStatus() {
|
async function testBulkSetSnapshotStatus() {
|
||||||
return await sql.begin(async tx => {
|
return await sql.begin(async (tx) => {
|
||||||
await tx.unsafe(cleanUpQuery).simple();
|
await tx.unsafe(cleanUpQuery).simple();
|
||||||
await tx.unsafe(databasePreparationQuery).simple();
|
await tx.unsafe(databasePreparationQuery).simple();
|
||||||
|
|
||||||
await tx`
|
await tx`
|
||||||
INSERT INTO snapshot_schedule
|
INSERT INTO snapshot_schedule
|
||||||
${sql(mockSnapshotSchedules, 'aid', 'created_at', 'finished_at', 'id', 'started_at', 'status', 'type')}
|
${sql(mockSnapshotSchedules, "aid", "created_at", "finished_at", "id", "started_at", "status", "type")}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ids = [1, 2, 3];
|
const ids = [1, 2, 3];
|
||||||
|
|
||||||
await bulkSetSnapshotStatus(tx, ids, 'pending')
|
|
||||||
|
|
||||||
const rows = tx<{status: string}[]>`
|
await bulkSetSnapshotStatus(tx, ids, "pending");
|
||||||
|
|
||||||
|
const rows = tx<{ status: string }[]>`
|
||||||
SELECT status FROM snapshot_schedule WHERE id = 1;
|
SELECT status FROM snapshot_schedule WHERE id = 1;
|
||||||
`.execute();
|
`.execute();
|
||||||
|
|
||||||
await tx`
|
await tx`
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
`
|
`;
|
||||||
|
|
||||||
await tx.unsafe(cleanUpQuery).simple();
|
await tx.unsafe(cleanUpQuery).simple();
|
||||||
return rows;
|
return rows;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
test("data mocking works", async () => {
|
test("data mocking works", async () => {
|
||||||
await testMocking();
|
await testMocking();
|
||||||
expect(() => {}).not.toThrowError();
|
expect(() => {}).not.toThrowError();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("bulkSetSnapshotStatus core logic works smoothly", async () => {
|
test("bulkSetSnapshotStatus core logic works smoothly", async () => {
|
||||||
const rows = await testBulkSetSnapshotStatus();
|
const rows = await testBulkSetSnapshotStatus();
|
||||||
expect(rows.every(item => item.status === 'pending')).toBe(true);
|
expect(rows.every((item) => item.status === "pending")).toBe(true);
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export function formatTimestampToPsql(timestamp: number) {
|
export function formatTimestampToPsql(timestamp: number) {
|
||||||
const date = new Date(timestamp);
|
const date = new Date(timestamp);
|
||||||
return date.toISOString().slice(0, 23).replace("T", " ");
|
return date.toISOString().slice(0, 23).replace("T", " ") + "+08";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseTimestampFromPsql(timestamp: string) {
|
export function parseTimestampFromPsql(timestamp: string) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { defineConfig } from "vitest/config";
|
import { defineConfig } from "vitest/config";
|
||||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
import tsconfigPaths from "vite-tsconfig-paths";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [tsconfigPaths()]
|
plugins: [tsconfigPaths()]
|
||||||
});
|
});
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
{
|
{
|
||||||
"name": "frontend",
|
"name": "frontend",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.1",
|
"version": "1.9.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/node": "^9.1.3",
|
"@astrojs/node": "^9.1.3",
|
||||||
"@astrojs/svelte": "^7.0.9",
|
"@astrojs/svelte": "^7.0.9",
|
||||||
"@tailwindcss/vite": "^4.1.4",
|
"@tailwindcss/vite": "^4.1.4",
|
||||||
"argon2id": "^1.0.1",
|
"argon2id": "^1.0.1",
|
||||||
"astro": "^5.5.5",
|
"astro": "^5.5.5",
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"pg": "^8.11.11",
|
"pg": "^8.11.11",
|
||||||
"postcss": "^8.5.3",
|
"postcss": "^8.5.3",
|
||||||
"postgres": "^3.4.5",
|
"postgres": "^3.4.5",
|
||||||
"svelte": "^5.25.7",
|
"svelte": "^5.25.7",
|
||||||
"tailwindcss": "^4.1.4",
|
"tailwindcss": "^4.1.4",
|
||||||
"ua-parser-js": "^2.0.3",
|
"ua-parser-js": "^2.0.3",
|
||||||
"vite-tsconfig-paths": "^5.1.4"
|
"vite-tsconfig-paths": "^5.1.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-wasm": "^6.2.2",
|
"@rollup/plugin-wasm": "^6.2.2",
|
||||||
"@types/pg": "^8.11.11"
|
"@types/pg": "^8.11.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,7 @@
|
|||||||
---
|
---
|
||||||
import Layout from "@layouts/Layout.astro";
|
import Layout from "@layouts/Layout.astro";
|
||||||
import TitleBar from "@components/TitleBar.astro";
|
import TitleBar from "@components/TitleBar.astro";
|
||||||
import MetadataRow from "@components/InfoPage/MetadataRow.astro";
|
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { zhCN } from "date-fns/locale";
|
|
||||||
import { getAllSnapshots } from "src/db/snapshots/getAllSnapshots";
|
|
||||||
import { getAidFromBV } from "src/db/bilibili_metadata/getAidFromBV";
|
|
||||||
import { getVideoMetadata } from "src/db/bilibili_metadata/getVideoMetadata";
|
|
||||||
import { aidExists as idExists } from "src/db/bilibili_metadata/aidExists";
|
|
||||||
import StatRow from "@components/VideoInfoPage/StatRow.astro";
|
import StatRow from "@components/VideoInfoPage/StatRow.astro";
|
||||||
|
|
||||||
const { id } = Astro.params;
|
const { id } = Astro.params;
|
||||||
|
44
packages/next/.gitignore
vendored
Normal file
44
packages/next/.gitignore
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.*
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/versions
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# env files (can opt-in for committing if needed)
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
|
||||||
|
# fumadocs
|
||||||
|
.source
|
3
packages/next/.source/index.ts
Normal file
3
packages/next/.source/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// @ts-nocheck -- skip type checking
|
||||||
|
import { _runtime } from "fumadocs-mdx"
|
||||||
|
import * as _source from "../source.config"
|
8
packages/next/.source/source.config.mjs
Normal file
8
packages/next/.source/source.config.mjs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// source.config.ts
|
||||||
|
import { defineConfig } from "fumadocs-mdx/config";
|
||||||
|
var source_config_default = defineConfig({
|
||||||
|
mdxOptions: {}
|
||||||
|
});
|
||||||
|
export {
|
||||||
|
source_config_default as default
|
||||||
|
};
|
3
packages/next/app/[locale]/LICENSE/content.css
Normal file
3
packages/next/app/[locale]/LICENSE/content.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
p {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
17
packages/next/app/[locale]/LICENSE/page.tsx
Normal file
17
packages/next/app/[locale]/LICENSE/page.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import HeaderServer from "@/components/shell/HeaderServer";
|
||||||
|
import tpLicense from "@/content/THIRD-PARTY-LICENSES.txt";
|
||||||
|
import projectLicense from "@/content/LICENSE.txt";
|
||||||
|
|
||||||
|
export default function LicensePage() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<HeaderServer />
|
||||||
|
<main className="lg:max-w-4xl lg:mx-auto">
|
||||||
|
<p className="leading-10">中 V 档案馆的软件在 AGPL 3.0 下许可,请见:</p>
|
||||||
|
<pre className="break-all whitespace-pre-wrap">{projectLicense}</pre>
|
||||||
|
<p className="leading-10">本项目引入的其它项目项目的许可详情如下:</p>
|
||||||
|
<pre className="break-all whitespace-pre-wrap">{tpLicense}</pre>
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
8
packages/next/app/[locale]/about/AboutContent.tsx
Normal file
8
packages/next/app/[locale]/about/AboutContent.tsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import About from "@/content/about.mdx";
|
||||||
|
import "./content.css";
|
||||||
|
|
||||||
|
export default function AboutContent() {
|
||||||
|
return <About />;
|
||||||
|
}
|
43
packages/next/app/[locale]/about/content.css
Normal file
43
packages/next/app/[locale]/about/content.css
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
.content {
|
||||||
|
h1 {
|
||||||
|
@apply text-3xl;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
@apply text-2xl;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
@apply text-xl;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
@apply text-lg;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
@apply my-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
@apply list-disc list-inside my-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
@apply list-decimal list-inside my-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
@apply my-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
@apply bg-gray-200 font-medium;
|
||||||
|
}
|
||||||
|
ul li p,
|
||||||
|
ol li p {
|
||||||
|
@apply inline;
|
||||||
|
}
|
||||||
|
}
|
17
packages/next/app/[locale]/about/page.tsx
Normal file
17
packages/next/app/[locale]/about/page.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { Header } from "@/components/shell/Header";
|
||||||
|
import { getCurrentUser } from "@/lib/userAuth";
|
||||||
|
import AboutContent from "./AboutContent";
|
||||||
|
|
||||||
|
export default async function AboutPage() {
|
||||||
|
const user = await getCurrentUser();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Header user={user} />
|
||||||
|
<main className="flex flex-col items-center min-h-screen gap-8 md:mt-12 relative z-0">
|
||||||
|
<div className="w-full lg:w-2/3 xl:w-1/2 content px-8 md:px-12 lg:px-0">
|
||||||
|
<AboutContent />
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Black.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Black.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-BlackItalic.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-BlackItalic.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Bold.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Bold.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-BoldItalic.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-BoldItalic.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-ExtraBold.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-ExtraBold.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-ExtraBoldItalic.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-ExtraBoldItalic.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-ExtraLight.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-ExtraLight.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-ExtraLightItalic.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-ExtraLightItalic.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Italic.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Italic.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Light.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Light.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-LightItalic.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-LightItalic.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Medium.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Medium.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-MediumItalic.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-MediumItalic.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Regular.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Regular.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-SemiBold.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-SemiBold.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-SemiBoldItalic.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-SemiBoldItalic.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Thin.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-Thin.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-ThinItalic.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/Inter-ThinItalic.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
449
packages/next/app/[locale]/fonts/InterFont/Inter.css
Normal file
449
packages/next/app/[locale]/fonts/InterFont/Inter.css
Normal file
@ -0,0 +1,449 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: "Inter Variable";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100 900;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterVariable.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter Variable";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 100 900;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterVariable-Italic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static fonts */
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-Thin.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-ThinItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-ExtraLight.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-ExtraLightItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-Light.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-LightItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-Regular.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-Italic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-Medium.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-MediumItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-SemiBold.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-SemiBoldItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-Bold.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-BoldItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-ExtraBold.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-ExtraBoldItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-Black.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("Inter-BlackItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-Thin.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 100;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-ThinItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-ExtraLight.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-ExtraLightItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-Light.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-LightItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-Regular.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-Italic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-Medium.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-MediumItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-SemiBold.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-SemiBoldItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-Bold.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-BoldItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-ExtraBold.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-ExtraBoldItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-Black.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "InterDisplay";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: fallback;
|
||||||
|
src: url("InterDisplay-BlackItalic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-feature-values InterVariable {
|
||||||
|
@character-variant {
|
||||||
|
cv01: 1;
|
||||||
|
cv02: 2;
|
||||||
|
cv03: 3;
|
||||||
|
cv04: 4;
|
||||||
|
cv05: 5;
|
||||||
|
cv06: 6;
|
||||||
|
cv07: 7;
|
||||||
|
cv08: 8;
|
||||||
|
cv09: 9;
|
||||||
|
cv10: 10;
|
||||||
|
cv11: 11;
|
||||||
|
cv12: 12;
|
||||||
|
cv13: 13;
|
||||||
|
alt-1: 1; /* Alternate one */
|
||||||
|
alt-3: 9; /* Flat-top three */
|
||||||
|
open-4: 2; /* Open four */
|
||||||
|
open-6: 3; /* Open six */
|
||||||
|
open-9: 4; /* Open nine */
|
||||||
|
lc-l-with-tail: 5; /* Lower-case L with tail */
|
||||||
|
simplified-u: 6; /* Simplified u */
|
||||||
|
alt-double-s: 7; /* Alternate German double s */
|
||||||
|
uc-i-with-serif: 8; /* Upper-case i with serif */
|
||||||
|
uc-g-with-spur: 10; /* Capital G with spur */
|
||||||
|
single-story-a: 11; /* Single-story a */
|
||||||
|
compact-lc-f: 12; /* Compact f */
|
||||||
|
compact-lc-t: 13; /* Compact t */
|
||||||
|
}
|
||||||
|
@styleset {
|
||||||
|
ss01: 1;
|
||||||
|
ss02: 2;
|
||||||
|
ss03: 3;
|
||||||
|
ss04: 4;
|
||||||
|
ss05: 5;
|
||||||
|
ss06: 6;
|
||||||
|
ss07: 7;
|
||||||
|
ss08: 8;
|
||||||
|
open-digits: 1; /* Open digits */
|
||||||
|
disambiguation: 2; /* Disambiguation (with zero) */
|
||||||
|
disambiguation-except-zero: 4; /* Disambiguation (no zero) */
|
||||||
|
round-quotes-and-commas: 3; /* Round quotes & commas */
|
||||||
|
square-punctuation: 7; /* Square punctuation */
|
||||||
|
square-quotes: 8; /* Square quotes */
|
||||||
|
circled-characters: 5; /* Circled characters */
|
||||||
|
squared-characters: 6; /* Squared characters */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@font-feature-values Inter {
|
||||||
|
@character-variant {
|
||||||
|
cv01: 1;
|
||||||
|
cv02: 2;
|
||||||
|
cv03: 3;
|
||||||
|
cv04: 4;
|
||||||
|
cv05: 5;
|
||||||
|
cv06: 6;
|
||||||
|
cv07: 7;
|
||||||
|
cv08: 8;
|
||||||
|
cv09: 9;
|
||||||
|
cv10: 10;
|
||||||
|
cv11: 11;
|
||||||
|
cv12: 12;
|
||||||
|
cv13: 13;
|
||||||
|
alt-1: 1; /* Alternate one */
|
||||||
|
alt-3: 9; /* Flat-top three */
|
||||||
|
open-4: 2; /* Open four */
|
||||||
|
open-6: 3; /* Open six */
|
||||||
|
open-9: 4; /* Open nine */
|
||||||
|
lc-l-with-tail: 5; /* Lower-case L with tail */
|
||||||
|
simplified-u: 6; /* Simplified u */
|
||||||
|
alt-double-s: 7; /* Alternate German double s */
|
||||||
|
uc-i-with-serif: 8; /* Upper-case i with serif */
|
||||||
|
uc-g-with-spur: 10; /* Capital G with spur */
|
||||||
|
single-story-a: 11; /* Single-story a */
|
||||||
|
compact-lc-f: 12; /* Compact f */
|
||||||
|
compact-lc-t: 13; /* Compact t */
|
||||||
|
}
|
||||||
|
@styleset {
|
||||||
|
ss01: 1;
|
||||||
|
ss02: 2;
|
||||||
|
ss03: 3;
|
||||||
|
ss04: 4;
|
||||||
|
ss05: 5;
|
||||||
|
ss06: 6;
|
||||||
|
ss07: 7;
|
||||||
|
ss08: 8;
|
||||||
|
open-digits: 1; /* Open digits */
|
||||||
|
disambiguation: 2; /* Disambiguation (with zero) */
|
||||||
|
disambiguation-except-zero: 4; /* Disambiguation (no zero) */
|
||||||
|
round-quotes-and-commas: 3; /* Round quotes & commas */
|
||||||
|
square-punctuation: 7; /* Square punctuation */
|
||||||
|
square-quotes: 8; /* Square quotes */
|
||||||
|
circled-characters: 5; /* Circled characters */
|
||||||
|
squared-characters: 6; /* Squared characters */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@font-feature-values InterDisplay {
|
||||||
|
@character-variant {
|
||||||
|
cv01: 1;
|
||||||
|
cv02: 2;
|
||||||
|
cv03: 3;
|
||||||
|
cv04: 4;
|
||||||
|
cv05: 5;
|
||||||
|
cv06: 6;
|
||||||
|
cv07: 7;
|
||||||
|
cv08: 8;
|
||||||
|
cv09: 9;
|
||||||
|
cv10: 10;
|
||||||
|
cv11: 11;
|
||||||
|
cv12: 12;
|
||||||
|
cv13: 13;
|
||||||
|
alt-1: 1; /* Alternate one */
|
||||||
|
alt-3: 9; /* Flat-top three */
|
||||||
|
open-4: 2; /* Open four */
|
||||||
|
open-6: 3; /* Open six */
|
||||||
|
open-9: 4; /* Open nine */
|
||||||
|
lc-l-with-tail: 5; /* Lower-case L with tail */
|
||||||
|
simplified-u: 6; /* Simplified u */
|
||||||
|
alt-double-s: 7; /* Alternate German double s */
|
||||||
|
uc-i-with-serif: 8; /* Upper-case i with serif */
|
||||||
|
uc-g-with-spur: 10; /* Capital G with spur */
|
||||||
|
single-story-a: 11; /* Single-story a */
|
||||||
|
compact-lc-f: 12; /* Compact f */
|
||||||
|
compact-lc-t: 13; /* Compact t */
|
||||||
|
}
|
||||||
|
@styleset {
|
||||||
|
ss01: 1;
|
||||||
|
ss02: 2;
|
||||||
|
ss03: 3;
|
||||||
|
ss04: 4;
|
||||||
|
ss05: 5;
|
||||||
|
ss06: 6;
|
||||||
|
ss07: 7;
|
||||||
|
ss08: 8;
|
||||||
|
open-digits: 1; /* Open digits */
|
||||||
|
disambiguation: 2; /* Disambiguation (with zero) */
|
||||||
|
disambiguation-except-zero: 4; /* Disambiguation (no zero) */
|
||||||
|
round-quotes-and-commas: 3; /* Round quotes & commas */
|
||||||
|
square-punctuation: 7; /* Square punctuation */
|
||||||
|
square-quotes: 8; /* Square quotes */
|
||||||
|
circled-characters: 5; /* Circled characters */
|
||||||
|
squared-characters: 6; /* Squared characters */
|
||||||
|
}
|
||||||
|
}
|
BIN
packages/next/app/[locale]/fonts/InterFont/InterDisplay-Black.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/InterDisplay-Black.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/InterDisplay-BlackItalic.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/InterDisplay-BlackItalic.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/next/app/[locale]/fonts/InterFont/InterDisplay-Bold.woff2
(Stored with Git LFS)
Normal file
BIN
packages/next/app/[locale]/fonts/InterFont/InterDisplay-Bold.woff2
(Stored with Git LFS)
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user