diff --git a/.tokeignore b/.tokeignore index f4e0597..b123ac9 100644 --- a/.tokeignore +++ b/.tokeignore @@ -5,4 +5,7 @@ data *.md *config* Inter.css -MiSans.css \ No newline at end of file +MiSans.css +*.yaml +*.yml +*.mdx diff --git a/Dockerfile.next b/Dockerfile.next new file mode 100644 index 0000000..081a8b0 --- /dev/null +++ b/Dockerfile.next @@ -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"] diff --git a/bun.lock b/bun.lock index 3147ce3..12eff82 100644 --- a/bun.lock +++ b/bun.lock @@ -14,9 +14,12 @@ }, }, "packages/backend": { - "name": "backend", + "name": "@cvsa/backend", + "version": "0.5.3", "dependencies": { + "@koshnic/ratelimit": "^1.0.3", "@rabbit-company/argon2id": "^2.1.0", + "chalk": "^5.4.1", "hono": "^4.7.8", "hono-rate-limiter": "^0.4.2", "ioredis": "^5.6.1", @@ -32,7 +35,8 @@ }, }, "packages/core": { - "name": "core", + "name": "@cvsa/core", + "version": "0.0.5", "dependencies": { "@koshnic/ratelimit": "^1.0.3", "chalk": "^5.4.1", @@ -55,6 +59,7 @@ "express": "^5.1.0", "ioredis": "^5.6.1", "onnxruntime-node": "1.19.2", + "postgres": "^3.4.5", }, "devDependencies": { "concurrently": "^9.1.2", @@ -120,7 +125,9 @@ "@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="], - "@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=="], @@ -222,8 +229,6 @@ "@ioredis/commands": ["@ioredis/commands@1.2.0", "", {}, "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg=="], - "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], - "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="], @@ -252,8 +257,6 @@ "@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="], - "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], - "@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="], "@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="], @@ -384,8 +387,6 @@ "@types/ioredis": ["@types/ioredis@5.0.0", "", { "dependencies": { "ioredis": "*" } }, "sha512-zJbJ3FVE17CNl5KXzdeSPtdltc4tMT3TzC6fxQS0sQngkbFZ6h+0uTafsRqu+eSLIugf6Yb0Ea0SUuRr42Nk9g=="], - "@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="], - "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], "@types/mocha": ["@types/mocha@10.0.10", "", {}, "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q=="], @@ -406,20 +407,6 @@ "@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/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/pretty-format": ["@vitest/pretty-format@3.1.2", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w=="], - - "@vitest/runner": ["@vitest/runner@3.1.2", "", { "dependencies": { "@vitest/utils": "3.1.2", "pathe": "^2.0.3" } }, "sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g=="], - - "@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/spy": ["@vitest/spy@3.1.2", "", { "dependencies": { "tinyspy": "^3.0.2" } }, "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA=="], - - "@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=="], - "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], "acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="], @@ -432,8 +419,6 @@ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], - "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], "argon2id": ["argon2id@1.0.1", "", {}, "sha512-rsiD3lX+0L0CsiZARp3bf9EGxprtuWAT7PpiJd+Fk53URV0/USOQkBIP1dLTV8t6aui0ECbymQ9W9YCcTd6XgA=="], @@ -444,7 +429,7 @@ "array-iterate": ["array-iterate@2.0.1", "", {}, "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg=="], - "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + "assertion-error": ["assertion-error@1.1.0", "", {}, "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="], "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=="], @@ -456,8 +441,6 @@ "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], - "backend": ["backend@workspace:packages/backend"], - "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], @@ -492,8 +475,6 @@ "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], - "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], - "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], @@ -504,7 +485,7 @@ "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], - "chai": ["chai@5.2.0", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw=="], + "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=="], "chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="], @@ -514,7 +495,7 @@ "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], - "check-error": ["check-error@2.1.1", "", {}, "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw=="], + "check-error": ["check-error@1.0.3", "", { "dependencies": { "get-func-name": "^2.0.2" } }, "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg=="], "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], @@ -546,8 +527,6 @@ "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], - "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], - "common-ancestor-path": ["common-ancestor-path@1.0.1", "", {}, "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w=="], "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], @@ -564,16 +543,12 @@ "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], - "core": ["core@workspace:packages/core"], - "crawler": ["crawler@workspace:packages/crawler"], "cron-parser": ["cron-parser@4.9.0", "", { "dependencies": { "luxon": "^3.2.1" } }, "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q=="], "cross-fetch": ["cross-fetch@3.2.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q=="], - "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=="], "css-tree": ["css-tree@3.1.0", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="], @@ -590,7 +565,7 @@ "dedent-js": ["dedent-js@1.0.1", "", {}, "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ=="], - "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], + "deep-eql": ["deep-eql@4.1.4", "", { "dependencies": { "type-detect": "^4.0.0" } }, "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg=="], "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], @@ -632,8 +607,6 @@ "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], - "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], - "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], @@ -680,8 +653,6 @@ "eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], - "expect-type": ["expect-type@1.2.1", "", {}, "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw=="], - "express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="], "express-rate-limit": ["express-rate-limit@7.5.0", "", { "peerDependencies": { "express": "^4.11 || 5 || ^5.0.0-beta.1" } }, "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg=="], @@ -712,8 +683,6 @@ "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=="], - "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=="], "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], @@ -746,8 +715,6 @@ "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - "glob-regex": ["glob-regex@0.3.2", "", {}, "sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw=="], - "global-agent": ["global-agent@3.0.0", "", { "dependencies": { "boolean": "^3.0.1", "es6-error": "^4.1.1", "matcher": "^3.0.0", "roarr": "^2.15.3", "semver": "^7.3.2", "serialize-error": "^7.0.1" } }, "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q=="], "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], @@ -850,10 +817,6 @@ "is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="], - "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], - - "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - "jake": ["jake@10.9.2", "", { "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", "filelist": "^1.0.4", "minimatch": "^3.1.2" }, "bin": { "jake": "bin/cli.js" } }, "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA=="], "jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="], @@ -862,8 +825,6 @@ "json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="], - "json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="], - "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], "kuler": ["kuler@2.0.0", "", {}, "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="], @@ -892,8 +853,6 @@ "limiter": ["limiter@3.0.0", "", {}, "sha512-hev7DuXojsTFl2YwyzUJMDnZ/qBDd3yZQLSH3aD4tdL1cqfc3TMnoecEJtWFaQFdErZsKoFMBTxF/FBSkgDbEg=="], - "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], - "locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="], "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], @@ -912,7 +871,7 @@ "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], - "loupe": ["loupe@3.1.3", "", {}, "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug=="], + "loupe": ["loupe@2.3.7", "", { "dependencies": { "get-func-name": "^2.0.1" } }, "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA=="], "lower-case": ["lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg=="], @@ -1024,8 +983,6 @@ "minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], - "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], - "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], "minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="], @@ -1042,8 +999,6 @@ "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=="], - "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], - "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], @@ -1070,8 +1025,6 @@ "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], - "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], - "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], @@ -1106,8 +1059,6 @@ "p-timeout": ["p-timeout@6.1.4", "", {}, "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg=="], - "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=="], "pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="], @@ -1122,15 +1073,9 @@ "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], - "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], - - "path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - "path-to-regexp": ["path-to-regexp@8.2.0", "", {}, "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ=="], - "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - - "pathval": ["pathval@2.0.0", "", {}, "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA=="], + "pathval": ["pathval@1.1.1", "", {}, "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ=="], "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=="], @@ -1154,8 +1099,6 @@ "picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], - "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], - "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=="], @@ -1204,8 +1147,6 @@ "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - "recrawl-sync": ["recrawl-sync@2.2.3", "", { "dependencies": { "@cush/relative": "^1.0.0", "glob-regex": "^0.3.0", "slash": "^3.0.0", "sucrase": "^3.20.3", "tslib": "^1.9.3" } }, "sha512-vSaTR9t+cpxlskkdUFrsEpnf67kSmPk66yAGT1fZPrDudxQjoMzPgQhSMImQ0pAw5k0NPirefQfhopSjhdUtpQ=="], - "redis-errors": ["redis-errors@1.2.0", "", {}, "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="], "redis-info": ["redis-info@3.1.0", "", { "dependencies": { "lodash": "^4.17.11" } }, "sha512-ER4L9Sh/vm63DkIE0bkSjxluQlioBiBgf5w1UuldaW/3vPcecdljVDisZhmnCMvsxHNiARTTDDHGg9cGwTfrKg=="], @@ -1280,10 +1221,6 @@ "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=="], - "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=="], - "shell-quote": ["shell-quote@1.8.2", "", {}, "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA=="], "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=="], @@ -1296,16 +1233,10 @@ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], - "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], - - "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - "simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="], "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], - "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], - "smol-toml": ["smol-toml@1.3.4", "", {}, "sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], @@ -1318,32 +1249,20 @@ "stack-trace": ["stack-trace@0.0.10", "", {}, "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg=="], - "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], - "standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="], "statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], - "std-env": ["std-env@3.9.0", "", {}, "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw=="], - "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], - "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], - "sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="], - "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=="], @@ -1358,26 +1277,14 @@ "text-hex": ["text-hex@1.0.0", "", {}, "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="], - "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], - - "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], - "tiny-case": ["tiny-case@1.0.3", "", {}, "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q=="], "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], - "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], - "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=="], - "tinypool": ["tinypool@1.0.2", "", {}, "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA=="], - - "tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], - - "tinyspy": ["tinyspy@3.0.2", "", {}, "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q=="], - "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], @@ -1394,12 +1301,8 @@ "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], - "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=="], - "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=="], - "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "type-detect": ["type-detect@4.1.0", "", {}, "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw=="], @@ -1468,28 +1371,18 @@ "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-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-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=="], - "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-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=="], - "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], - "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], - "which-pm-runs": ["which-pm-runs@1.1.0", "", {}, "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA=="], - "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], - "widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="], "winston": ["winston@3.17.0", "", { "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.9.0" } }, "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw=="], @@ -1500,8 +1393,6 @@ "wrap-ansi": ["wrap-ansi@9.0.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q=="], - "wrap-ansi-cjs": ["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=="], - "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], @@ -1538,14 +1429,6 @@ "@huggingface/transformers/onnxruntime-node": ["onnxruntime-node@1.21.0", "", { "dependencies": { "global-agent": "^3.0.0", "onnxruntime-common": "1.21.0", "tar": "^7.0.1" }, "os": [ "linux", "win32", "darwin", ] }, "sha512-NeaCX6WW2L8cRCSqy3bInlo5ojjQqu2fD3D+9W5qb5irwxhEyWKXeH2vZ8W9r6VxaMPUan+4/7NDwZMtouZxEw=="], - "@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], - - "@isaacs/cliui/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], - - "@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/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=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g=="], @@ -1602,12 +1485,8 @@ "readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "recrawl-sync/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], - "serialize-error/type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], - "sucrase/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], - "unified/is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], "unstorage/chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], @@ -1624,22 +1503,6 @@ "@huggingface/transformers/onnxruntime-node/onnxruntime-common": ["onnxruntime-common@1.21.0", "", {}, "sha512-Q632iLLrtCAVOTO65dh2+mNbQir/QNTVBG3h/QdZBpns7mZ0RYbLRBgGABPbpU9351AgYy7SJf1WaeVwMrBFPQ=="], - "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], - - "@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], - - "@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], - - "@koshnic/ratelimit/chai/assertion-error": ["assertion-error@1.1.0", "", {}, "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="], - - "@koshnic/ratelimit/chai/check-error": ["check-error@1.0.3", "", { "dependencies": { "get-func-name": "^2.0.2" } }, "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg=="], - - "@koshnic/ratelimit/chai/deep-eql": ["deep-eql@4.1.4", "", { "dependencies": { "type-detect": "^4.0.0" } }, "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg=="], - - "@koshnic/ratelimit/chai/loupe": ["loupe@2.3.7", "", { "dependencies": { "get-func-name": "^2.0.1" } }, "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA=="], - - "@koshnic/ratelimit/chai/pathval": ["pathval@1.1.1", "", {}, "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ=="], - "astro/sharp/@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], "astro/sharp/@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="], @@ -1706,8 +1569,6 @@ "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=="], - "unstorage/chokidar/readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], "widest-line/string-width/emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="], diff --git a/packages/backend/lib/auth/getJWTsecret.ts b/packages/backend/lib/auth/getJWTsecret.ts index 9388892..7c30faa 100644 --- a/packages/backend/lib/auth/getJWTsecret.ts +++ b/packages/backend/lib/auth/getJWTsecret.ts @@ -5,9 +5,10 @@ export const getJWTsecret = () => { if (!secret) { const response: ErrorResponse = { message: "JWT_SECRET is not set", - code: "SERVER_ERROR" + code: "SERVER_ERROR", + errors: [] }; return [response, true]; } return [secret, null]; -} \ No newline at end of file +}; diff --git a/packages/backend/middleware/captcha.ts b/packages/backend/middleware/captcha.ts index 7f9e55e..60b0d40 100644 --- a/packages/backend/middleware/captcha.ts +++ b/packages/backend/middleware/captcha.ts @@ -4,7 +4,7 @@ import { SlidingWindow } from "@core/mq/slidingWindow.ts"; import { getCaptchaConfigMaxDuration, getCurrentCaptchaDifficulty } from "@/lib/auth/captchaDifficulty.ts"; import { sqlCred } from "@core/db/dbNew.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 { getJWTsecret } from "@/lib/auth/getJWTsecret.ts"; import { lockManager } from "@core/mq/lockManager.ts"; @@ -23,7 +23,8 @@ export const captchaMiddleware = async (c: Context, next: Next) => { if (!authHeader) { const response: ErrorResponse = { message: "'Authorization' header is missing.", - code: "UNAUTHORIZED" + code: "UNAUTHORIZED", + errors: [] }; return c.json(response, 401); } @@ -32,7 +33,8 @@ export const captchaMiddleware = async (c: Context, next: Next) => { if (!authIsBearer || authHeader.length < 8) { const response: ErrorResponse = { message: "'Authorization' header is invalid.", - code: "INVALID_HEADER" + code: "INVALID_HEADER", + errors: [] }; return c.json(response, 400); } @@ -60,47 +62,48 @@ export const captchaMiddleware = async (c: Context, next: Next) => { if (consumed) { const response: ErrorResponse = { message: "Token has already been used.", - code: "INVALID_CREDENTIALS" + code: "INVALID_CREDENTIALS", + errors: [] }; return c.json(response, 401); } if (difficulty < requiredDifficulty) { const response: ErrorResponse = { message: "Token too weak.", - code: "UNAUTHORIZED" + code: "UNAUTHORIZED", + errors: [] }; return c.json(response, 401); } const EXPIRE_FIVE_MINUTES = 300; await lockManager.acquireLock(tokenID, EXPIRE_FIVE_MINUTES); - } - catch (e) { + } catch (e) { if (e instanceof JwtTokenInvalid) { const response: ErrorResponse = { message: "Failed to verify the token.", - code: "INVALID_CREDENTIALS" + code: "INVALID_CREDENTIALS", + errors: [] }; return c.json(response, 400); - } - else if (e instanceof JwtTokenExpired) { + } else if (e instanceof JwtTokenExpired) { const response: ErrorResponse = { message: "Token expired.", - code: "INVALID_CREDENTIALS" + code: "INVALID_CREDENTIALS", + errors: [] }; return c.json(response, 400); - } - else if (e instanceof ValidationError) { + } else if (e instanceof ValidationError) { const response: ErrorResponse = { code: "INVALID_QUERY_PARAMS", message: "Invalid query parameters", errors: e.errors }; return c.json(response, 400); - } - else { + } else { const response: ErrorResponse = { message: "Unknown error.", - code: "UNKNOWN_ERROR" + code: "UNKNOWN_ERROR", + errors: [] }; return c.json(response, 500); } @@ -114,4 +117,4 @@ export const captchaMiddleware = async (c: Context, next: Next) => { await window.event(`captcha-${identifierWithIP}`); await next(); -}; \ No newline at end of file +}; diff --git a/packages/backend/middleware/index.ts b/packages/backend/middleware/index.ts index 6f8e411..0cd2a9d 100644 --- a/packages/backend/middleware/index.ts +++ b/packages/backend/middleware/index.ts @@ -1,4 +1,4 @@ -import { Hono } from "hono"; +import { Context, Hono } from "hono"; import { Variables } from "hono/types"; import { bodyLimitForPing } from "./bodyLimits.ts"; import { pingHandler } from "routes/ping"; @@ -8,8 +8,21 @@ import { logger } from "./logger.ts"; import { timing } from "hono/timing"; import { contentType } from "./contentType.ts"; import { captchaMiddleware } from "./captcha.ts"; +import { cors } from "hono/cors"; export function configureMiddleWares(app: Hono<{ Variables: Variables }>) { + app.use("*", async (c, next) => { + if (c.req.path === "/user") { + const corsMiddlewareHandler = cors({ + origin: c.req.header("Origin"), + credentials: true + }); + return corsMiddlewareHandler(c, next); + } + const corsMiddlewareHandler = cors(); + return corsMiddlewareHandler(c, next); + }); + app.use("*", contentType); app.use(timing()); app.use("*", preetifyResponse); diff --git a/packages/backend/middleware/rateLimiters.ts b/packages/backend/middleware/rateLimiters.ts index 53c4115..00531f7 100644 --- a/packages/backend/middleware/rateLimiters.ts +++ b/packages/backend/middleware/rateLimiters.ts @@ -6,8 +6,8 @@ import { RateLimiter } from "@koshnic/ratelimit"; import { ErrorResponse } from "@/src/schema"; import { redis } from "@core/db/redis.ts"; -export const getIdentifier = (c: Context, includeIP: boolean = true) => { - let ipAddr = generateRandomId(6); +export const getUserIP = (c: Context) => { + let ipAddr = null; const info = getConnInfo(c); if (info.remote && info.remote.address) { ipAddr = info.remote.address; @@ -16,6 +16,14 @@ export const getIdentifier = (c: Context, includeIP: boolean = true) => { if (forwardedFor) { 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 method = c.req.method; const ipIdentifier = includeIP ? `@${ipAddr}` : ""; @@ -35,10 +43,11 @@ export const registerRateLimiter = async (c: Context, nex if (!allowed) { const response: ErrorResponse = { message: `Too many requests, please retry after ${Math.round(retryAfter)} seconds.`, - code: "RATE_LIMIT_EXCEEDED" + code: "RATE_LIMIT_EXCEEDED", + errors: [] }; return c.json(response, 429); } await next(); -}; \ No newline at end of file +}; diff --git a/packages/backend/package.json b/packages/backend/package.json index 2cc883d..a368376 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,12 +1,17 @@ { - "name": "backend", + "name": "@cvsa/backend", + "private": false, + "version": "0.5.3", "scripts": { "format": "prettier --write .", "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": { + "@koshnic/ratelimit": "^1.0.3", "@rabbit-company/argon2id": "^2.1.0", + "chalk": "^5.4.1", "hono": "^4.7.8", "hono-rate-limiter": "^0.4.2", "ioredis": "^5.6.1", @@ -19,5 +24,7 @@ "devDependencies": { "@types/bun": "^1.2.11", "prettier": "^3.5.3" - } + }, + "main": "./dist/main.js", + "types": "./src/types.d.ts" } diff --git a/packages/backend/routes/captcha/[id]/result/GET.ts b/packages/backend/routes/captcha/[id]/result/GET.ts index 25d307c..0c9c2e4 100644 --- a/packages/backend/routes/captcha/[id]/result/GET.ts +++ b/packages/backend/routes/captcha/[id]/result/GET.ts @@ -2,7 +2,7 @@ import { Context } from "hono"; import { Bindings, BlankEnv } from "hono/types"; import { ErrorResponse } from "src/schema"; import { createHandlers } from "src/utils.ts"; -import { sign } from 'hono/jwt' +import { sign } from "hono/jwt"; import { generateRandomId } from "@core/lib/randomID.ts"; import { getJWTsecret } from "lib/auth/getJWTsecret.ts"; @@ -34,7 +34,8 @@ export const verifyChallengeHandler = createHandlers( if (!ans) { const response: ErrorResponse = { message: "Missing required query parameter: ans", - code: "INVALID_QUERY_PARAMS" + code: "INVALID_QUERY_PARAMS", + errors: [] }; return c.json(response, 400); } @@ -43,26 +44,33 @@ export const verifyChallengeHandler = createHandlers( if (data.error && res.status === 404) { const response: ErrorResponse = { message: data.error, - code: "ENTITY_NOT_FOUND" + code: "ENTITY_NOT_FOUND", + i18n: { + key: "backend.error.captcha_not_found" + }, + errors: [] }; return c.json(response, 401); } else if (data.error && res.status === 400) { const response: ErrorResponse = { message: data.error, - code: "INVALID_QUERY_PARAMS" + code: "INVALID_QUERY_PARAMS", + errors: [] }; return c.json(response, 400); } else if (data.error) { const response: ErrorResponse = { message: data.error, - code: "UNKNOWN_ERROR" + code: "UNKNOWN_ERROR", + errors: [] }; return c.json(response, 500); } if (!data.success) { const response: ErrorResponse = { message: "Incorrect answer", - code: "INVALID_CREDENTIALS" + code: "INVALID_CREDENTIALS", + errors: [] }; return c.json(response, 401); } @@ -74,13 +82,16 @@ export const verifyChallengeHandler = createHandlers( const jwtSecret = r as string; 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 jwt = await sign({ - difficulty: data.difficulty!, - id: tokenID, - exp: FIVE_MINUTES_LATER - }, jwtSecret); + const jwt = await sign( + { + difficulty: data.difficulty!, + id: tokenID, + exp: FIVE_MINUTES_LATER + }, + jwtSecret + ); return c.json({ token: jwt }); diff --git a/packages/backend/routes/captcha/difficulty/GET.ts b/packages/backend/routes/captcha/difficulty/GET.ts index 0bed7cc..ce1d339 100644 --- a/packages/backend/routes/captcha/difficulty/GET.ts +++ b/packages/backend/routes/captcha/difficulty/GET.ts @@ -16,12 +16,13 @@ export const getCaptchaDifficultyHandler = createHandlers(async (c) => { if (!difficulty) { const response: ErrorResponse = { code: "ENTITY_NOT_FOUND", - message: "No difficulty configs found for this route." + message: "No difficulty configs found for this route.", + errors: [] }; return c.json>(response, 404); } return c.json({ - "difficulty": difficulty + difficulty: difficulty }); } catch (e: unknown) { if (e instanceof ValidationError) { diff --git a/packages/backend/routes/captcha/index.ts b/packages/backend/routes/captcha/index.ts index fa6d476..90b27e5 100644 --- a/packages/backend/routes/captcha/index.ts +++ b/packages/backend/routes/captcha/index.ts @@ -1,2 +1,2 @@ export * from "./session/POST.ts"; -export * from "./[id]/result/GET.ts"; \ No newline at end of file +export * from "./[id]/result/GET.ts"; diff --git a/packages/backend/routes/captcha/session/POST.ts b/packages/backend/routes/captcha/session/POST.ts index 2686a77..0836368 100644 --- a/packages/backend/routes/captcha/session/POST.ts +++ b/packages/backend/routes/captcha/session/POST.ts @@ -2,58 +2,50 @@ import { createHandlers } from "src/utils.ts"; import { getCurrentCaptchaDifficulty } from "@/lib/auth/captchaDifficulty.ts"; import { sqlCred } from "@core/db/dbNew.ts"; 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"; 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 baseURL = process.env["UCAPTCHA_URL"]; - const url = new URL(baseURL); - url.pathname = "/challenge"; - return await fetch(url.toString(), { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - difficulty: difficulty, - }) - }); -} + const baseURL = process.env["UCAPTCHA_URL"]; + const url = new URL(baseURL); + url.pathname = "/challenge"; + return await fetch(url.toString(), { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + difficulty: difficulty + }) + }); +}; export const createCaptchaSessionHandler = createHandlers(async (c) => { - try { - const requestBody = await bodySchema.validate(await c.req.json()); - const { route } = requestBody; - const difficuly = await getCurrentCaptchaDifficulty(sqlCred, route) - const res = await createNewChallenge(difficuly); - return c.json(await res.json(), res.status as ContentfulStatusCode); - } catch (e: unknown) { - if (e instanceof ValidationError) { - const response: ErrorResponse = { - code: "INVALID_QUERY_PARAMS", - message: "Invalid query parameters", - errors: e.errors - }; - return c.json(response, 400); - } else { - const response: ErrorResponse = { - code: "UNKNOWN_ERROR", - message: "Unknown error", - errors: [e] - }; - return c.json>(response, 500); - } - } + try { + const requestBody = await bodySchema.validate(await c.req.json()); + const { route } = requestBody; + const difficuly = await getCurrentCaptchaDifficulty(sqlCred, route); + const res = await createNewChallenge(difficuly); + return c.json(await res.json(), res.status as ContentfulStatusCode); + } catch (e: unknown) { + if (e instanceof ValidationError) { + const response: ErrorResponse = { + code: "INVALID_QUERY_PARAMS", + message: "Invalid query parameters", + errors: e.errors + }; + return c.json(response, 400); + } else { + const response: ErrorResponse = { + code: "UNKNOWN_ERROR", + message: "Unknown error", + errors: [e] + }; + return c.json>(response, 500); + } + } }); diff --git a/packages/backend/routes/user/POST.ts b/packages/backend/routes/user/POST.ts new file mode 100644 index 0000000..bc72514 --- /dev/null +++ b/packages/backend/routes/user/POST.ts @@ -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; + +export const userExists = async (username: string) => { + const result = await sqlCred` + SELECT 1 + FROM users + WHERE username = ${username} + `; + return result.length > 0; +}; + +const createLoginSession = async (uid: number, ua?: string, ip?: string): Promise => { + const ip_address = ip || null; + const user_agent = ua || 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', ${ip_address}, ${user_agent}) + `; + 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(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 = { + 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>(response, 500); + } + + const sessionID = await createLoginSession(uid, c.req.header("User-Agent"), getUserIP(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(response, 201); + } catch (e) { + if (e instanceof ValidationError) { + const response: ErrorResponse = { + message: "Invalid registration data.", + errors: e.errors, + code: "INVALID_PAYLOAD" + }; + return c.json>(response, 400); + } else if (e instanceof SyntaxError) { + const response: ErrorResponse = { + message: "Invalid JSON payload.", + errors: [e.message], + code: "INVALID_FORMAT" + }; + return c.json>(response, 400); + } else { + const response: ErrorResponse = { + message: "Unknown error.", + errors: [(e as Error).message], + code: "UNKNOWN_ERROR" + }; + return c.json>(response, 500); + } + } +}); diff --git a/packages/backend/routes/user/index.ts b/packages/backend/routes/user/index.ts index d9f7bf7..2cf5602 100644 --- a/packages/backend/routes/user/index.ts +++ b/packages/backend/routes/user/index.ts @@ -1 +1,2 @@ -export * from "./register.ts"; +export * from "./POST.ts"; +export * from "./session/[id]/GET.ts"; diff --git a/packages/backend/routes/user/register.ts b/packages/backend/routes/user/register.ts deleted file mode 100644 index d774b56..0000000 --- a/packages/backend/routes/user/register.ts +++ /dev/null @@ -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; - -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(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(response, 201); - } catch (e) { - if (e instanceof ValidationError) { - const response: ErrorResponse = { - message: "Invalid registration data.", - errors: e.errors, - code: "INVALID_PAYLOAD" - }; - return c.json>(response, 400); - } else if (e instanceof SyntaxError) { - const response: ErrorResponse = { - message: "Invalid JSON payload.", - errors: [e.message], - code: "INVALID_FORMAT" - }; - return c.json>(response, 400); - } else { - const response: ErrorResponse = { - message: "Unknown error.", - errors: [(e as Error).message], - code: "UNKNOWN_ERROR" - }; - return c.json>(response, 500); - } - } -}); diff --git a/packages/backend/routes/user/session/[id]/GET.ts b/packages/backend/routes/user/session/[id]/GET.ts new file mode 100644 index 0000000..78b9c3d --- /dev/null +++ b/packages/backend/routes/user/session/[id]/GET.ts @@ -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) => { + const id = c.req.param("id"); + const users = await sqlCred` + 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(response, 404); + } + const user = users[0]; + return c.json({ + username: user.username, + nickname: user.nickname, + role: user.role + }); + } +); diff --git a/packages/backend/src/main.ts b/packages/backend/src/main.ts index 61ababf..52acbde 100644 --- a/packages/backend/src/main.ts +++ b/packages/backend/src/main.ts @@ -15,4 +15,4 @@ configureRoutes(app); await startServer(app); -export const VERSION = "0.4.6"; +export const VERSION = "0.5.2"; diff --git a/packages/backend/src/routing.ts b/packages/backend/src/routing.ts index d5a7aa2..ee3886b 100644 --- a/packages/backend/src/routing.ts +++ b/packages/backend/src/routing.ts @@ -1,23 +1,23 @@ import { rootHandler } from "routes"; import { pingHandler } from "routes/ping"; -import { registerHandler } from "routes/user"; +import { getUserByLoginSessionHandler, registerHandler } from "routes/user"; import { videoInfoHandler, getSnapshotsHanlder } from "routes/video"; import { Hono } from "hono"; import { Variables } from "hono/types"; import { createCaptchaSessionHandler, verifyChallengeHandler } from "routes/captcha"; -import { getCaptchaDifficultyHandler } from "../routes/captcha/difficulty/GET.ts"; +import { getCaptchaDifficultyHandler } from "routes/captcha/difficulty/GET.ts"; export function configureRoutes(app: Hono<{ Variables: Variables }>) { app.get("/", ...rootHandler); app.all("/ping", ...pingHandler); app.get("/video/:id/snapshots", ...getSnapshotsHanlder); - app.post("/user", ...registerHandler); - app.get("/video/:id/info", ...videoInfoHandler); + app.post("/user", ...registerHandler); + app.get("/user/session/:id", ...getUserByLoginSessionHandler); + app.post("/captcha/session", ...createCaptchaSessionHandler); app.get("/captcha/:id/result", ...verifyChallengeHandler); - - app.get("/captcha/difficulty", ...getCaptchaDifficultyHandler) + app.get("/captcha/difficulty", ...getCaptchaDifficultyHandler); } diff --git a/packages/backend/src/schema.d.ts b/packages/backend/src/schema.d.ts index 5b16743..e753764 100644 --- a/packages/backend/src/schema.d.ts +++ b/packages/backend/src/schema.d.ts @@ -1,4 +1,4 @@ -type ErrorCode = +export type ErrorCode = | "INVALID_QUERY_PARAMS" | "UNKNOWN_ERROR" | "INVALID_PAYLOAD" @@ -9,14 +9,50 @@ type ErrorCode = | "INVALID_CREDENTIALS" | "ENTITY_NOT_FOUND" | "SERVER_ERROR" - | "RATE_LIMIT_EXCEEDED"; + | "RATE_LIMIT_EXCEEDED" + | "ENTITY_EXISTS"; -export interface ErrorResponse { +export interface ErrorResponse { code: ErrorCode; message: string; - errors?: E[]; + errors: E[] = []; + i18n?: { + key: string; + values?: { + [key: string]: string | number | Date; + }; + }; } export interface StatusResponse { message: string; } + +export type CaptchaSessionResponse = ErrorResponse | CaptchaSessionRawResponse; + +interface CaptchaSessionRawResponse { + success: boolean; + id: string; + g: string; + n: string; + t: number; +} + +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; diff --git a/packages/backend/src/types.d.ts b/packages/backend/src/types.d.ts new file mode 100644 index 0000000..686fbd9 --- /dev/null +++ b/packages/backend/src/types.d.ts @@ -0,0 +1 @@ +export * from "./schema"; diff --git a/packages/core/db/pgConfigNew.ts b/packages/core/db/pgConfigNew.ts index 7edfc92..2180ae1 100644 --- a/packages/core/db/pgConfigNew.ts +++ b/packages/core/db/pgConfigNew.ts @@ -1,8 +1,8 @@ const requiredEnvVars = ["DB_HOST", "DB_NAME", "DB_USER", "DB_PASSWORD", "DB_PORT", "DB_NAME_CRED"]; 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); diff --git a/packages/core/db/schema.d.ts b/packages/core/db/schema.d.ts index f10c8bc..c25ddcf 100644 --- a/packages/core/db/schema.d.ts +++ b/packages/core/db/schema.d.ts @@ -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 { id: number; uid: number; @@ -53,3 +40,27 @@ export interface SnapshotScheduleType { finished_at?: 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; +} diff --git a/packages/core/db/videoSnapshot.ts b/packages/core/db/videoSnapshot.ts deleted file mode 100644 index eeabd58..0000000 --- a/packages/core/db/videoSnapshot.ts +++ /dev/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(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(query, [bv, limit, offset]); - return queryResult.rows; -} diff --git a/packages/core/index.ts b/packages/core/index.ts new file mode 100644 index 0000000..a627c87 --- /dev/null +++ b/packages/core/index.ts @@ -0,0 +1 @@ +export * from "./db/dbNew"; diff --git a/packages/core/main.ts b/packages/core/main.ts deleted file mode 100644 index f96466e..0000000 --- a/packages/core/main.ts +++ /dev/null @@ -1 +0,0 @@ -export const DB_VERSION = 10; diff --git a/packages/core/package.json b/packages/core/package.json index f8ada58..f632410 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,10 @@ { - "name": "core", + "name": "@cvsa/core", + "private": false, + "version": "0.0.5", "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": { "@koshnic/ratelimit": "^1.0.3", @@ -13,5 +16,7 @@ }, "devDependencies": { "@types/ioredis": "^5.0.0" - } + }, + "main": "./dist/index.js", + "types": "./types.d.ts" } diff --git a/packages/core/types.d.ts b/packages/core/types.d.ts new file mode 100644 index 0000000..24322bb --- /dev/null +++ b/packages/core/types.d.ts @@ -0,0 +1,2 @@ +export * from "./db/schema"; +export * from "./index"; diff --git a/packages/crawler/db/bilibili_metadata.ts b/packages/crawler/db/bilibili_metadata.ts index f50c888..b6b363f 100644 --- a/packages/crawler/db/bilibili_metadata.ts +++ b/packages/crawler/db/bilibili_metadata.ts @@ -1,5 +1,5 @@ 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"; export async function videoExistsInAllData(sql: Psql, aid: number) { @@ -32,7 +32,7 @@ export async function insertVideoLabel(sql: Psql, aid: number, label: number) { export async function getVideoInfoFromAllData(sql: Psql, aid: number) { const rows = await sql` SELECT * FROM bilibili_metadata WHERE aid = ${aid} - `; + `; const row = rows[0]; let authorInfo = ""; if (row.uid && (await userExistsInBiliUsers(sql, row.uid))) { diff --git a/packages/crawler/package.json b/packages/crawler/package.json index 9e84eb1..dfdfcd1 100644 --- a/packages/crawler/package.json +++ b/packages/crawler/package.json @@ -20,6 +20,7 @@ "bullmq": "^5.52.1", "express": "^5.1.0", "ioredis": "^5.6.1", + "postgres": "^3.4.5", "onnxruntime-node": "1.19.2" } } diff --git a/packages/frontend/src/components/Dialog.svelte b/packages/frontend/src/components/Dialog.svelte new file mode 100644 index 0000000..fd9d191 --- /dev/null +++ b/packages/frontend/src/components/Dialog.svelte @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/packages/frontend/src/components/NavigationDrawer.svelte b/packages/frontend/src/components/NavigationDrawer.svelte index 404c883..a13ebf2 100644 --- a/packages/frontend/src/components/NavigationDrawer.svelte +++ b/packages/frontend/src/components/NavigationDrawer.svelte @@ -6,7 +6,6 @@ export let show: boolean = false; export let onClose: () => void; - let drawer: HTMLDivElement; let cover: HTMLDivElement; onMount(() => { @@ -27,19 +26,17 @@
{#if show} {/if} diff --git a/packages/frontend/src/components/Portal.svelte b/packages/frontend/src/components/Portal.svelte new file mode 100644 index 0000000..a838ebd --- /dev/null +++ b/packages/frontend/src/components/Portal.svelte @@ -0,0 +1,8 @@ + + +
+ +
\ No newline at end of file diff --git a/packages/frontend/src/components/RegisterPage/RegisterForm.svelte b/packages/frontend/src/components/RegisterPage/RegisterForm.svelte new file mode 100644 index 0000000..c01471d --- /dev/null +++ b/packages/frontend/src/components/RegisterPage/RegisterForm.svelte @@ -0,0 +1,78 @@ + + +
+ + + + + \ No newline at end of file diff --git a/packages/frontend/src/components/TextField.svelte b/packages/frontend/src/components/TextField.svelte new file mode 100644 index 0000000..66b649c --- /dev/null +++ b/packages/frontend/src/components/TextField.svelte @@ -0,0 +1,72 @@ + + +
+
+
+
+ +
+ + {labelText} + +
+ +
+
+ + focus = true} + onblur={() => focus = false} + oninput={onValueChange} + type={type} + /> +
+ {#if supportingText || maxChar} +
+ {#if supportingText} + + {supportingText} + + {/if} + {#if maxChar} + + {inputText.length}/{maxChar} + + {/if} +
+ {/if} +
diff --git a/packages/frontend/src/components/TitleBarMobile.svelte b/packages/frontend/src/components/TitleBarMobile.svelte index 105aacc..ee1d7ff 100644 --- a/packages/frontend/src/components/TitleBarMobile.svelte +++ b/packages/frontend/src/components/TitleBarMobile.svelte @@ -9,6 +9,7 @@ import HomeIcon from "@components/icon/HomeIcon.svelte"; import InfoIcon from "@components/icon/InfoIcon.svelte"; import RegisterIcon from "@components/icon/RegisterIcon.svelte"; + import Portal from "@components/Portal.svelte"; let searchBox: SearchBox | null = null; let showSearchBox = false; @@ -19,22 +20,24 @@ } - showDrawer = false}> -
-
- - 首页 + + showDrawer = false}> +
+
+ + 首页 +
+
+ + 关于 +
+
+ + 注册 +
-
- - 关于 -
-
- - 注册 -
-
- + +
{#if !showSearchBox} diff --git a/packages/frontend/src/components/icon/LeftArrow.astro b/packages/frontend/src/components/icon/LeftArrow.astro new file mode 100644 index 0000000..975fceb --- /dev/null +++ b/packages/frontend/src/components/icon/LeftArrow.astro @@ -0,0 +1,8 @@ +--- +const { ...props } = Astro.props; +--- + + + diff --git a/packages/frontend/src/components/icon/LoadingSpinner.svelte b/packages/frontend/src/components/icon/LoadingSpinner.svelte new file mode 100644 index 0000000..bceffda --- /dev/null +++ b/packages/frontend/src/components/icon/LoadingSpinner.svelte @@ -0,0 +1,15 @@ + + +
+ + + + + + + + + +
diff --git a/packages/frontend/src/components/icon/MenuIcon.svelte b/packages/frontend/src/components/icon/MenuIcon.svelte index 1c74e68..9522247 100644 --- a/packages/frontend/src/components/icon/MenuIcon.svelte +++ b/packages/frontend/src/components/icon/MenuIcon.svelte @@ -3,18 +3,7 @@
- - - Created with Pixso. - - - - - - - + - -
diff --git a/packages/frontend/src/components/icon/RightArrow.astro b/packages/frontend/src/components/icon/RightArrow.astro index b42a138..b4dc488 100644 --- a/packages/frontend/src/components/icon/RightArrow.astro +++ b/packages/frontend/src/components/icon/RightArrow.astro @@ -2,7 +2,7 @@ const {...props} = Astro.props; --- - + \ No newline at end of file diff --git a/packages/frontend/src/lib/vdf.ts b/packages/frontend/src/lib/vdf.ts new file mode 100644 index 0000000..edd623c --- /dev/null +++ b/packages/frontend/src/lib/vdf.ts @@ -0,0 +1,113 @@ + +// Define interfaces for input and output +interface VdfProgressCallback { + (progress: number): void; +} + +interface VdfResult { + result: bigint; + time: number; // Time taken in milliseconds +} + +// The content of the Web Worker script +const workerContent = `addEventListener("message", async (event) => { + const { g, N, difficulty } = event.data; + + // Although pow is not used in the iterative VDF, it's good to keep the original worker code structure. + // The iterative computeVDFWithProgress is better for progress reporting. + function pow(base, exponent, mod) { + let result = 1n; + base = base % mod; + while (exponent > 0n) { + if (exponent % 2n === 1n) { + result = (result * base) % mod; + } + base = (base * base) % mod; + exponent = exponent / 2n; + // Using BigInt division (/) which performs integer division + } + return result; + } + + // Compute VDF iteratively to report progress + function computeVDFWithProgress(g, N, T, postProgress) { + let result = g; + let latestTime = performance.now(); + const totalSteps = T; // T is the difficulty, representing 2^T squaring steps + + for (let i = 0n; i < totalSteps; i++) { + result = (result * result) % N; + // Report progress periodically (approx. every 16ms to match typical frame rate) + if (performance.now() - latestTime > 16) { + // Calculate progress as a percentage + const progress = Number((i + 1n) * 10000n / totalSteps) / 100; // Using 10000 for better precision before dividing by 100 + postProgress(progress); + latestTime = performance.now(); + } + } + // Ensure final progress is reported + postProgress(100); + return result; + } + + const startTime = performance.now(); + // The worker computes g^(2^difficulty) mod N. The loop runs 'difficulty' times, performing squaring. + const result = computeVDFWithProgress(g, N, difficulty, (progress) => { + // Post progress back to the main thread + postMessage({ type: "progress", progress: progress }); + }); + const endTime = performance.now(); + const timeTaken = endTime - startTime; + + // Post the final result and time taken back to the main thread + postMessage({ type: "result", result: result.toString(), time: timeTaken }); +}); +`; + +/** + * Computes the Verifiable Delay Function (VDF) result g^(2^difficulty) mod N + * in a Web Worker and reports progress. + * @param g - The base (bigint). + * @param N - The modulus (bigint). + * @param difficulty - The number of squaring steps (T) (bigint). + * @param onProgress - Optional callback function to receive progress updates (0-100). + * @returns A Promise that resolves with the VDF result and time taken. + */ +export function computeVdfInWorker(g: bigint, N: bigint, difficulty: bigint, onProgress?: VdfProgressCallback): Promise { + return new Promise((resolve, reject) => { + // Create a Blob containing the worker script + const blob = new Blob([workerContent], { type: "text/javascript" }); + // Create a URL for the Blob + const workerUrl = URL.createObjectURL(blob); + // Create a new Web Worker + const worker = new Worker(workerUrl); + + // Handle messages from the worker + worker.onmessage = (event) => { + const { type, progress, result, time } = event.data; + + if (type === "progress") { + if (onProgress) { + onProgress(progress); + } + } else if (type === "result") { + // Resolve the promise with the result and time + resolve({ result: BigInt(result), time }); + // Terminate the worker and revoke the URL + worker.terminate(); + URL.revokeObjectURL(workerUrl); + } + }; + + // Handle potential errors in the worker + worker.onerror = (error) => { + reject(error); + // Terminate the worker and revoke the URL in case of error + worker.terminate(); + URL.revokeObjectURL(workerUrl); + }; + + // Post the data to the worker to start the computation + worker.postMessage({ g, N, difficulty }); + }); +} diff --git a/packages/frontend/src/pages/register/index.astro b/packages/frontend/src/pages/register/index.astro index ede0a4b..6f345d6 100644 --- a/packages/frontend/src/pages/register/index.astro +++ b/packages/frontend/src/pages/register/index.astro @@ -1,13 +1,24 @@ --- import Layout from "@layouts/Layout.astro"; import RightArrow from "@components/icon/RightArrow.astro"; +import RegisterForm from "@components/RegisterPage/RegisterForm.svelte"; +import LeftArrow from "@components/icon/LeftArrow.astro"; + +const backendURL = import.meta.env.BACKEND_URL; --- -
-
+
+
+

+ + +

欢迎

-

+

欢迎来到中 V 档案馆。
这里是中文虚拟歌手相关信息的收集站与档案馆。

@@ -15,16 +26,14 @@ import RightArrow from "@components/icon/RightArrow.astro"; 注册一个账号,
让我们一起见证中 V 的历史,现在,与未来。

-

+

已有账户? 登录 -

-

很抱歉,但您现在无法注册。

-

因为目前还没有写好啦~

-

返回首页

+
diff --git a/packages/frontend/src/pages/video/[id]/info.astro b/packages/frontend/src/pages/video/[id]/info.astro index 2b641d2..b1bf121 100644 --- a/packages/frontend/src/pages/video/[id]/info.astro +++ b/packages/frontend/src/pages/video/[id]/info.astro @@ -1,13 +1,7 @@ --- import Layout from "@layouts/Layout.astro"; import TitleBar from "@components/TitleBar.astro"; -import MetadataRow from "@components/InfoPage/MetadataRow.astro"; 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"; const { id } = Astro.params; diff --git a/packages/frontend/src/styles/content.css b/packages/frontend/src/styles/content.css index dde9717..0ae7e49 100644 --- a/packages/frontend/src/styles/content.css +++ b/packages/frontend/src/styles/content.css @@ -1,14 +1,6 @@ @import "tailwindcss"; .content { - @apply text-gray-800 dark:text-zinc-100; - - h1, - h2, - h3, - h4 { - @apply font-medium text-gray-900 dark:text-white my-4; - } h1 { @apply text-3xl; @@ -30,10 +22,6 @@ @apply my-4; } - a { - @apply text-slate-800 dark:text-sky-300 hover:underline; - } - ul { @apply list-disc list-inside my-4; } @@ -46,27 +34,6 @@ @apply my-2; } - blockquote { - @apply border-l-4 border-gray-300 pl-4 italic my-4; - } - - code { - @apply bg-gray-100 text-gray-800 rounded px-1 duration-300; - } - - pre { - @apply bg-gray-100 p-4 rounded overflow-x-auto my-4 duration-300 h-0; - } - - table { - @apply w-full border-collapse my-4; - } - - th, - td { - @apply border border-gray-300 p-2; - } - th { @apply bg-gray-200 font-medium; } diff --git a/packages/frontend/tsconfig.json b/packages/frontend/tsconfig.json index c99a382..cd25b55 100644 --- a/packages/frontend/tsconfig.json +++ b/packages/frontend/tsconfig.json @@ -7,10 +7,10 @@ "paths": { "@components/*": ["src/components/*"], "@layouts/*": ["src/layouts/*"], - "@utils/*": ["src/utils/*"], + "@lib/*": ["src/lib/*"], "@assets/*": ["src/assets/*"], "@styles": ["src/styles/*"], - "@core/*": ["../core/*"] + "@core/*": ["../core/*"], }, "verbatimModuleSyntax": true } diff --git a/packages/next/.gitignore b/packages/next/.gitignore new file mode 100644 index 0000000..e2e52e0 --- /dev/null +++ b/packages/next/.gitignore @@ -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 diff --git a/packages/next/.source/index.ts b/packages/next/.source/index.ts new file mode 100644 index 0000000..26291e0 --- /dev/null +++ b/packages/next/.source/index.ts @@ -0,0 +1,3 @@ +// @ts-nocheck -- skip type checking +import { _runtime } from "fumadocs-mdx" +import * as _source from "../source.config" \ No newline at end of file diff --git a/packages/next/.source/source.config.mjs b/packages/next/.source/source.config.mjs new file mode 100644 index 0000000..22f13ae --- /dev/null +++ b/packages/next/.source/source.config.mjs @@ -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 +}; diff --git a/packages/next/app/[locale]/about/AboutContent.tsx b/packages/next/app/[locale]/about/AboutContent.tsx new file mode 100644 index 0000000..3078076 --- /dev/null +++ b/packages/next/app/[locale]/about/AboutContent.tsx @@ -0,0 +1,8 @@ +"use client"; + +import About from "@/content/about.mdx"; +import "./content.css"; + +export default function AboutContent() { + return ; +} diff --git a/packages/next/app/[locale]/about/content.css b/packages/next/app/[locale]/about/content.css new file mode 100644 index 0000000..e41a1d6 --- /dev/null +++ b/packages/next/app/[locale]/about/content.css @@ -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; + } +} diff --git a/packages/next/app/[locale]/about/page.tsx b/packages/next/app/[locale]/about/page.tsx new file mode 100644 index 0000000..c352a67 --- /dev/null +++ b/packages/next/app/[locale]/about/page.tsx @@ -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 ( + <> +
+
+
+ +
+
+ + ); +} diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-Black.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-Black.woff2 new file mode 100644 index 0000000..89b8df9 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-Black.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12ed0eed6749099b46c7b2e8198dc30c2d7e0f2a4e5fb1d12f0b6ae2c4f33cc4 +size 111668 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-BlackItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-BlackItalic.woff2 new file mode 100644 index 0000000..71f56ab --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-BlackItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:308e101141e9dee3b6b121614da03969eb8179886975a9eeb5348021b04368fe +size 118420 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-Bold.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-Bold.woff2 new file mode 100644 index 0000000..07604e9 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-Bold.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa888127b6da015b65569f0351f3b5c391ad928904951f1c20e9f8462a8d95ea +size 114840 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-BoldItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-BoldItalic.woff2 new file mode 100644 index 0000000..ac216a9 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-BoldItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a10532d76c90c4597c0ad4bfc9284600e597d3012dd1ec16c1d44e0ad0058ab +size 121500 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraBold.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraBold.woff2 new file mode 100644 index 0000000..1f88168 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraBold.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f75025856f8db1b2186e9cb89be9de9894932c8b7b20f4df5e65916ff714e34 +size 114856 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraBoldItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraBoldItalic.woff2 new file mode 100644 index 0000000..25e52ce --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraBoldItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53bb20ba292e2ac28a0777bf0f56f31b98be432a3cc04359e2eb608c758349c7 +size 121516 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraLight.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraLight.woff2 new file mode 100644 index 0000000..1ab4d09 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraLight.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba4fc81dbb25871f1bcabc664b1e37703fca0a05f7248a923e7db497c6d211cc +size 112728 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraLightItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraLightItalic.woff2 new file mode 100644 index 0000000..e88cd22 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-ExtraLightItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38bad3a6a9ad1a7fcd8082e6423ba5e0baea16598f2cf304e527844f697e32b2 +size 119320 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-Italic.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-Italic.woff2 new file mode 100644 index 0000000..6b36b21 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-Italic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d078cb3bc8f934740d53b39dd23b0678f2f97477e49ec785dd9d8acd8b96bfc +size 117700 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-Light.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-Light.woff2 new file mode 100644 index 0000000..1feb0f1 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-Light.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e111a1e2ad914ccda9179b95e83fb10234dd52a1932e0b93c480476227983fd9 +size 112592 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-LightItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-LightItalic.woff2 new file mode 100644 index 0000000..5d65227 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-LightItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:050265b27d11860a26c66c054210852661abb5d229c4e0bb3525757a830f3790 +size 119608 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-Medium.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-Medium.woff2 new file mode 100644 index 0000000..f6354b1 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-Medium.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ff3e94614e1493eb556314fd247ae6c4a85a7783b4cc86be539940cf83f2a48 +size 114348 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-MediumItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-MediumItalic.woff2 new file mode 100644 index 0000000..f578443 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-MediumItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b0df503de488a92082a8c5d72ddc4c0229183ceb645ae1c25c2d0d63778517c +size 120784 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-Regular.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-Regular.woff2 new file mode 100644 index 0000000..cd2b9fe --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-Regular.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e06f6b1bc553aaea4e4668023ed0ab0a147129c3107f511bc7d03d361b0ae085 +size 111268 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-SemiBold.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-SemiBold.woff2 new file mode 100644 index 0000000..6d48aeb --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-SemiBold.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cb7103e4e605989afebc03d989c79201e54b21b5183db33981f70db9178a301 +size 114812 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-SemiBoldItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-SemiBoldItalic.woff2 new file mode 100644 index 0000000..89d1089 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-SemiBoldItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e2a2bc3b5b9af0644f005693b10499dab18065d6aedbf46c8b74ccede27daeb +size 121416 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-Thin.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-Thin.woff2 new file mode 100644 index 0000000..8607f76 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-Thin.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70ca998635d9fc627dede8108f04d0989e6e03346183f0ad0917723e790f6973 +size 109548 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter-ThinItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/Inter-ThinItalic.woff2 new file mode 100644 index 0000000..5637118 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter-ThinItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:930d666b74e0dc0c26c2821f5643b701f8a41beaf3bb95ce146298104f29169c +size 116880 diff --git a/packages/next/app/[locale]/fonts/InterFont/Inter.css b/packages/next/app/[locale]/fonts/InterFont/Inter.css new file mode 100644 index 0000000..b487296 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/Inter.css @@ -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 */ + } +} diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Black.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Black.woff2 new file mode 100644 index 0000000..d7dbac2 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Black.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05650cb83c70fda2a465eade0c0a1a6c25d37ec49df3cd74b7e564683f9729f1 +size 110308 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-BlackItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-BlackItalic.woff2 new file mode 100644 index 0000000..98950fe --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-BlackItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9746bf2bd43fe158144b83ede747088e80396daad55b9e6ea7232e0e22ee6fce +size 116820 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Bold.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Bold.woff2 new file mode 100644 index 0000000..c6992e4 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Bold.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23bc37619593377e128f24660fedb2869d18277b4026cb46e5637be7643faf91 +size 113556 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-BoldItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-BoldItalic.woff2 new file mode 100644 index 0000000..30c6bfb --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-BoldItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a0fe1f01b8777fab4a5f73c757743fa52579c7723b0291777625cb53c0a792a +size 120432 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraBold.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraBold.woff2 new file mode 100644 index 0000000..a426fdb --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraBold.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97eeee5a6f4f22fef1f607cf8836104d65968f03e59bc068a7586bf18364a8a7 +size 113636 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraBoldItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraBoldItalic.woff2 new file mode 100644 index 0000000..7358e69 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraBoldItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:159b72ba47887032915420aa1445ae6768197e7ea732230182998f14d1cdb932 +size 120712 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraLight.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraLight.woff2 new file mode 100644 index 0000000..f93b602 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraLight.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9031b6d2a1a559753d50b311ecb463ddf7acaaae1d992a7e9b009620d8ce6def +size 113108 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraLightItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraLightItalic.woff2 new file mode 100644 index 0000000..0c749bb --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ExtraLightItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8d7078160ef92b82c2123857c1b3aefaa4a795a44b56df5fe3edade60d81576 +size 120124 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Italic.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Italic.woff2 new file mode 100644 index 0000000..4d6a0e4 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Italic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfd398d7372b61278e1505bfbdfc5ab0f6511ef887a47a2c90c13475eae585da +size 116988 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Light.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Light.woff2 new file mode 100644 index 0000000..c1cdf65 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Light.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01dd2d491ed863177e61f6e9458813baa85453ad97b32c5c1216927d4eebfe65 +size 112976 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-LightItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-LightItalic.woff2 new file mode 100644 index 0000000..84336f7 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-LightItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59b5be56306fd353d067aa6995c2c92bc3feb3ace73684d94e3c6e73fe2beaac +size 119692 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Medium.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Medium.woff2 new file mode 100644 index 0000000..cccb58b --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Medium.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1227907684853882ad00d7f97ce9f64bc17b89a2a291a7d4ec84fccfa442934 +size 113476 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-MediumItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-MediumItalic.woff2 new file mode 100644 index 0000000..7d96b60 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-MediumItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bf254c1a65c806c019f52818add66747da83595a314112917911bcf5fa2f5c5 +size 120560 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Regular.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Regular.woff2 new file mode 100644 index 0000000..8112f1d --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Regular.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a9463a58c3e7ba1e3cd65b5dbff91a35c508ff78a104cd1121feff83efeb787 +size 108948 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-SemiBold.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-SemiBold.woff2 new file mode 100644 index 0000000..5b42dac --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-SemiBold.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9f63a82b826fb0117c92715c3a52a2d2247bc321bc39341420bf52d91e8277a +size 113772 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-SemiBoldItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-SemiBoldItalic.woff2 new file mode 100644 index 0000000..257b0fa --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-SemiBoldItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd9d78314bdd5062302a73c7e2954008bab8158304fa7ac4f0ea8977b841dccb +size 120468 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Thin.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Thin.woff2 new file mode 100644 index 0000000..18ede47 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-Thin.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21cfe42e7f1031b410e247ed199f43fc362415af81b3a8e442a97f63b4dbe327 +size 108820 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ThinItalic.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ThinItalic.woff2 new file mode 100644 index 0000000..8b58c68 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterDisplay-ThinItalic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eff21589eacf1f6a596191038d7b47b4dd2455a096b175bb3572ecb6d026a611 +size 116040 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterVariable-Italic.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterVariable-Italic.woff2 new file mode 100644 index 0000000..318e720 --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterVariable-Italic.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e564f652916db6c139570fefb9524a77c4d48f30c92928de9db19b6b5c7a262a +size 387976 diff --git a/packages/next/app/[locale]/fonts/InterFont/InterVariable.woff2 b/packages/next/app/[locale]/fonts/InterFont/InterVariable.woff2 new file mode 100644 index 0000000..e511e5e --- /dev/null +++ b/packages/next/app/[locale]/fonts/InterFont/InterVariable.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:693b77d4f32ee9b8bfc995589b5fad5e99adf2832738661f5402f9978429a8e3 +size 352240 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans VF.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans VF.woff2 new file mode 100644 index 0000000..1cd2a1d --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans VF.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09103434dc310743d51b5e66111848c75c76a00a5a5bc9e5d96200a7e63bf98b +size 11870264 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans-Bold.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans-Bold.woff2 new file mode 100644 index 0000000..69fecf9 --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans-Bold.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb86bb54661547ed95a44ec099ab75f964a0b81e256845f56feaabf27541180b +size 5067652 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans-Demibold.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans-Demibold.woff2 new file mode 100644 index 0000000..31b9d31 --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans-Demibold.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d22e2de2e994f7ad7336820129e0a27a97840d3591fdc3a0fb6ba382d7dbb569 +size 4981184 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans-ExtraLight.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans-ExtraLight.woff2 new file mode 100644 index 0000000..bc1c234 --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans-ExtraLight.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc71ed05c3044ebdb3f69a5da9e8e1e0701f172837450d21157e3998e3eecce9 +size 4733240 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans-Heavy.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans-Heavy.woff2 new file mode 100644 index 0000000..a81da0d --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans-Heavy.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7891c8eb6cffe1910f239e4fc55646f5e1767445e1802a34d5f940977f5dd9ec +size 4999800 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans-Light.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans-Light.woff2 new file mode 100644 index 0000000..f32ebaf --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans-Light.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2918bcf6864e5a255c34f0ddbec83d32f4a7db9e7dfcff03ce6591ac540d3df +size 4798348 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans-Medium.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans-Medium.woff2 new file mode 100644 index 0000000..be26a7f --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans-Medium.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abd794688489b3c3ceeb9d2f61d5d9d09ae25381f40945c3aa6d0683cd78a197 +size 4928036 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans-Normal.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans-Normal.woff2 new file mode 100644 index 0000000..98d4976 --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans-Normal.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63c882e6994b4a572173881d777962418b803dc166d41405d77dba40b2d0dcd9 +size 4868672 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans-Regular.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans-Regular.woff2 new file mode 100644 index 0000000..89feb59 --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans-Regular.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d7a4ba4faf18306e446787c1ab1bd1e90c9f27bfa937cd8eb3469c7504e563f +size 4847960 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans-Semibold.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans-Semibold.woff2 new file mode 100644 index 0000000..01869ac --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans-Semibold.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14505bb0c0db9b33fd636ae5c13e1d48ec4cdb51fe35c993a63b2629f6547819 +size 5016928 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans-Thin.woff2 b/packages/next/app/[locale]/fonts/MiSans/MiSans-Thin.woff2 new file mode 100644 index 0000000..5370b32 --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans-Thin.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8684502229233359f74b3d273d84214368b270e73a3e068678ef29738c90f2c +size 4470104 diff --git a/packages/next/app/[locale]/fonts/MiSans/MiSans.css b/packages/next/app/[locale]/fonts/MiSans/MiSans.css new file mode 100644 index 0000000..f16070f --- /dev/null +++ b/packages/next/app/[locale]/fonts/MiSans/MiSans.css @@ -0,0 +1,87 @@ +@font-face { + font-family: "MiSans VF"; + font-style: normal; + font-weight: 150 700; + font-display: fallback; + src: url("MiSans VF.woff2") format("woff2"); +} + +@font-face { + font-family: "MiSans"; + font-style: normal; + font-weight: 100; + font-display: fallback; + src: url("MiSans-Thin.woff2") format("woff2"); +} + +@font-face { + font-family: "MiSans"; + font-style: normal; + font-weight: 200; + font-display: fallback; + src: url("MiSans-ExtraLight.woff2") format("woff2"); +} + +@font-face { + font-family: "MiSans"; + font-style: normal; + font-weight: 300; + font-display: fallback; + src: url("MiSans-Light.woff2") format("woff2"); +} + +@font-face { + font-family: "MiSans"; + font-style: normal; + font-weight: 360; + font-display: fallback; + src: url("MiSans-Normal.woff2") format("woff2"); +} + +@font-face { + font-family: "MiSans"; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url("MiSans-Regular.woff2") format("woff2"); +} + +@font-face { + font-family: "MiSans"; + font-style: normal; + font-weight: 500; + font-display: fallback; + src: url("MiSans-Medium.woff2") format("woff2"); +} + +@font-face { + font-family: "MiSans"; + font-style: normal; + font-weight: 600; + font-display: fallback; + src: url("MiSans-Demibold.woff2") format("woff2"); +} + +@font-face { + font-family: "MiSans"; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url("MiSans-Semibold.woff2") format("woff2"); +} + +@font-face { + font-family: "MiSans"; + font-style: normal; + font-weight: 800; + font-display: fallback; + src: url("MiSans-Bold.woff2") format("woff2"); +} + +@font-face { + font-family: "MiSans"; + font-style: normal; + font-weight: 900; + font-display: fallback; + src: url("MiSans-Heavy.woff2") format("woff2"); +} diff --git a/packages/next/app/[locale]/global.css b/packages/next/app/[locale]/global.css new file mode 100644 index 0000000..57d07a6 --- /dev/null +++ b/packages/next/app/[locale]/global.css @@ -0,0 +1,106 @@ +@import url("./fonts/InterFont/Inter.css"); +@import url("./fonts/MiSans/MiSans.css"); + +@import "tailwindcss"; + +@theme { + --color-background: #fff8f6; + --color-on-background: #2a1613; + --color-surface: #fff8f6; + --color-surface-dim: #f7d2cc; + --color-surface-bright: #fff8f6; + --color-surface-container-lowest: #ffffff; + --color-surface-container-low: #fff0ee; + --color-surface-container: #ffe9e6; + --color-surface-container-high: #ffe2dd; + --color-surface-container-highest: #ffdad4; + --color-on-surface: #2a1613; + --color-surface-variant: #ffdad4; + --color-on-surface-variant: #5f3e39; + --color-inverse-surface: #422b27; + --color-inverse-on-surface: #ffedea; + --color-outline: #946e68; + --color-outline-variant: #eabcb4; + --color-shadow: #000000; + --color-scrim: #000000; + --color-surface-tint: #c00100; + --color-primary: #a50100; + --color-on-primary: #ffffff; + --color-primary-container: #eb0000; + --color-on-primary-container: #ffffff; + --color-inverse-primary: #ffb4a8; + --color-secondary: #b4271a; + --color-on-secondary: #ffffff; + --color-secondary-container: #ff7460; + --color-on-secondary-container: #2f0000; + --color-tertiary: #6f4800; + --color-on-tertiary: #ffffff; + --color-tertiary-container: #9f6900; + --color-on-tertiary-container: #ffffff; + --color-error: #ba1a1a; + --color-on-error: #ffffff; + --color-error-container: #ffdad6; + --color-on-error-container: #410002; + + --color-dark-background: #210e0b; + --color-dark-on-background: #ffdad4; + --color-dark-surface: #210e0b; + --color-dark-surface-dim: #210e0b; + --color-dark-surface-bright: #4b332f; + --color-dark-surface-container-lowest: #1b0907; + --color-dark-surface-container-low: #2a1613; + --color-dark-surface-container: #2f1a17; + --color-dark-surface-container-high: #3a2421; + --color-dark-surface-container-highest: #462f2b; + --color-dark-on-surface: #ffdad4; + --color-dark-surface-variant: #5f3e39; + --color-dark-on-surface-variant: #eabcb4; + --color-dark-inverse-surface: #ffdad4; + --color-dark-inverse-on-surface: #422b27; + --color-dark-outline: #b08780; + --color-dark-outline-variant: #5f3e39; + --color-dark-shadow: #000000; + --color-dark-scrim: #000000; + --color-dark-surface-tint: #ffb4a8; + --color-dark-primary: #ffb4a8; + --color-dark-on-primary: #690000; + --color-dark-primary-container: #de0000; + --color-dark-on-primary-container: #ffffff; + --color-dark-inverse-primary: #c00100; + --color-dark-secondary: #ffb4a8; + --color-dark-on-secondary: #690000; + --color-dark-secondary-container: #870100; + --color-dark-on-secondary-container: #ffc9c0; + --color-dark-tertiary: #feba54; + --color-dark-on-tertiary: #452b00; + --color-dark-tertiary-container: #966300; + --color-dark-on-tertiary-container: #ffffff; + --color-dark-error: #ffb4ab; + --color-dark-on-error: #690005; + --color-dark-error-container: #93000a; + --color-dark-on-error-container: #ffdad6; +} + +a { + @apply text-primary dark:text-dark-primary; +} + +:root { + font-family: "Inter", "MiSans", sans-serif; + font-weight: 400; + @apply bg-surface dark:bg-dark-surface text-on-surface dark:text-dark-on-surface; +} + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; + appearance: none; +} + +@supports (font-variation-settings: normal) { + :root { + font-family: "Inter Variable", "MiSans VF", sans-serif; + font-optical-sizing: auto; + font-weight: 330; + } +} diff --git a/packages/next/app/[locale]/layout.tsx b/packages/next/app/[locale]/layout.tsx new file mode 100644 index 0000000..a7cf1b5 --- /dev/null +++ b/packages/next/app/[locale]/layout.tsx @@ -0,0 +1,38 @@ +import type { Metadata } from "next"; +import "./global.css"; +import React from "react"; +import { routing } from "@/i18n/routing"; +import { NextIntlClientProvider, hasLocale } from "next-intl"; +import { notFound } from "next/navigation"; + +export const metadata: Metadata = { + title: "中V档案馆" +}; + +export default async function RootLayout({ + children, + params +}: Readonly<{ + children: React.ReactNode; + params: Promise<{ locale: string }>; +}>) { + const { locale } = await params; + if (!hasLocale(routing.locales, locale)) { + notFound(); + } + return ( + + + + + 中V档案馆 + + + + {children} +
+
+ + + ); +} diff --git a/packages/next/app/[locale]/my/profile/page.tsx b/packages/next/app/[locale]/my/profile/page.tsx new file mode 100644 index 0000000..1371b50 --- /dev/null +++ b/packages/next/app/[locale]/my/profile/page.tsx @@ -0,0 +1,17 @@ +import { Header } from "@/components/shell/Header"; +import { getCurrentUser } from "@/lib/userAuth"; +import { redirect } from "next/navigation"; + +export default async function ProfilePage() { + const user = await getCurrentUser(); + + if (!user) { + redirect("/login"); + } + + return ( + <> +
+ + ); +} diff --git a/packages/next/app/[locale]/not-found.tsx b/packages/next/app/[locale]/not-found.tsx new file mode 100644 index 0000000..1167ec5 --- /dev/null +++ b/packages/next/app/[locale]/not-found.tsx @@ -0,0 +1,5 @@ +import { NotFound } from "@/components/utils/404"; + +export default async function NotFoundPage() { + return ; +} diff --git a/packages/next/app/[locale]/page.tsx b/packages/next/app/[locale]/page.tsx new file mode 100644 index 0000000..e7241f4 --- /dev/null +++ b/packages/next/app/[locale]/page.tsx @@ -0,0 +1,17 @@ +import { Header } from "@/components/shell/Header"; +import { getCurrentUser } from "@/lib/userAuth"; + +export default async function Home() { + const user = await getCurrentUser(); + + return ( + <> +
+ +
+

正在施工中……

+

在搜索栏输入BV号或AV号,可以查询目前数据库收集到的信息~

+
+ + ); +} diff --git a/packages/next/app/[locale]/signup/ErrorDialog.tsx b/packages/next/app/[locale]/signup/ErrorDialog.tsx new file mode 100644 index 0000000..de2d7de --- /dev/null +++ b/packages/next/app/[locale]/signup/ErrorDialog.tsx @@ -0,0 +1,22 @@ +import { DialogButton, DialogButtonGroup, DialogHeadline, DialogSupportingText } from "@/components/ui/Dialog"; +import type { ErrorCode as ResponseErrorCode } from "@cvsa/backend"; +import { useTranslations } from "next-intl"; + +interface ErrorDialogProps { + children: React.ReactNode; + closeDialog: () => void; + errorCode?: ResponseErrorCode; +} + +export const ErrorDialog: React.FC = ({ children, closeDialog, errorCode }) => { + const t = useTranslations("backend.error_code"); + return ( + <> + {errorCode ? t(errorCode) : "错误"} + {children} + + 关闭 + + + ); +}; diff --git a/packages/next/app/[locale]/signup/SignUpForm.tsx b/packages/next/app/[locale]/signup/SignUpForm.tsx new file mode 100644 index 0000000..6d34286 --- /dev/null +++ b/packages/next/app/[locale]/signup/SignUpForm.tsx @@ -0,0 +1,147 @@ +"use client"; + +import { useEffect, useState } from "react"; +import TextField from "@/components/ui/TextField"; +import LoadingSpinner from "@/components/icons/LoadingSpinner"; +import { Portal } from "@/components/utils/Portal"; +import { Dialog } from "@/components/ui/Dialog"; +import { setLocale } from "yup"; +import { useTranslations } from "next-intl"; +import { useCaptcha } from "@/components/hooks/useCaptcha"; +import useSWRMutation from "swr/mutation"; +import { requestSignUp } from "./request"; +import { FilledButton } from "@/components/ui/Buttons/FilledButton"; +import { ErrorDialog } from "./ErrorDialog"; +import { ApiRequestError } from "@/lib/net"; +import { useRouter } from "next/navigation"; + +setLocale({ + mixed: { + default: "field_invalid", + required: () => ({ key: "field_required" }) + }, + string: { + min: ({ min }) => ({ key: "field_too_short", values: { min } }), + max: ({ max }) => ({ key: "field_too_big", values: { max } }) + } +}); + +export interface LocalizedMessage { + key: string; + values: { + [key: string]: number | string; + }; +} + +interface RegistrationFormProps { + backendURL: string; +} + +const SignUpForm: React.FC = ({ backendURL }) => { + const [usernameInput, setUsername] = useState(""); + const [passwordInput, setPassword] = useState(""); + const [nicknameInput, setNickname] = useState(""); + const [showDialog, setShowDialog] = useState(false); + const [dialogContent, setDialogContent] = useState(<>); + const [isLoading, setLoading] = useState(false); + const t = useTranslations(""); + const { startCaptcha, captchaResult, captchaUsed, setCaptchaUsedState, captchaError } = useCaptcha({ + backendURL, + route: "POST-/user" + }); + const { trigger } = useSWRMutation(`${backendURL}/user`, requestSignUp); + const router = useRouter(); + + const translateErrorMessage = (item: LocalizedMessage | string, path?: string) => { + if (typeof item === "string") { + return item; + } + return t(`yup_errors.${item.key}`, { ...item.values, field: path ? t(path) : "" }); + }; + + const register = async () => { + try { + if (captchaUsed || !captchaResult) { + await startCaptcha(); + } + + const result = await trigger({ + data: { + username: usernameInput, + password: passwordInput, + nickname: nicknameInput + }, + setShowDialog, + captchaResult, + setCaptchaUsedState, + translateErrorMessage, + setDialogContent, + t + }); + if (result) { + router.push("/"); + } + } finally { + setLoading(false); + } + }; + + useEffect(() => { + if (!captchaError || captchaError === undefined) return; + const err = captchaError as ApiRequestError; + setShowDialog(true); + if (err.code && err.code == -1) { + setDialogContent( + setShowDialog(false)}> +

无法连接到服务器,请检查你的网络连接后重试。

+
+ ); + } + }, [captchaError]); + + useEffect(() => { + startCaptcha(); + }, []); + + return ( +
{ + setLoading(true); + e.preventDefault(); + await register(); + }} + > + + + + + {isLoading ? : 注册} + + + {dialogContent} + + + ); +}; + +export default SignUpForm; diff --git a/packages/next/app/[locale]/signup/page.tsx b/packages/next/app/[locale]/signup/page.tsx new file mode 100644 index 0000000..d42821e --- /dev/null +++ b/packages/next/app/[locale]/signup/page.tsx @@ -0,0 +1,40 @@ +import { LeftArrow } from "@/components/icons/LeftArrow"; +import { RightArrow } from "@/components/icons/RightArrow"; +import SignUpForm from "./SignUpForm"; + +export default function SignupPage() { + return ( +
+
+

+ + +

+

欢迎

+

+ 欢迎来到中 V 档案馆。 +
+ 这里是中文虚拟歌手相关信息的收集站与档案馆。 +

+

+ 注册一个账号, +
+ 让我们一起见证中 V 的历史,现在,与未来。 +

+

+ 已有账户? + + 登录 + +

+ +
+
+ ); +} diff --git a/packages/next/app/[locale]/signup/request.tsx b/packages/next/app/[locale]/signup/request.tsx new file mode 100644 index 0000000..c763af9 --- /dev/null +++ b/packages/next/app/[locale]/signup/request.tsx @@ -0,0 +1,151 @@ +import { Dispatch, JSX, SetStateAction } from "react"; +import { ApiRequestError, fetcher } from "@/lib/net"; +import type { CaptchaVerificationRawResponse, ErrorResponse, SignUpResponse } from "@cvsa/backend"; +import { Link } from "@/i18n/navigation"; +import { LocalizedMessage } from "./SignUpForm"; +import { ErrorDialog } from "./ErrorDialog"; +import { string, object, ValidationError } from "yup"; + +interface SignUpFormData { + username: string; + password: string; + nickname?: string; +} + +const FormSchema = object().shape({ + username: string().required().max(50), + password: string().required().min(4).max(120), + nickname: string().optional().max(30) +}); + +const validateForm = async ( + data: SignUpFormData, + setShowDialog: Dispatch>, + setDialogContent: Dispatch>, + translateErrorMessage: (item: LocalizedMessage | string, path?: string) => string +): Promise => { + const { username: usernameInput, password: passwordInput, nickname: nicknameInput } = data; + try { + const formData = await FormSchema.validate( + { + username: usernameInput, + password: passwordInput, + nickname: nicknameInput + }, + { abortEarly: false } + ); + return { + username: formData.username, + password: formData.password, + nickname: formData.nickname + }; + } catch (e) { + if (!(e instanceof ValidationError)) { + return null; + } + setShowDialog(true); + setDialogContent( + setShowDialog(false)}> +

注册信息填写有误,请检查后重新提交。

+ 错误信息: +
+
    + {e.errors.map((item, i) => { + return
  1. {translateErrorMessage(item, e.inner[i].path)}
  2. ; + })} +
+
+ ); + return null; + } +}; + +interface RequestSignUpArgs { + data: SignUpFormData; + setShowDialog: Dispatch>; + setDialogContent: Dispatch>; + translateErrorMessage: (item: LocalizedMessage | string, path?: string) => string; + setCaptchaUsedState: Dispatch>; + captchaResult: CaptchaVerificationRawResponse | undefined; + t: any; +} + +export const requestSignUp = async (url: string, { arg }: { arg: RequestSignUpArgs }) => { + const { data, setShowDialog, setDialogContent, translateErrorMessage, setCaptchaUsedState, captchaResult, t } = arg; + const res = await validateForm(data, setShowDialog, setDialogContent, translateErrorMessage); + if (!res) { + return; + } + const { username, nickname, password } = res; + + try { + if (!captchaResult) { + const err = new ApiRequestError("Cannot get captcha result"); + err.response = { + code: "UNKNOWN_ERROR", + message: "Cannot get captch verifiction result", + i18n: { + key: "captcha_failed_to_get" + } + } as ErrorResponse; + throw err; + } + setCaptchaUsedState(true); + const registrationResponse = await fetcher(url, { + method: "POST", + withCredentials: true, + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${captchaResult!.token}` + }, + data: { + username: username, + password: password, + nickname: nickname + } + }); + return registrationResponse; + } catch (error) { + if (error instanceof ApiRequestError && error.response) { + const res = error.response as ErrorResponse; + setShowDialog(true); + setDialogContent( + setShowDialog(false)} errorCode={res.code}> +

无法为你注册账户。

+

+ 错误信息:
+ {res.i18n + ? t.rich(res.i18n.key, { + ...res.i18n.values, + support: (chunks: string) => {chunks} + }) + : res.message} +

+
+ ); + } else if (error instanceof Error) { + setShowDialog(true); + setDialogContent( + setShowDialog(false)}> +

无法为你注册账户。

+

+ 错误信息: +
+ {error.message} +

+
+ ); + } else { + setShowDialog(true); + setDialogContent( + setShowDialog(false)} errorCode="UNKNOWN_ERROR"> +

无法为你注册账户。

+

+ 错误信息:
+

{JSON.stringify(error)}
+

+
+ ); + } + } +}; diff --git a/packages/next/app/[locale]/song/[id]/info/page.tsx b/packages/next/app/[locale]/song/[id]/info/page.tsx new file mode 100644 index 0000000..e6e81c3 --- /dev/null +++ b/packages/next/app/[locale]/song/[id]/info/page.tsx @@ -0,0 +1,160 @@ +import { format } from "date-fns"; +import { zhCN } from "date-fns/locale"; +import { getAllSnapshots } from "@/lib/db/snapshots/getAllSnapshots"; +import { getAidFromBV } from "@/lib/db/bilibili_metadata/getAidFromBV"; +import { getVideoMetadata } from "@/lib/db/bilibili_metadata/getVideoMetadata"; +import { aidExists as idExists } from "@/lib/db/bilibili_metadata/aidExists"; +import { notFound } from "next/navigation"; +import { BiliVideoMetadataType, VideoSnapshotType } from "@cvsa/core"; + +const MetadataRow = ({ title, desc }: { title: string; desc: string | number | undefined | null }) => { + if (!desc) return <>; + return ( + + + {title} + + {desc} + + ); +}; + +export default async function VideoInfoPage({ params }: { params: Promise<{ id: string }> }) { + const { id } = await params; + let videoInfo: BiliVideoMetadataType | null = null; + let snapshots: VideoSnapshotType[] = []; + + async function getVideoAid(videoId: string | string[] | undefined) { + if (!videoId) return null; + const videoIdStr = Array.isArray(videoId) ? videoId[0] : videoId; + if (videoIdStr?.startsWith("av")) { + return parseInt(videoIdStr.slice(2)); + } else if (videoIdStr?.startsWith("BV")) { + return getAidFromBV(videoIdStr); + } + return parseInt(videoIdStr); + } + + const aid = await getVideoAid(id); + + if (!aid) { + return notFound(); + } + + const exists = await idExists(aid); + + if (!exists) { + return notFound(); + } + + try { + const videoData = await getVideoMetadata(aid); + const snapshotsData = await getAllSnapshots(aid); + videoInfo = videoData; + if (snapshotsData) { + snapshots = snapshotsData; + } + } catch (e) { + console.error(e); + } + + if (!videoInfo) { + return notFound(); + } + + return ( +
+
+

+ 视频信息:{" "} + + av{videoInfo.aid} + +

+ +
+

基本信息

+
+ + + + + + + + + + + + + + +
+
+
+ +
+

播放量历史数据

+ {snapshots && snapshots.length > 0 ? ( +
+ + + + + + + + + + + + + + + {snapshots.map((snapshot) => ( + + + + + + + + + + + ))} + +
创建时间观看硬币点赞收藏分享弹幕评论
+ {format(new Date(snapshot.created_at), "yyyy-MM-dd HH:mm:ss", { + locale: zhCN + })} + {snapshot.views}{snapshot.coins}{snapshot.likes} + {snapshot.favorites} + {snapshot.shares} + {snapshot.danmakus} + + {snapshot.replies} +
+
+ ) : ( +

暂无历史数据。

+ )} +
+
+
+ ); +} diff --git a/packages/next/app/[locale]/song/layout.tsx b/packages/next/app/[locale]/song/layout.tsx new file mode 100644 index 0000000..2fcf8e2 --- /dev/null +++ b/packages/next/app/[locale]/song/layout.tsx @@ -0,0 +1,17 @@ +import { Header } from "@/components/shell/Header"; +import { getCurrentUser } from "@/lib/userAuth"; +import React from "react"; + +export default async function RootLayout({ + children +}: Readonly<{ + children: React.ReactNode; +}>) { + const user = await getCurrentUser(); + return ( + <> +
+ {children} + + ); +} diff --git a/packages/next/app/[locale]/test-vdf/TestCard.tsx b/packages/next/app/[locale]/test-vdf/TestCard.tsx new file mode 100644 index 0000000..1acb66f --- /dev/null +++ b/packages/next/app/[locale]/test-vdf/TestCard.tsx @@ -0,0 +1,206 @@ +"use client"; + +import { N_ARRAY } from "@/lib/const"; +import { UAParser } from "ua-parser-js"; +import { useEffect, useState } from "react"; +import { computeVdfInWorker } from "@/lib/vdf"; +import { FilledButton } from "@/components/ui/Buttons/FilledButton"; + +let bigintSupported = typeof BigInt !== "undefined"; + +function generateRandomBigInt(min: bigint, max: bigint) { + const range = max - min; + const bitLength = range.toString(2).length; + const byteLength = Math.ceil(bitLength / 8); + const mask = (1n << BigInt(bitLength)) - 1n; + let result; + do { + const randomBytes = new Uint8Array(byteLength); + crypto.getRandomValues(randomBytes); + result = 0n; + for (let i = 0; i < byteLength; i++) { + result = (result << 8n) | BigInt(randomBytes[i]); + } + result = result & mask; + } while (result > range); + return min + result; +} + +function generateValidG(N: bigint) { + if (N <= 4n) throw new Error("N must be > 4"); + while (true) { + const r = generateRandomBigInt(2n, N - 1n); + const g = (r * r) % N; + if (g !== 1n && g !== 0n && g !== N - 1n) { + return g; + } + } +} + +export const VDFtestCard = () => { + const [browserInfo, setBrowserInfo] = useState(null); + const [isBenchmarking, setIsBenchmarking] = useState(false); + const [benchmarkResults, setBenchmarkResults] = useState<{ N: bigint; difficulty: bigint; time: number }[]>([]); + const [currentProgress, setCurrentProgress] = useState(0); + const [currentN, setCurrentN] = useState(null); + const [currentDifficulty, setCurrentDifficulty] = useState(null); + const [currentTestIndex, setCurrentTestIndex] = useState(0); + const difficulties = [BigInt(20000), BigInt(200000)]; + const [testCombinations, setTestCombinations] = useState<{ N: bigint; difficulty: bigint }[]>([]); + const speedSampleIndex = 1; + const [speedSample, setSpeedSample] = useState<{ N: bigint; difficulty: bigint; time: number } | undefined>( + undefined + ); + + useEffect(() => { + // 创建需要测试的 N 和难度的组合 + const combinations: { N: bigint; difficulty: bigint }[] = []; + N_ARRAY.forEach((n) => { + difficulties.forEach((difficulty) => { + combinations.push({ N: n, difficulty }); + }); + }); + setTestCombinations(combinations); + + const ua = navigator ? navigator.userAgent : ""; + const { browser } = UAParser(ua); + setBrowserInfo(browser.name + " " + browser.version); + }, []); + + async function startBenchmark() { + if (testCombinations.length === 0) { + alert("No N values provided in src/const N_ARRAY."); + return; + } + setIsBenchmarking(true); + setBenchmarkResults([]); + setCurrentTestIndex(0); + + async function runTest(index: number) { + if (index >= testCombinations.length) { + setIsBenchmarking(false); + setCurrentN(null); + setCurrentDifficulty(null); + return; + } + + const { N, difficulty } = testCombinations[index]; + const g = generateValidG(N); + + try { + const { time } = await computeVdfInWorker(g, N, difficulty, (progress) => { + setCurrentProgress(progress); + setCurrentN(N); + setCurrentDifficulty(difficulty); + }); + setBenchmarkResults((prevResults) => [...prevResults, { N, difficulty, time }]); + setCurrentProgress(0); + setCurrentTestIndex((prevIndex) => prevIndex + 1); + runTest(index + 1); + } catch (error) { + setIsBenchmarking(false); + setCurrentN(null); + setCurrentDifficulty(null); + } + } + + runTest(0); + } + + function getAccumulatedTime() { + return benchmarkResults.reduce((acc, result) => acc + result.time, 0); + } + + function calculateSpeed() { + const sample = benchmarkResults[speedSampleIndex]; + if (!sample) return 0; + return (Number(sample.difficulty) / sample.time) * 1000; + } + useEffect(() => { + if (benchmarkResults.length > speedSampleIndex) { + setSpeedSample(benchmarkResults[speedSampleIndex]); + } + }, [benchmarkResults]); + + return ( +
+

VDF 基准测试

+ + {!bigintSupported ? ( +

⚠️ 您的浏览器不支持 BigInt,无法运行基准测试。

+ ) : !isBenchmarking ? ( + + 开始测试 + + ) : null} + + {isBenchmarking && ( + <> +

+ 正在测试: {currentTestIndex + 1}/{testCombinations.length} +

+ {currentN !== null && currentDifficulty !== null && ( + <> +

密钥长度: {currentN.toString(2).length} 比特

+

难度: {currentDifficulty.toLocaleString()}

+
+
+
+
+
+ + )} + + )} + + {benchmarkResults.length > 0 && !isBenchmarking && ( + <> +

测试结果

+

+ 测试在 {(getAccumulatedTime() / 1000).toFixed(3)} 秒内完成.
+ 速度: {Math.round(calculateSpeed()).toLocaleString()} 迭代 / 秒.
+ + 速度是在 N = {speedSample?.N.toString(2).length} bits, T = {speedSample?.difficulty}{" "} + 的测试中测量的. + +
+ {browserInfo && <>浏览器版本:{browserInfo}} +

+ + + + + + + + + + {benchmarkResults.map((result) => ( + + + + + + ))} + +
+ 耗时 (ms) + + N (bits) + + T (迭代) +
{result.time.toFixed(2)}{result.N.toString(2).length}{Number(result.difficulty)}
+ + )} +
+ ); +}; diff --git a/packages/next/app/[locale]/test-vdf/page.tsx b/packages/next/app/[locale]/test-vdf/page.tsx new file mode 100644 index 0000000..e7ac071 --- /dev/null +++ b/packages/next/app/[locale]/test-vdf/page.tsx @@ -0,0 +1,47 @@ +import { Header } from "@/components/shell/Header"; +import { getCurrentUser } from "@/lib/userAuth"; +import { VDFtestCard } from "./TestCard"; + +export default async function VdfBenchmarkPage() { + const user = await getCurrentUser(); + + return ( + <> +
+
+ +
+

关于本页

+
+

+ 这是一个性能测试页面, +
+ 旨在测试我们的一个 VDF (Verifiable Delayed Function, 可验证延迟函数) 实现的性能。 +
+ 这是一个数学函数,它驱动了整个网站的验证码(CAPTCHA)。 +
+ 通过使用该函数,我们可以让您无需通过点选图片或滑动滑块既可完成验证, + 同时防御我们的网站,使其免受自动程序的攻击。 +
+

+

+ 点击按钮,会自动测试并展示结果。 +
+

+

+ 你可以将结果发送至邮箱: + contact@alikia2x.com 或 QQ: + 1559913735,并附上自己的设备信息 + (例如,手机型号、电脑的 CPU 型号等)。 +
+ 我们会根据测试结果,优化我们的实现,使性能更优。 +
+ 感谢你的支持! +
+

+
+
+
+ + ); +} diff --git a/packages/next/app/[locale]/video/[id]/info/page.tsx b/packages/next/app/[locale]/video/[id]/info/page.tsx new file mode 100644 index 0000000..b4fa55e --- /dev/null +++ b/packages/next/app/[locale]/video/[id]/info/page.tsx @@ -0,0 +1,86 @@ +import { Suspense } from "react"; +import Link from "next/link"; +import { format } from "date-fns"; +import { notFound } from "next/navigation"; + +const StatRow = ({ title, description }: { title: string; description?: number }) => { + return ( +
+ {title} + {description?.toLocaleString() ?? "N/A"} +
+ ); +}; + +const VideoInfo = async ({ id }: { id: string }) => { + const backendURL = process.env.BACKEND_URL; + + const res = await fetch(`${backendURL}/video/${id}/info`); + + if (!res.ok) { + return notFound(); + } + + const data = await res.json(); + + return ( +
+

+ {data.title || data.bvid} +

+ +

+ + {data.bvid} · av{data.aid} + +
+ 发布于 {format(new Date(data.pubdate * 1000), "yyyy-MM-dd HH:mm:ss")} +
+ 播放:{(data.stat?.view ?? 0).toLocaleString()} ·{" "} + 弹幕:{(data.stat?.danmaku ?? 0).toLocaleString()} +
+ + 分区: {data.tname}, tid{data.tid} · v2: {data.tname_v2}, tid + {data.tid_v2} + +

+ + Video cover + +

简介

+
+				{data.desc}
+			
+ +
+

统计数据

+
+ + + + + + + +
+
+
+ ); +}; + +export default async function VideoPage({ params }: { params: Promise<{ id: string }> }) { + const { id } = await params; + return ( +
+ +

正在努力加载中……

+
+ } + > + + + + ); +} diff --git a/packages/next/app/[locale]/video/layout.tsx b/packages/next/app/[locale]/video/layout.tsx new file mode 100644 index 0000000..2fcf8e2 --- /dev/null +++ b/packages/next/app/[locale]/video/layout.tsx @@ -0,0 +1,17 @@ +import { Header } from "@/components/shell/Header"; +import { getCurrentUser } from "@/lib/userAuth"; +import React from "react"; + +export default async function RootLayout({ + children +}: Readonly<{ + children: React.ReactNode; +}>) { + const user = await getCurrentUser(); + return ( + <> +
+ {children} + + ); +} diff --git a/packages/next/app/layout.tsx b/packages/next/app/layout.tsx new file mode 100644 index 0000000..44d7665 --- /dev/null +++ b/packages/next/app/layout.tsx @@ -0,0 +1,30 @@ +import type { Metadata } from "next"; +import "./[locale]/global.css"; +import React from "react"; +import { NextIntlClientProvider } from "next-intl"; + +export const metadata: Metadata = { + title: "中V档案馆" +}; + +export default async function RootLayout({ + children +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + + + 中V档案馆 + + + + {children} +
+
+ + + ); +} diff --git a/packages/next/app/not-found.tsx b/packages/next/app/not-found.tsx new file mode 100644 index 0000000..1167ec5 --- /dev/null +++ b/packages/next/app/not-found.tsx @@ -0,0 +1,5 @@ +import { NotFound } from "@/components/utils/404"; + +export default async function NotFoundPage() { + return ; +} diff --git a/packages/next/bun.lock b/packages/next/bun.lock new file mode 100644 index 0000000..54d5932 --- /dev/null +++ b/packages/next/bun.lock @@ -0,0 +1,1159 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "next", + "dependencies": { + "@cvsa/backend": "^0.5.3", + "@cvsa/core": "^0.0.5", + "@mdx-js/loader": "^3.1.0", + "@mdx-js/react": "^3.1.0", + "@next/mdx": "^15.3.3", + "@types/mdx": "^2.0.13", + "axios": "^1.9.0", + "date-fns": "^4.1.0", + "framer-motion": "^12.15.0", + "fumadocs-mdx": "^11.6.6", + "i18next": "^25.2.1", + "next": "^15.3.3", + "next-intl": "^4.1.0", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "swr": "^2.3.3", + "ua-parser-js": "^2.0.3", + "yup": "^1.6.1", + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.1.8", + "@types/node": "^20.17.57", + "@types/react": "^19.1.6", + "@types/react-dom": "^19.1.5", + "tailwindcss": "^4.1.8", + "typescript": "^5.8.3", + }, + }, + }, + "packages": { + "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], + + "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], + + "@babel/runtime": ["@babel/runtime@7.27.4", "", {}, "sha512-t3yaEOuGu9NlIZ+hIeGbBjFtZT7j2cb2tg0fuaJKeGotchRjjLfrBA9Kwf8quhpP1EUuxModQg04q/mBwyg8uA=="], + + "@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="], + + "@cvsa/backend": ["@cvsa/backend@0.5.3", "", { "dependencies": { "@rabbit-company/argon2id": "^2.1.0", "hono": "^4.7.8", "hono-rate-limiter": "^0.4.2", "ioredis": "^5.6.1", "limiter": "^3.0.0", "postgres": "^3.4.5", "rate-limit-redis": "^4.2.0", "yup": "^1.6.1", "zod": "^3.24.3" } }, "sha512-RzGjarU2TOzD6/d6qikE4xd/ZqNQl3jOYtgfJg5kbWFuiXnOgEC9QBTi+adzjmaWFrcpuYck6ooWpg4eT3s43g=="], + + "@cvsa/core": ["@cvsa/core@0.0.5", "", { "dependencies": { "@koshnic/ratelimit": "^1.0.3", "chalk": "^5.4.1", "ioredis": "^5.6.1", "logform": "^2.7.0", "postgres": "^3.4.5", "winston": "^3.17.0" } }, "sha512-YmsLDF6+hkqPm68BLgpbpB7RTlwKAjHu08TlU5+PdtNfGwYVcJx4fy+jnGEo8tCv68CvBYqoHXRN5Cr4OYo5oQ=="], + + "@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=="], + + "@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.5", "", { "os": "android", "cpu": "arm" }, "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA=="], + + "@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.5", "", { "os": "android", "cpu": "x64" }, "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw=="], + + "@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.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ=="], + + "@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.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.5", "", { "os": "linux", "cpu": "arm" }, "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw=="], + + "@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.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg=="], + + "@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.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ=="], + + "@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.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ=="], + + "@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.5", "", { "os": "none", "cpu": "arm64" }, "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw=="], + + "@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.5", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw=="], + + "@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.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA=="], + + "@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.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g=="], + + "@formatjs/ecma402-abstract": ["@formatjs/ecma402-abstract@2.3.4", "", { "dependencies": { "@formatjs/fast-memoize": "2.2.7", "@formatjs/intl-localematcher": "0.6.1", "decimal.js": "^10.4.3", "tslib": "^2.8.0" } }, "sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA=="], + + "@formatjs/fast-memoize": ["@formatjs/fast-memoize@2.2.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ=="], + + "@formatjs/icu-messageformat-parser": ["@formatjs/icu-messageformat-parser@2.11.2", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.4", "@formatjs/icu-skeleton-parser": "1.8.14", "tslib": "^2.8.0" } }, "sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA=="], + + "@formatjs/icu-skeleton-parser": ["@formatjs/icu-skeleton-parser@1.8.14", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.4", "tslib": "^2.8.0" } }, "sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ=="], + + "@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.5.10", "", { "dependencies": { "tslib": "2" } }, "sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q=="], + + "@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.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-x64": ["@img/sharp-libvips-darwin-x64@1.1.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ=="], + + "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.1.0", "", { "os": "linux", "cpu": "arm" }, "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA=="], + + "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew=="], + + "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.1.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ=="], + + "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.1.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA=="], + + "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q=="], + + "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w=="], + + "@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.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.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.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.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.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.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.2", "", { "dependencies": { "@emnapi/runtime": "^1.4.3" }, "cpu": "none" }, "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ=="], + + "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ=="], + + "@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=="], + + "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + + "@koshnic/ratelimit": ["@koshnic/ratelimit@1.0.3", "", { "dependencies": { "@types/chai": "^4.3.9", "@types/mocha": "^10.0.3", "chai": "^4.3.10", "ioredis": "^5.3.2", "mocha": "^10.2.0" } }, "sha512-cfDcSc+I+M4hNM+/4M+lfn8UuTq4OEFKl78ThOcGNaO7g8tWb1vm2qVpV1p1loYao1mqk00NBNwHQu2E/qFq2g=="], + + "@mdx-js/loader": ["@mdx-js/loader@3.1.0", "", { "dependencies": { "@mdx-js/mdx": "^3.0.0", "source-map": "^0.7.0" }, "peerDependencies": { "webpack": ">=5" }, "optionalPeers": ["webpack"] }, "sha512-xU/lwKdOyfXtQGqn3VnJjlDrmKXEvMi1mgYxVmukEUtVycIz1nh7oQ40bKTd4cA7rLStqu0740pnhGYxGoqsCg=="], + + "@mdx-js/mdx": ["@mdx-js/mdx@3.1.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw=="], + + "@mdx-js/react": ["@mdx-js/react@3.1.0", "", { "dependencies": { "@types/mdx": "^2.0.0" }, "peerDependencies": { "@types/react": ">=16", "react": ">=16" } }, "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ=="], + + "@next/env": ["@next/env@15.3.3", "", {}, "sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw=="], + + "@next/mdx": ["@next/mdx@15.3.3", "", { "dependencies": { "source-map": "^0.7.0" }, "peerDependencies": { "@mdx-js/loader": ">=0.15.0", "@mdx-js/react": ">=0.15.0" }, "optionalPeers": ["@mdx-js/loader", "@mdx-js/react"] }, "sha512-kJI7E/353vsoGa2usU/P36gDSA0iVc9xqJFFiPgLrSgWlivkANTRXjrnNVmVpHZ6ETmiZP52fMuKwmT9/FSmNQ=="], + + "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-WRJERLuH+O3oYB4yZNVahSVFmtxRNjNF1I1c34tYMoJb0Pve+7/RaLAJJizyYiFhjYNGHRAE1Ri2Fd23zgDqhg=="], + + "@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-XHdzH/yBc55lu78k/XwtuFR/ZXUTcflpRXcsu0nKmF45U96jt1tsOZhVrn5YH+paw66zOANpOnFQ9i6/j+UYvw=="], + + "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-VZ3sYL2LXB8znNGcjhocikEkag/8xiLgnvQts41tq6i+wql63SMS1Q6N8RVXHw5pEUjiof+II3HkDd7GFcgkzw=="], + + "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-h6Y1fLU4RWAp1HPNJWDYBQ+e3G7sLckyBXhmH9ajn8l/RSMnhbuPBV/fXmy3muMcVwoJdHL+UtzRzs0nXOf9SA=="], + + "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw=="], + + "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw=="], + + "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.3.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-SxorONgi6K7ZUysMtRF3mIeHC5aA3IQLmKFQzU0OuhuUYwpOBc1ypaLJLP5Bf3M9k53KUUUj4vTPwzGvl/NwlQ=="], + + "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.3.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4QZG6F8enl9/S2+yIiOiju0iCTFd93d8VC1q9LZS4p/Xuk81W2QDjCFeoogmrWWkAD59z8ZxepBQap2dKS5ruw=="], + + "@orama/orama": ["@orama/orama@3.1.7", "", {}, "sha512-6yB0117ZjsgNevZw3LP+bkrZa9mU/POPVaXgzMPOBbBc35w2P3R+1vMMhEfC06kYCpd5bf0jodBaTkYQW5TVeQ=="], + + "@rabbit-company/argon2id": ["@rabbit-company/argon2id@2.1.0", "", { "peerDependencies": { "typescript": "^5.6.2" } }, "sha512-X/kt89qjmS9+Zh+DYCGcWeTwHa4C8vY8T3EnSma+vWj7spMzAYX4F8vmGUkny9hygpTOeC/yXwAUdJAfJ52H+w=="], + + "@schummar/icu-type-parser": ["@schummar/icu-type-parser@1.21.5", "", {}, "sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw=="], + + "@shikijs/core": ["@shikijs/core@3.4.2", "", { "dependencies": { "@shikijs/types": "3.4.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-AG8vnSi1W2pbgR2B911EfGqtLE9c4hQBYkv/x7Z+Kt0VxhgQKcW7UNDVYsu9YxwV6u+OJrvdJrMq6DNWoBjihQ=="], + + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.4.2", "", { "dependencies": { "@shikijs/types": "3.4.2", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-1/adJbSMBOkpScCE/SB6XkjJU17ANln3Wky7lOmrnpl+zBdQ1qXUJg2GXTYVHRq+2j3hd1DesmElTXYDgtfSOQ=="], + + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.4.2", "", { "dependencies": { "@shikijs/types": "3.4.2", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-zcZKMnNndgRa3ORja6Iemsr3DrLtkX3cAF7lTJkdMB6v9alhlBsX9uNiCpqofNrXOvpA3h6lHcLJxgCIhVOU5Q=="], + + "@shikijs/langs": ["@shikijs/langs@3.4.2", "", { "dependencies": { "@shikijs/types": "3.4.2" } }, "sha512-H6azIAM+OXD98yztIfs/KH5H4PU39t+SREhmM8LaNXyUrqj2mx+zVkr8MWYqjceSjDw9I1jawm1WdFqU806rMA=="], + + "@shikijs/rehype": ["@shikijs/rehype@3.4.2", "", { "dependencies": { "@shikijs/types": "3.4.2", "@types/hast": "^3.0.4", "hast-util-to-string": "^3.0.1", "shiki": "3.4.2", "unified": "^11.0.5", "unist-util-visit": "^5.0.0" } }, "sha512-atbsrT3UKs25OdKVbNoHyKO9ZP7KEBPlo1oanPGMkvUL0fLictpxMPz6vPE2YTeHhpwz7EMrA4K4FHRY8XAReg=="], + + "@shikijs/themes": ["@shikijs/themes@3.4.2", "", { "dependencies": { "@shikijs/types": "3.4.2" } }, "sha512-qAEuAQh+brd8Jyej2UDDf+b4V2g1Rm8aBIdvt32XhDPrHvDkEnpb7Kzc9hSuHUxz0Iuflmq7elaDuQAP9bHIhg=="], + + "@shikijs/transformers": ["@shikijs/transformers@3.4.2", "", { "dependencies": { "@shikijs/core": "3.4.2", "@shikijs/types": "3.4.2" } }, "sha512-I5baLVi/ynLEOZoWSAMlACHNnG+yw5HDmse0oe+GW6U1u+ULdEB3UHiVWaHoJSSONV7tlcVxuaMy74sREDkSvg=="], + + "@shikijs/types": ["@shikijs/types@3.4.2", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-zHC1l7L+eQlDXLnxvM9R91Efh2V4+rN3oMVS2swCBssbj2U/FBwybD1eeLaq8yl/iwT+zih8iUbTBCgGZOYlVg=="], + + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], + + "@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="], + + "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="], + + "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], + + "@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.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.8", "", { "os": "android", "cpu": "arm64" }, "sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg=="], + + "@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.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw=="], + + "@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.8", "", { "os": "linux", "cpu": "arm" }, "sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ=="], + + "@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.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ=="], + + "@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.8", "", { "os": "linux", "cpu": "x64" }, "sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg=="], + + "@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.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA=="], + + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.8", "", { "os": "win32", "cpu": "x64" }, "sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ=="], + + "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.8", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.8", "@tailwindcss/oxide": "4.1.8", "postcss": "^8.4.41", "tailwindcss": "4.1.8" } }, "sha512-vB/vlf7rIky+w94aWMw34bWW1ka6g6C3xIOdICKX2GC0VcLtL6fhlLiafF0DVIwa9V6EHz8kbWMkS2s2QvvNlw=="], + + "@types/chai": ["@types/chai@4.3.20", "", {}, "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ=="], + + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + + "@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="], + + "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], + + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="], + + "@types/mocha": ["@types/mocha@10.0.10", "", {}, "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q=="], + + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + + "@types/node": ["@types/node@20.17.57", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-f3T4y6VU4fVQDKVqJV4Uppy8c1p/sVvS3peyqxyWnzkqXFJLRU7Y1Bl7rMS1Qe9z0v4M6McY0Fp9yBsgHJUsWQ=="], + + "@types/node-fetch": ["@types/node-fetch@2.6.12", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA=="], + + "@types/react": ["@types/react@19.1.6", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q=="], + + "@types/react-dom": ["@types/react-dom@19.1.5", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg=="], + + "@types/triple-beam": ["@types/triple-beam@1.3.5", "", {}, "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + + "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + + "acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="], + + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + + "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], + + "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "assertion-error": ["assertion-error@1.1.0", "", {}, "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="], + + "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], + + "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], + + "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + + "axios": ["axios@1.9.0", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg=="], + + "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], + + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], + + "body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="], + + "brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], + + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "browser-stdout": ["browser-stdout@1.3.1", "", {}, "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="], + + "busboy": ["busboy@1.6.0", "", { "dependencies": { "streamsearch": "^1.1.0" } }, "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA=="], + + "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + + "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + + "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001718", "", {}, "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw=="], + + "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + + "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=="], + + "chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="], + + "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], + + "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], + + "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + + "character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="], + + "check-error": ["check-error@1.0.3", "", { "dependencies": { "get-func-name": "^2.0.2" } }, "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg=="], + + "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], + + "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], + + "cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], + + "cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="], + + "collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="], + + "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], + + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], + + "colorspace": ["colorspace@1.1.4", "", { "dependencies": { "color": "^3.1.3", "text-hex": "1.0.x" } }, "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w=="], + + "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], + + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + + "compute-scroll-into-view": ["compute-scroll-into-view@3.1.1", "", {}, "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw=="], + + "content-disposition": ["content-disposition@1.0.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg=="], + + "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], + + "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + + "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], + + "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + + "date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="], + + "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=="], + + "decimal.js": ["decimal.js@10.5.0", "", {}, "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw=="], + + "decode-named-character-reference": ["decode-named-character-reference@1.1.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w=="], + + "deep-eql": ["deep-eql@4.1.4", "", { "dependencies": { "type-detect": "^4.0.0" } }, "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg=="], + + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], + + "denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="], + + "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "detect-europe-js": ["detect-europe-js@0.1.2", "", {}, "sha512-lgdERlL3u0aUdHocoouzT10d9I89VVhk0qNRmll7mXdGfJT1/wqZ2ZLA4oJAjeACPY5fT1wsbq2AT+GkuInsow=="], + + "detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="], + + "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="], + + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + + "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], + + "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "enabled": ["enabled@2.0.0", "", {}, "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="], + + "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + + "enhanced-resolve": ["enhanced-resolve@5.18.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg=="], + + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], + + "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], + + "esast-util-from-estree": ["esast-util-from-estree@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "unist-util-position-from-estree": "^2.0.0" } }, "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ=="], + + "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], + + "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=="], + + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], + + "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + + "estree-util-attach-comments": ["estree-util-attach-comments@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw=="], + + "estree-util-build-jsx": ["estree-util-build-jsx@3.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-walker": "^3.0.0" } }, "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ=="], + + "estree-util-is-identifier-name": ["estree-util-is-identifier-name@3.0.0", "", {}, "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg=="], + + "estree-util-scope": ["estree-util-scope@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0" } }, "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ=="], + + "estree-util-to-js": ["estree-util-to-js@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "astring": "^1.8.0", "source-map": "^0.7.0" } }, "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg=="], + + "estree-util-value-to-estree": ["estree-util-value-to-estree@3.4.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-Zlp+gxis+gCfK12d3Srl2PdX2ybsEA8ZYy6vQGVQTNNYLEGRQQ56XB64bjemN8kxIKXP1nC9ip4Z+ILy9LGzvQ=="], + + "estree-util-visit": ["estree-util-visit@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/unist": "^3.0.0" } }, "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww=="], + + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + + "express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="], + + "express-rate-limit": ["express-rate-limit@7.5.0", "", { "peerDependencies": { "express": "^4.11 || 5 || ^5.0.0-beta.1" } }, "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg=="], + + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="], + + "fdir": ["fdir@6.4.5", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw=="], + + "fecha": ["fecha@4.2.3", "", {}, "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "finalhandler": ["finalhandler@2.1.0", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q=="], + + "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], + + "flat": ["flat@5.0.2", "", { "bin": { "flat": "cli.js" } }, "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="], + + "fn.name": ["fn.name@1.1.0", "", {}, "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="], + + "follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="], + + "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=="], + + "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], + + "framer-motion": ["framer-motion@12.15.0", "", { "dependencies": { "motion-dom": "^12.15.0", "motion-utils": "^12.12.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-XKg/LnKExdLGugZrDILV7jZjI599785lDIJZLxMiiIFidCsy0a4R2ZEf+Izm67zyOuJgQYTHOmodi7igQsw3vg=="], + + "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], + + "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "fumadocs-core": ["fumadocs-core@15.5.0", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.6.1", "@orama/orama": "^3.1.6", "@shikijs/rehype": "^3.4.2", "@shikijs/transformers": "^3.4.2", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", "image-size": "^2.0.2", "negotiator": "^1.0.0", "react-remove-scroll": "^2.6.3", "remark": "^15.0.0", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^3.4.2", "unist-util-visit": "^5.0.0" }, "peerDependencies": { "@oramacloud/client": "1.x.x || 2.x.x", "algoliasearch": "5.x.x", "next": "14.x.x || 15.x.x", "react": "18.x.x || 19.x.x", "react-dom": "18.x.x || 19.x.x" }, "optionalPeers": ["@oramacloud/client", "algoliasearch", "next", "react", "react-dom"] }, "sha512-om0rmaYG8MidItR1dGuiNYX1MbSGUM1xEFfWpBCcJ9yI52FPGOJtZajWgAqqjvOVJk9Wl4m03sZdBjb4S8ra3g=="], + + "fumadocs-mdx": ["fumadocs-mdx@11.6.6", "", { "dependencies": { "@mdx-js/mdx": "^3.1.0", "@standard-schema/spec": "^1.0.0", "chokidar": "^4.0.3", "esbuild": "^0.25.4", "estree-util-value-to-estree": "^3.4.0", "gray-matter": "^4.0.3", "js-yaml": "^4.1.0", "lru-cache": "^11.1.0", "picocolors": "^1.1.1", "tinyexec": "^1.0.1", "tinyglobby": "^0.2.13", "unist-util-visit": "^5.0.0", "zod": "^3.25.28" }, "peerDependencies": { "@fumadocs/mdx-remote": "^1.2.0", "fumadocs-core": "^14.0.0 || ^15.0.0", "next": "^15.3.0" }, "optionalPeers": ["@fumadocs/mdx-remote"], "bin": { "fumadocs-mdx": "bin.js" } }, "sha512-CRSrO2C8+hybQq6u97pB/FN3Hq1Y8FbTnqYfr1MzLdLCB7IsbfXu4KkkqJq4Tq4icGb68BpeLWDsSxDmrswNAA=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-func-name": ["get-func-name@2.0.2", "", {}, "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ=="], + + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + + "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], + + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + + "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], + + "glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="], + + "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "gray-matter": ["gray-matter@4.0.3", "", { "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" } }, "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], + + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + + "hast-util-to-estree": ["hast-util-to-estree@3.1.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-attach-comments": "^3.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w=="], + + "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], + + "hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="], + + "hast-util-to-string": ["hast-util-to-string@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A=="], + + "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + + "he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="], + + "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=="], + + "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], + + "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=="], + + "i18next": ["i18next@25.2.1", "", { "dependencies": { "@babel/runtime": "^7.27.1" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-+UoXK5wh+VlE1Zy5p6MjcvctHXAhRwQKCxiJD8noKZzIXmnAX8gdHX5fLPA3MEVxEN4vbZkQFy8N0LyD9tUqPw=="], + + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + + "image-size": ["image-size@2.0.2", "", { "bin": { "image-size": "bin/image-size.js" } }, "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w=="], + + "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "inline-style-parser": ["inline-style-parser@0.2.4", "", {}, "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="], + + "intl-messageformat": ["intl-messageformat@10.7.16", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.4", "@formatjs/fast-memoize": "2.2.7", "@formatjs/icu-messageformat-parser": "2.11.2", "tslib": "^2.8.0" } }, "sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug=="], + + "ioredis": ["ioredis@5.6.1", "", { "dependencies": { "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA=="], + + "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], + + "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], + + "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], + + "is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="], + + "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], + + "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], + + "is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="], + + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + + "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], + + "is-standalone-pwa": ["is-standalone-pwa@0.1.1", "", {}, "sha512-9Cbovsa52vNQCjdXOzeQq5CnCbAcRk05aU62K20WO372NrTv0NxibLFCK6lQ4/iZEFdEA3p3t2VNOn8AJ53F5g=="], + + "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], + + "is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="], + + "jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="], + + "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], + + "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], + + "kuler": ["kuler@2.0.0", "", {}, "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="], + + "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.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="], + + "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.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="], + + "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.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="], + + "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.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="], + + "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.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="], + + "limiter": ["limiter@3.0.0", "", {}, "sha512-hev7DuXojsTFl2YwyzUJMDnZ/qBDd3yZQLSH3aD4tdL1cqfc3TMnoecEJtWFaQFdErZsKoFMBTxF/FBSkgDbEg=="], + + "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], + + "lodash.defaults": ["lodash.defaults@4.2.0", "", {}, "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="], + + "lodash.isarguments": ["lodash.isarguments@3.1.0", "", {}, "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="], + + "log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="], + + "logform": ["logform@2.7.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ=="], + + "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], + + "loupe": ["loupe@2.3.7", "", { "dependencies": { "get-func-name": "^2.0.1" } }, "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA=="], + + "lru-cache": ["lru-cache@11.1.0", "", {}, "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A=="], + + "magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="], + + "markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="], + + "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], + + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + + "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], + + "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA=="], + + "mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="], + + "mdast-util-gfm-autolink-literal": ["mdast-util-gfm-autolink-literal@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-find-and-replace": "^3.0.0", "micromark-util-character": "^2.0.0" } }, "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ=="], + + "mdast-util-gfm-footnote": ["mdast-util-gfm-footnote@2.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0" } }, "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ=="], + + "mdast-util-gfm-strikethrough": ["mdast-util-gfm-strikethrough@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg=="], + + "mdast-util-gfm-table": ["mdast-util-gfm-table@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "markdown-table": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg=="], + + "mdast-util-gfm-task-list-item": ["mdast-util-gfm-task-list-item@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ=="], + + "mdast-util-mdx": ["mdast-util-mdx@3.0.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w=="], + + "mdast-util-mdx-expression": ["mdast-util-mdx-expression@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ=="], + + "mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.2.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q=="], + + "mdast-util-mdxjs-esm": ["mdast-util-mdxjs-esm@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg=="], + + "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], + + "mdast-util-to-hast": ["mdast-util-to-hast@13.2.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA=="], + + "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], + + "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], + + "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], + + "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], + + "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], + + "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], + + "micromark-extension-gfm": ["micromark-extension-gfm@3.0.0", "", { "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", "micromark-extension-gfm-footnote": "^2.0.0", "micromark-extension-gfm-strikethrough": "^2.0.0", "micromark-extension-gfm-table": "^2.0.0", "micromark-extension-gfm-tagfilter": "^2.0.0", "micromark-extension-gfm-task-list-item": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w=="], + + "micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="], + + "micromark-extension-gfm-footnote": ["micromark-extension-gfm-footnote@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw=="], + + "micromark-extension-gfm-strikethrough": ["micromark-extension-gfm-strikethrough@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw=="], + + "micromark-extension-gfm-table": ["micromark-extension-gfm-table@2.1.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg=="], + + "micromark-extension-gfm-tagfilter": ["micromark-extension-gfm-tagfilter@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg=="], + + "micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw=="], + + "micromark-extension-mdx-expression": ["micromark-extension-mdx-expression@3.0.1", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q=="], + + "micromark-extension-mdx-jsx": ["micromark-extension-mdx-jsx@3.0.2", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ=="], + + "micromark-extension-mdx-md": ["micromark-extension-mdx-md@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ=="], + + "micromark-extension-mdxjs": ["micromark-extension-mdxjs@3.0.0", "", { "dependencies": { "acorn": "^8.0.0", "acorn-jsx": "^5.0.0", "micromark-extension-mdx-expression": "^3.0.0", "micromark-extension-mdx-jsx": "^3.0.0", "micromark-extension-mdx-md": "^2.0.0", "micromark-extension-mdxjs-esm": "^3.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ=="], + + "micromark-extension-mdxjs-esm": ["micromark-extension-mdxjs-esm@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-position-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A=="], + + "micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="], + + "micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="], + + "micromark-factory-mdx-expression": ["micromark-factory-mdx-expression@2.0.3", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-position-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ=="], + + "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="], + + "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="], + + "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="], + + "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="], + + "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="], + + "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="], + + "micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-events-to-acorn": ["micromark-util-events-to-acorn@2.0.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg=="], + + "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="], + + "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="], + + "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + + "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + + "minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], + + "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], + + "minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="], + + "mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], + + "mocha": ["mocha@10.8.2", "", { "dependencies": { "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", "chokidar": "^3.5.3", "debug": "^4.3.5", "diff": "^5.2.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", "glob": "^8.1.0", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", "minimatch": "^5.1.6", "ms": "^2.1.3", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", "workerpool": "^6.5.1", "yargs": "^16.2.0", "yargs-parser": "^20.2.9", "yargs-unparser": "^2.0.0" }, "bin": { "mocha": "bin/mocha.js", "_mocha": "bin/_mocha" } }, "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg=="], + + "motion-dom": ["motion-dom@12.15.0", "", { "dependencies": { "motion-utils": "^12.12.1" } }, "sha512-D2ldJgor+2vdcrDtKJw48k3OddXiZN1dDLLWrS8kiHzQdYVruh0IoTwbJBslrnTXIPgFED7PBN2Zbwl7rNqnhA=="], + + "motion-utils": ["motion-utils@12.12.1", "", {}, "sha512-f9qiqUHm7hWSLlNW8gS9pisnsN7CRFRD58vNjptKdsqFLpkVnX00TNeD6Q0d27V9KzT7ySFyK1TZ/DShfVOv6w=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "next": ["next@15.3.3", "", { "dependencies": { "@next/env": "15.3.3", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.15", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.3.3", "@next/swc-darwin-x64": "15.3.3", "@next/swc-linux-arm64-gnu": "15.3.3", "@next/swc-linux-arm64-musl": "15.3.3", "@next/swc-linux-x64-gnu": "15.3.3", "@next/swc-linux-x64-musl": "15.3.3", "@next/swc-win32-arm64-msvc": "15.3.3", "@next/swc-win32-x64-msvc": "15.3.3", "sharp": "^0.34.1" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw=="], + + "next-intl": ["next-intl@4.1.0", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.5.4", "negotiator": "^1.0.0", "use-intl": "^4.1.0" }, "peerDependencies": { "next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0", "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-JNJRjc7sdnfUxhZmGcvzDszZ60tQKrygV/VLsgzXhnJDxQPn1cN2rVpc53adA1SvBJwPK2O6Sc6b4gYSILjCzw=="], + + "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + + "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], + + "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], + + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "one-time": ["one-time@1.0.0", "", { "dependencies": { "fn.name": "1.x.x" } }, "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g=="], + + "oniguruma-parser": ["oniguruma-parser@0.12.1", "", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="], + + "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=="], + + "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], + + "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], + + "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], + + "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], + + "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], + + "path-to-regexp": ["path-to-regexp@8.2.0", "", {}, "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ=="], + + "pathval": ["pathval@1.1.1", "", {}, "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], + + "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=="], + + "postgres": ["postgres@3.4.7", "", {}, "sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw=="], + + "property-expr": ["property-expr@2.0.6", "", {}, "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA=="], + + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], + + "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-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + + "qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="], + + "randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="], + + "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], + + "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=="], + + "react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="], + + "react-dom": ["react-dom@19.1.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g=="], + + "react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="], + + "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], + + "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + + "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + + "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], + + "recma-build-jsx": ["recma-build-jsx@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-build-jsx": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew=="], + + "recma-jsx": ["recma-jsx@1.0.0", "", { "dependencies": { "acorn-jsx": "^5.0.0", "estree-util-to-js": "^2.0.0", "recma-parse": "^1.0.0", "recma-stringify": "^1.0.0", "unified": "^11.0.0" } }, "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q=="], + + "recma-parse": ["recma-parse@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "esast-util-from-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ=="], + + "recma-stringify": ["recma-stringify@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-to-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g=="], + + "redis-errors": ["redis-errors@1.2.0", "", {}, "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="], + + "redis-parser": ["redis-parser@3.0.0", "", { "dependencies": { "redis-errors": "^1.0.0" } }, "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A=="], + + "regex": ["regex@6.0.1", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA=="], + + "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], + + "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], + + "rehype-recma": ["rehype-recma@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "hast-util-to-estree": "^3.0.0" } }, "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw=="], + + "remark": ["remark@15.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A=="], + + "remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="], + + "remark-mdx": ["remark-mdx@3.1.0", "", { "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" } }, "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA=="], + + "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="], + + "remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="], + + "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="], + + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + + "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=="], + + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + + "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], + + "scroll-into-view-if-needed": ["scroll-into-view-if-needed@3.1.0", "", { "dependencies": { "compute-scroll-into-view": "^3.0.2" } }, "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ=="], + + "section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="], + + "semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], + + "send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], + + "serialize-javascript": ["serialize-javascript@6.0.2", "", { "dependencies": { "randombytes": "^2.1.0" } }, "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g=="], + + "serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="], + + "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], + + "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=="], + + "shiki": ["shiki@3.4.2", "", { "dependencies": { "@shikijs/core": "3.4.2", "@shikijs/engine-javascript": "3.4.2", "@shikijs/engine-oniguruma": "3.4.2", "@shikijs/langs": "3.4.2", "@shikijs/themes": "3.4.2", "@shikijs/types": "3.4.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-wuxzZzQG8kvZndD7nustrNFIKYJ1jJoWIPaBpVe2+KHSvtzMi4SBjOxrigs8qeqce/l3U0cwiC+VAkLKSunHQQ=="], + + "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-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], + + "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], + + "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + + "simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="], + + "source-map": ["source-map@0.7.4", "", {}, "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + + "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + + "stack-trace": ["stack-trace@0.0.10", "", {}, "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg=="], + + "standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="], + + "statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], + + "streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="], + + "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], + + "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], + + "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="], + + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + + "style-to-js": ["style-to-js@1.1.16", "", { "dependencies": { "style-to-object": "1.0.8" } }, "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw=="], + + "style-to-object": ["style-to-object@1.0.8", "", { "dependencies": { "inline-style-parser": "0.2.4" } }, "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g=="], + + "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="], + + "supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], + + "swr": ["swr@2.3.3", "", { "dependencies": { "dequal": "^2.0.3", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A=="], + + "tailwindcss": ["tailwindcss@4.1.8", "", {}, "sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og=="], + + "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=="], + + "text-hex": ["text-hex@1.0.0", "", {}, "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="], + + "tiny-case": ["tiny-case@1.0.3", "", {}, "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q=="], + + "tinyexec": ["tinyexec@1.0.1", "", {}, "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw=="], + + "tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], + + "toposort": ["toposort@2.0.2", "", {}, "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg=="], + + "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + + "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], + + "triple-beam": ["triple-beam@1.4.1", "", {}, "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg=="], + + "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "type-detect": ["type-detect@4.1.0", "", {}, "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw=="], + + "type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], + + "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], + + "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="], + + "ua-is-frozen": ["ua-is-frozen@0.1.2", "", {}, "sha512-RwKDW2p3iyWn4UbaxpP2+VxwqXh0jpvdxsYpZ5j/MLLiQOfbsV5shpgQiw93+KMYQPcteeMQ289MaAFzs3G9pw=="], + + "ua-parser-js": ["ua-parser-js@2.0.3", "", { "dependencies": { "@types/node-fetch": "^2.6.12", "detect-europe-js": "^0.1.2", "is-standalone-pwa": "^0.1.1", "node-fetch": "^2.7.0", "ua-is-frozen": "^0.1.2" }, "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-LZyXZdNttONW8LjzEH3Z8+6TE7RfrEiJqDKyh0R11p/kxvrV2o9DrT2FGZO+KVNs3k+drcIQ6C3En6wLnzJGpw=="], + + "undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], + + "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=="], + + "unist-util-is": ["unist-util-is@6.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="], + + "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], + + "unist-util-position-from-estree": ["unist-util-position-from-estree@2.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw=="], + + "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + + "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], + + "use-intl": ["use-intl@4.1.0", "", { "dependencies": { "@formatjs/fast-memoize": "^2.2.0", "@schummar/icu-type-parser": "1.21.5", "intl-messageformat": "^10.5.14" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0" } }, "sha512-mQvDYFvoGn+bm/PWvlQOtluKCknsQ5a9F1Cj0hMfBjMBVTwnOqLPd6srhjvVdEQEQFVyHM1PfyifKqKYb11M9Q=="], + + "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], + + "use-sync-external-store": ["use-sync-external-store@1.5.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-message": ["vfile-message@4.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="], + + "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], + + "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], + + "winston": ["winston@3.17.0", "", { "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.9.0" } }, "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw=="], + + "winston-transport": ["winston-transport@4.9.0", "", { "dependencies": { "logform": "^2.7.0", "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" } }, "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A=="], + + "workerpool": ["workerpool@6.5.1", "", {}, "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA=="], + + "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=="], + + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + + "yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="], + + "yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="], + + "yargs-unparser": ["yargs-unparser@2.0.0", "", { "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" } }, "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA=="], + + "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], + + "yup": ["yup@1.6.1", "", { "dependencies": { "property-expr": "^2.0.5", "tiny-case": "^1.0.3", "toposort": "^2.0.2", "type-fest": "^2.19.0" } }, "sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA=="], + + "zod": ["zod@3.25.46", "", {}, "sha512-IqRxcHEIjqLd4LNS/zKffB3Jzg3NwqJxQQ0Ns7pdrvgGkwQsEBdEQcOHaBVqvvZArShRzI39+aMST3FBGmTrLQ=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + + "@formatjs/ecma402-abstract/@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.6.1", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.4.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ=="], + + "@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.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/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "accepts/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="], + + "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "colorspace/color": ["color@3.2.1", "", { "dependencies": { "color-convert": "^1.9.3", "color-string": "^1.6.0" } }, "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA=="], + + "express/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="], + + "fumadocs-core/@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.6.1", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg=="], + + "gray-matter/js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="], + + "log-symbols/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + + "mocha/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + + "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], + + "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], + + "send/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="], + + "type-is/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="], + + "yargs-unparser/is-plain-obj": ["is-plain-obj@2.1.0", "", {}, "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="], + + "accepts/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "colorspace/color/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], + + "express/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "gray-matter/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + + "log-symbols/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "mocha/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + + "send/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "type-is/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "colorspace/color/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + + "mocha/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + } +} diff --git a/packages/next/components/hooks/useCaptcha.ts b/packages/next/components/hooks/useCaptcha.ts new file mode 100644 index 0000000..4149006 --- /dev/null +++ b/packages/next/components/hooks/useCaptcha.ts @@ -0,0 +1,51 @@ +import useSWRMutation from "swr/mutation"; +import { useState } from "react"; +import type { CaptchaVerificationRawResponse, CaptchaSessionRawResponse } from "@cvsa/backend"; +import { fetcher } from "@/lib/net"; +import { computeVdfInWorker } from "@/lib/vdf"; + +interface UseCaptchaOptions { + backendURL: string; + route: string; +} + +export function useCaptcha({ backendURL, route }: UseCaptchaOptions) { + const fullUrl = `${backendURL}/captcha/session`; + const [isUsed, setIsUsed] = useState(false); + + const { trigger, data, isMutating, error } = useSWRMutation( + fullUrl, + async (url: string) => { + const sessionRes = await fetcher(url, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + data: { route } + }); + + const { g, n, t, id } = sessionRes; + if (!g || !n || !t || !id) { + throw new Error("Missing required CAPTCHA parameters"); + } + + const ans = await computeVdfInWorker(BigInt(g), BigInt(n), BigInt(t)); + + const resultUrl = new URL(`${backendURL}/captcha/${id}/result`); + resultUrl.searchParams.set("ans", ans.result.toString()); + + const result = await fetcher(resultUrl.toString()); + setIsUsed(false); + return result; + } + ); + + return { + startCaptcha: trigger, + captchaResult: data, + isLoadingCaptcha: isMutating, + captchaError: error, + captchaUsed: isUsed, + setCaptchaUsedState: setIsUsed + }; +} diff --git a/packages/next/components/icons/CloseIcon.tsx b/packages/next/components/icons/CloseIcon.tsx new file mode 100644 index 0000000..88b2ffb --- /dev/null +++ b/packages/next/components/icons/CloseIcon.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +export const CloseIcon: React.FC> = (props) => ( +
+ + + +
+); diff --git a/packages/next/components/icons/HomeIcon.tsx b/packages/next/components/icons/HomeIcon.tsx new file mode 100644 index 0000000..f95154f --- /dev/null +++ b/packages/next/components/icons/HomeIcon.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +export const HomeIcon: React.FC> = (props) => ( +
+ + + +
+); diff --git a/packages/next/components/icons/InfoIcon.tsx b/packages/next/components/icons/InfoIcon.tsx new file mode 100644 index 0000000..f2b312a --- /dev/null +++ b/packages/next/components/icons/InfoIcon.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +export const InfoIcon: React.FC> = (props) => ( +
+ + + +
+); diff --git a/packages/next/components/icons/LeftArrow.tsx b/packages/next/components/icons/LeftArrow.tsx new file mode 100644 index 0000000..8d8cfcd --- /dev/null +++ b/packages/next/components/icons/LeftArrow.tsx @@ -0,0 +1,13 @@ +import React from "react"; + +export const LeftArrow: React.FC> = (props) => ( + + + +); diff --git a/packages/next/components/icons/LoadingSpinner.tsx b/packages/next/components/icons/LoadingSpinner.tsx new file mode 100644 index 0000000..25abfff --- /dev/null +++ b/packages/next/components/icons/LoadingSpinner.tsx @@ -0,0 +1,39 @@ +import React from "react"; + +const LoadingSpinner: React.FC> = (props) => ( +
+ + + + + + + + + +
+); + +export default LoadingSpinner; diff --git a/packages/next/components/icons/MenuIcon.tsx b/packages/next/components/icons/MenuIcon.tsx new file mode 100644 index 0000000..5977c8c --- /dev/null +++ b/packages/next/components/icons/MenuIcon.tsx @@ -0,0 +1,15 @@ +import React from "react"; + +export const MenuIcon: React.FC> = (props) => ( +
+ + + +
+); diff --git a/packages/next/components/icons/RegisterIcon.tsx b/packages/next/components/icons/RegisterIcon.tsx new file mode 100644 index 0000000..5cd344c --- /dev/null +++ b/packages/next/components/icons/RegisterIcon.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +export const RegisterIcon: React.FC> = (props) => ( +
+ + + +
+); diff --git a/packages/next/components/icons/RightArrow.tsx b/packages/next/components/icons/RightArrow.tsx new file mode 100644 index 0000000..9c4784b --- /dev/null +++ b/packages/next/components/icons/RightArrow.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +export const RightArrow: React.FC> = (props) => ( + + + +); diff --git a/packages/next/components/icons/SearchIcon.tsx b/packages/next/components/icons/SearchIcon.tsx new file mode 100644 index 0000000..4f26208 --- /dev/null +++ b/packages/next/components/icons/SearchIcon.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +export const SearchIcon: React.FC> = (props) => ( +
+ + + +
+); diff --git a/packages/next/components/shell/Header.tsx b/packages/next/components/shell/Header.tsx new file mode 100644 index 0000000..d2d6756 --- /dev/null +++ b/packages/next/components/shell/Header.tsx @@ -0,0 +1,145 @@ +"use client"; + +import TitleLight from "@/public/icons/标题-浅色.svg"; +import TitleDark from "@/public/icons/标题-深色.svg"; +import LogoMobileLight from "@/public/icons/TitleBar Mobile Light.svg"; +import LogoMobileDark from "@/public/icons/TitleBar Mobile Dark.svg"; +import DarkModeImage from "@/components/utils/DarkModeImage"; +import React, { useState } from "react"; +import { NavigationDrawer } from "@/components/ui/NavigatinDrawer"; +import { Portal } from "@/components/utils/Portal"; +import { RegisterIcon } from "@/components/icons/RegisterIcon"; +import { SearchBox } from "@/components/ui/SearchBox"; +import { MenuIcon } from "@/components/icons/MenuIcon"; +import { SearchIcon } from "@/components/icons/SearchIcon"; +import { InfoIcon } from "@/components/icons/InfoIcon"; +import { HomeIcon } from "@/components/icons/HomeIcon"; +import { TextButton } from "@/components/ui/Buttons/TextButton"; +import { Link } from "@/i18n/navigation"; +import type { UserResponse } from "@cvsa/backend"; + +interface HeaderProps { + user: UserResponse | null; +} + +export const HeaderDestop = ({ user }: HeaderProps) => { + return ( +
+
+ + + +
+ + + +
+ {user ? ( + {user.nickname || user.username} + ) : ( + 注册 + )} + + 关于 +
+
+ ); +}; + +export const HeaderMobile = ({ user }: HeaderProps) => { + const [showDrawer, setShowDrawer] = useState(false); + const [showsearchBox, setShowsearchBox] = useState(false); + + return ( + <> + + setShowDrawer(false)}> +
+
+ +
+ + + +
+ + 首页 +
+
+ + + +
+ + 关于 +
+
+ + + + +
+ + 注册 +
+
+ +
+
+
+
+ {!showsearchBox && ( + + )} + {!showsearchBox && ( +
+ + + +
+ )} + {showsearchBox && setShowsearchBox(false)} />} + {!showsearchBox && ( + + )} +
+ + ); +}; + +export const Header = (props: HeaderProps) => { + return ( + <> + + + + ); +}; diff --git a/packages/next/components/ui/Buttons/FilledButton.tsx b/packages/next/components/ui/Buttons/FilledButton.tsx new file mode 100644 index 0000000..ddb98dd --- /dev/null +++ b/packages/next/components/ui/Buttons/FilledButton.tsx @@ -0,0 +1,41 @@ +import useRipple from "@/components/utils/useRipple"; + +interface FilledButtonProps extends React.ButtonHTMLAttributes { + size?: "xs" | "s" | "m" | "l" | "xl"; + shape?: "round" | "square"; + children?: React.ReactNode; + ripple?: boolean; +} + +export const FilledButton = ({ + children, + size = "s", + shape = "round", + className, + ripple = true, + ...rest +}: FilledButtonProps) => { + let sizeClasses = "text-sm leading-5 h-10 px-4"; + let shapeClasses = shape === "round" ? "rounded-full" : "rounded-xl"; + + if (size === "m") { + sizeClasses = "text-base leading-6 h-14 px-6"; + shapeClasses = shape === "round" ? "rounded-full" : "rounded-2xl"; + } + + const { onMouseDown, onTouchStart } = useRipple({ ripple }); + + return ( + + ); +}; diff --git a/packages/next/components/ui/Buttons/TextButton.tsx b/packages/next/components/ui/Buttons/TextButton.tsx new file mode 100644 index 0000000..0ee83e2 --- /dev/null +++ b/packages/next/components/ui/Buttons/TextButton.tsx @@ -0,0 +1,41 @@ +import useRipple from "@/components/utils/useRipple"; + +interface TextButtonProps extends React.ButtonHTMLAttributes { + size?: "xs" | "s" | "m" | "l" | "xl"; + shape?: "round" | "square"; + children?: React.ReactNode; + ripple?: boolean; +} + +export const TextButton = ({ + children, + size = "s", + shape = "round", + className, + ripple = true, + ...rest +}: TextButtonProps) => { + let sizeClasses = "text-sm leading-5 h-10 px-4"; + let shapeClasses = "rounded-full"; + + if (size === "m") { + sizeClasses = "text-base leading-6 h-14 px-6"; + shapeClasses = shape === "round" ? "rounded-full" : "rounded-2xl"; + } + + const { onMouseDown, onTouchStart } = useRipple({ ripple }); + + return ( + + ); +}; diff --git a/packages/next/components/ui/Dialog.tsx b/packages/next/components/ui/Dialog.tsx new file mode 100644 index 0000000..5bc3904 --- /dev/null +++ b/packages/next/components/ui/Dialog.tsx @@ -0,0 +1,111 @@ +import { motion, AnimatePresence } from "framer-motion"; +import React from "react"; +import { TextButton } from "./Buttons/TextButton"; +import { useEffect } from "react"; + +export const useDisableBodyScroll = (open: boolean) => { + useEffect(() => { + if (open) { + document.body.style.overflow = "hidden"; + } else { + document.body.style.overflow = "unset"; + } + }, [open]); +}; + +type OptionalChidrenProps> = T & { + children?: React.ReactNode; +}; + +type HeadElementAttr = React.HTMLAttributes; +type DivElementAttr = React.HTMLAttributes; +type ButtonElementAttr = React.HTMLAttributes; + +type DialogHeadlineProps = OptionalChidrenProps; +type DialogSupportingTextProps = OptionalChidrenProps; +type DialogButtonGroupProps = OptionalChidrenProps; + +interface DialogButtonProps extends OptionalChidrenProps { + onClick?: React.MouseEventHandler; +} +interface DialogProps extends OptionalChidrenProps { + show: boolean; + children?: React.ReactNode; +} + +export const DialogHeadline: React.FC = ({ + children, + className, + ...rest +}: DialogHeadlineProps) => { + return ( +

+ {children} +

+ ); +}; + +export const DialogSupportingText: React.FC = ({ + children, + className, + ...rest +}: DialogHeadlineProps) => { + return ( +
+ {children} +
+ ); +}; + +export const DialogButton: React.FC = ({ children, onClick, ...rest }: DialogButtonProps) => { + return ( + + {children} + + ); +}; + +export const DialogButtonGroup: React.FC = ({ children, ...rest }: DialogButtonGroupProps) => { + return ( +
+ {children} +
+ ); +}; + +export const Dialog: React.FC = ({ show, children, className }: DialogProps) => { + useDisableBodyScroll(show); + return ( + + {show && ( +
+
+ )} +
+ ); +}; diff --git a/packages/next/components/ui/NavigatinDrawer.tsx b/packages/next/components/ui/NavigatinDrawer.tsx new file mode 100644 index 0000000..384b405 --- /dev/null +++ b/packages/next/components/ui/NavigatinDrawer.tsx @@ -0,0 +1,62 @@ +import React, { useEffect, useRef } from "react"; +import { motion, AnimatePresence } from "framer-motion"; + +interface DrawerProps { + show?: boolean; + onClose: () => void; + children: React.ReactNode; +} + +export const NavigationDrawer = ({ show = false, onClose, children }: DrawerProps) => { + const scrimRef = useRef(null); + + useEffect(() => { + const handleOutsideClick = (event: MouseEvent) => { + if (show && scrimRef.current && event.target === scrimRef.current) { + onClose(); + } + }; + + window.addEventListener("click", handleOutsideClick); + return () => { + window.removeEventListener("click", handleOutsideClick); + }; + }, [show, onClose]); + + return ( + + {show && ( + <> + {/* Scrim - Fade in/out */} + + ); +}; + +export default NavigationDrawer; diff --git a/packages/next/components/ui/SearchBox.tsx b/packages/next/components/ui/SearchBox.tsx new file mode 100644 index 0000000..2387a21 --- /dev/null +++ b/packages/next/components/ui/SearchBox.tsx @@ -0,0 +1,92 @@ +import React, { useState, useRef, useCallback } from "react"; +import { SearchIcon } from "@/components/icons/SearchIcon"; +import { CloseIcon } from "@/components/icons/CloseIcon"; + +interface SearchBoxProps { + close?: () => void; +} + +export const SearchBox: React.FC = ({ close = () => {} }) => { + const [inputValue, setInputValue] = useState(""); + const inputElement = useRef(null); + + const search = useCallback((query: string) => { + if (query.trim()) { + window.location.href = `/song/${query.trim()}/info`; + } + }, []); + + const handleInputChange = useCallback((event: React.ChangeEvent) => { + setInputValue(event.target.value); + }, []); + + const handleKeyDown = useCallback( + (event: React.KeyboardEvent) => { + if (event.key === "Enter") { + event.preventDefault(); + search(inputValue); + } + }, + [inputValue, search] + ); + + const handleClear = useCallback(() => { + setInputValue(""); + close(); + }, [close]); + + return ( +
+
+ +
+ +
+
+ +
+ + +
+
+ ); +}; diff --git a/packages/next/components/ui/TextField.css b/packages/next/components/ui/TextField.css new file mode 100644 index 0000000..0288cc8 --- /dev/null +++ b/packages/next/components/ui/TextField.css @@ -0,0 +1,13 @@ +@import "tailwindcss"; + +.border-middle-idle-empty { + @apply border-y-[1px]; +} + +.border-middle-idle { + @apply border-y-[1px] border-t-0; +} + +.border-middle-focus { + @apply border-primary dark:border-dark-primary border-y-2 border-t-0; +} diff --git a/packages/next/components/ui/TextField.tsx b/packages/next/components/ui/TextField.tsx new file mode 100644 index 0000000..a40795b --- /dev/null +++ b/packages/next/components/ui/TextField.tsx @@ -0,0 +1,107 @@ +"use client"; + +import React, { useState } from "react"; + +interface InputProps extends React.HTMLAttributes { + labelText?: string; + type?: React.HTMLInputTypeAttribute; + inputText?: string; + onInputTextChange?: (value: string) => void; + maxChar?: number; + supportingText?: string; + variant?: "filled" | "outlined" | "standard"; +} + +const OutlineTextField: React.FC = ({ + labelText = "", + type = "text", + inputText: initialInputText = "", + onInputTextChange, + maxChar, + supportingText, + ...rest +}) => { + const [focus, setFocus] = useState(false); + const [inputText, setInputText] = useState(initialInputText); + + const handleValueChange = (event: React.ChangeEvent) => { + const { value } = event.target; + setInputText(value); + onInputTextChange?.(value); + }; + + return ( +
+
+
+
+ +
+ + {labelText} + +
+ +
+
+ + setFocus(true)} + onBlur={() => setFocus(false)} + onChange={handleValueChange} + type={type} + value={inputText} + /> +
+ {(supportingText || maxChar) && ( +
+ {supportingText && {supportingText}} + {maxChar && ( + maxChar ? "text-red-500" : ""}`}> + {inputText.length}/{maxChar} + + )} +
+ )} +
+ ); +}; + +const TextField: React.FC = (props) => { + if (!props.variant || props.variant === "outlined") { + return ; + } +}; + +export default TextField; diff --git a/packages/next/components/utils/404.tsx b/packages/next/components/utils/404.tsx new file mode 100644 index 0000000..3a10b24 --- /dev/null +++ b/packages/next/components/utils/404.tsx @@ -0,0 +1,20 @@ +import { getCurrentUser } from "@/lib/userAuth"; +import { Header } from "@/components/shell/Header"; +import { Link } from "@/i18n/navigation"; +import { getTranslations } from "next-intl/server"; + +export const NotFound = async () => { + const user = await getCurrentUser(); + const t = await getTranslations("not_found"); + return ( + <> +
+ +
+

404

+

{t("title")}

+ {t("back_to_home")} +
+ + ); +}; diff --git a/packages/next/components/utils/DarkModeImage.tsx b/packages/next/components/utils/DarkModeImage.tsx new file mode 100644 index 0000000..1aed745 --- /dev/null +++ b/packages/next/components/utils/DarkModeImage.tsx @@ -0,0 +1,55 @@ +"use client"; + +import { useState, useEffect } from "react"; +import Image from "next/image"; + +interface Props { + lightSrc: string; + darkSrc: string; + alt?: string; + className?: string; + width?: number; + height?: number; +} + +const DarkModeImage = ({ lightSrc, darkSrc, alt = "", className = "", width, height }: Props) => { + const [isDarkMode, setIsDarkMode] = useState(false); + const [currentSrc, setCurrentSrc] = useState(lightSrc); + const [opacity, setOpacity] = useState(0); + + useEffect(() => { + const handleDarkModeChange = (event: MediaQueryListEvent) => { + setIsDarkMode(event.matches); + setCurrentSrc(event.matches ? darkSrc : lightSrc); + setOpacity(1); + }; + + const darkModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); + setIsDarkMode(darkModeMediaQuery.matches); + setCurrentSrc(darkModeMediaQuery.matches ? darkSrc : lightSrc); + setOpacity(1); + + darkModeMediaQuery.addEventListener("change", handleDarkModeChange); + + return () => { + darkModeMediaQuery.removeEventListener("change", handleDarkModeChange); + }; + }, [darkSrc, lightSrc]); + + useEffect(() => { + setCurrentSrc(isDarkMode ? darkSrc : lightSrc); + }, [isDarkMode, darkSrc, lightSrc]); + + return ( + {alt} + ); +}; + +export default DarkModeImage; diff --git a/packages/next/components/utils/LocalizedRichText.tsx b/packages/next/components/utils/LocalizedRichText.tsx new file mode 100644 index 0000000..8a28df7 --- /dev/null +++ b/packages/next/components/utils/LocalizedRichText.tsx @@ -0,0 +1,20 @@ +import { ReactNode } from "react"; + +// These tags are available +type Tag = "p" | "b" | "i"; + +type Props = { + children(tags: Record ReactNode>): ReactNode; +}; + +export default function LocalizedRichText({ children }: Props) { + return ( +
+ {children({ + p: (chunks: ReactNode) =>

{chunks}

, + b: (chunks: ReactNode) => {chunks}, + i: (chunks: ReactNode) => {chunks} + })} +
+ ); +} diff --git a/packages/next/components/utils/Portal.tsx b/packages/next/components/utils/Portal.tsx new file mode 100644 index 0000000..d76d2d7 --- /dev/null +++ b/packages/next/components/utils/Portal.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import ReactDOM from "react-dom"; + +export const Portal = ({ children }: { children: React.ReactNode }) => { + const documentNotUndefined = typeof document !== "undefined"; + // Ensure portal root exists in your HTML + const portalRoot = documentNotUndefined ? document.getElementById("portal-root") : null; + + if (!portalRoot) { + return null; + } + + return ReactDOM.createPortal(children, portalRoot); +}; diff --git a/packages/next/components/utils/ripple.css b/packages/next/components/utils/ripple.css new file mode 100644 index 0000000..4f44890 --- /dev/null +++ b/packages/next/components/utils/ripple.css @@ -0,0 +1,15 @@ +.ripple { + position: absolute; + border-radius: 50%; + transform: scale(0); + opacity: 0.2; + animation: ripple-effect 0.8s linear; + background-color: currentColor; +} + +@keyframes ripple-effect { + to { + transform: scale(4); + opacity: 0; + } +} diff --git a/packages/next/components/utils/useRipple.tsx b/packages/next/components/utils/useRipple.tsx new file mode 100644 index 0000000..10887e8 --- /dev/null +++ b/packages/next/components/utils/useRipple.tsx @@ -0,0 +1,90 @@ +import "./ripple.css"; + +import { useCallback, useRef } from "react"; + +interface UseRippleOptions { + ripple?: boolean; +} + +const useRipple = ({ ripple = true }: UseRippleOptions = {}) => { + const isTouchEventRef = useRef(false); + + const resetTouchFlag = useCallback(() => { + isTouchEventRef.current = false; + }, []); + + const handleMouseDown = useCallback( + (event: React.MouseEvent) => { + if (!ripple) return; + + if (isTouchEventRef.current) { + // Skip mouse event if this was a touch interaction + return; + } + + // Proceed with mouse ripple + createRippleEffect(event); + }, + [ripple] + ); + + const handleTouchStart = useCallback( + (event: React.TouchEvent) => { + if (!ripple) return; + + isTouchEventRef.current = true; + + // Proceed with touch ripple + createRippleEffect(event); + }, + [ripple, resetTouchFlag] + ); + + const handleTouchEnd = useCallback( + (_event: React.TouchEvent) => { + if (!ripple) return; + + isTouchEventRef.current = false; + }, + [ripple, resetTouchFlag] + ); + + const createRippleEffect = (event: React.MouseEvent | React.TouchEvent) => { + const target = event.currentTarget; + const rect = target.getBoundingClientRect(); + + let x = 0; + let y = 0; + + if ("touches" in event) { + x = event.touches[0].clientX - rect.left; + y = event.touches[0].clientY - rect.top; + } else { + x = event.clientX - rect.left; + y = event.clientY - rect.top; + } + + const diameter = Math.max(rect.width, rect.height); + const rippleElement = document.createElement("span"); + + rippleElement.style.width = `${diameter}px`; + rippleElement.style.height = `${diameter}px`; + rippleElement.style.left = `${x - diameter / 2}px`; + rippleElement.style.top = `${y - diameter / 2}px`; + rippleElement.classList.add("ripple"); + + target.appendChild(rippleElement); + + rippleElement.addEventListener("animationend", () => { + rippleElement.remove(); + }); + }; + + return { + onMouseDown: ripple ? handleMouseDown : undefined, + onTouchStart: ripple ? handleTouchStart : undefined, + ontouchend: ripple ? handleTouchEnd : undefined + }; +}; + +export default useRipple; diff --git a/packages/next/content/about.mdx b/packages/next/content/about.mdx new file mode 100644 index 0000000..de549dd --- /dev/null +++ b/packages/next/content/about.mdx @@ -0,0 +1,60 @@ +# 关于「中 V 档案馆」 + +「中 V 档案馆」是一个旨在收录与展示「中文歌声合成作品」及有关信息的网站。 + +## 创建背景与关联工作 + +纵观整个互联网,对于「中文歌声合成」或「中文虚拟歌手」(常简称为中 V 或 VC)相关信息进行较为系统、全面地整理收集的主要有以下几个网站: + +- [萌娘百科](https://zh.moegirl.org.cn/): + 收录了大量中 V 歌曲及歌姬的信息,呈现形式为传统维基(基于 [MediaWiki](https://www.mediawiki.org/))。 +- [VCPedia](https://vcpedia.cn/): + 由原萌娘百科中文歌声合成编辑团队的部分成员搭建,专属于中文歌声合成相关内容的信息集成站点 [^1],呈现形式为传统维基(基于 [MediaWiki](https://www.mediawiki.org/))。 +- [VocaDB](https://vocadb.net/): 一个围绕 Vocaloid、UTAU 和其他歌声合成器的协作数据库,其中包含艺术家、唱片、PV + 等 [^2],其中包含大量中文歌声合成作品。 +- [天钿 Daily](https://tdd.bunnyxt.com/):一个 VC 相关数据交流与分享的网站。致力于 VC 相关数据交流,定期抓取 VC 相关数据,选取有意义的纬度展示。[^3] + +上述网站中,或多或少存在一些不足,例如: + +- 萌娘百科、VCPedia 受限于传统维基,绝大多数内容依赖人工编辑。 +- VocaDB 基于结构化数据库构建,由此可以依赖程序生成一些信息,但 **条目收录** 仍然完全依赖人工完成。 +- VocaDB 主要专注于元数据展示,少有关于歌曲、作者等的描述性的文字,也缺乏描述性的背景信息。 +- 天钿 Daily 只展示歌曲的统计数据及历史趋势,没有关于歌曲其它信息的收集。 + +因此,**中 V 档案馆** 吸取前人经验,克服上述网站的不足,希望做到: + +- 歌曲收录(指发现歌曲并创建条目)的完全自动化 +- 歌曲元信息提取的高度自动化 +- 歌曲统计数据收集的完全自动化 +- 在程序辅助的同时欢迎并鼓励贡献者参与编辑(主要为描述性内容)或纠错 +- 在适当的许可声明下,引用来自上述源的数据,使内容更加全面、丰富。 + +## 技术架构 + +参见 [CVSA 文档](https://docs.projectcvsa.com/)。 + +## 开放许可 + +受本文以 [CC BY-NC-SA 4.0 协议](https://creativecommons.org/licenses/by-nc-sa/4.0/) 提供。 + +### 数据库 + +中 V 档案馆使用 [PostgreSQL](https://postgresql.org) 作为数据库,我们承诺定期导出数据库转储 (dump) +文件并公开,其内容遵从以下协议或条款: + +- 数据库中的事实性数据,根据适用法律,不构成受版权保护的内容。中 V 档案馆放弃一切可能的权利([CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/))。 +- 对于数据库中有原创性的内容(如贡献者编辑的描述性内容),如无例外,以 [CC BY 4.0 协议](https://creativecommons.org/licenses/by/4.0/) 提供。 +- 对于引用、摘编或改编自萌娘百科、VCPedia 的内容,以与原始协议(CC BY-NC-SA 3.0 + CN)兼容的协议 [CC BY-NC-SA 4.0 协议](https://creativecommons.org/licenses/by-nc-sa/4.0/) 提供,并注明原始协议 。 + > 根据原始协议第四条第 2 项内容,CC BY-NC-SA 4.0 协议为与原始协议具有相同授权要素的后续版本(“可适用的协议”)。 +- 中 V 档案馆文档使用 [CC BY 4.0 协议](https://creativecommons.org/licenses/by/4.0/)。 + +### 软件代码 + +用于构建中 V 档案馆的软件代码在 [AGPL 3.0](https://www.gnu.org/licenses/agpl-3.0.html) 许可证下公开,参见 [LICENSE](./LICENSE) + +[^1]: 引用自 [VCPedia](https://vcpedia.cn/%E9%A6%96%E9%A1%B5),于 [知识共享 署名-非商业性使用-相同方式共享 3.0中国大陆 (CC BY-NC-SA 3.0 CN) 许可协议](https://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 下提供。 + +[^2]: 翻译自 [VocaDB](https://vocadb.net/),于 [CC BY 4.0协议](https://creativecommons.org/licenses/by/4.0/) 下提供。 + +[^3]: 引用自 [关于 - 天钿Daily](https://tdd.bunnyxt.com/about) diff --git a/packages/next/i18n/navigation.ts b/packages/next/i18n/navigation.ts new file mode 100644 index 0000000..298692d --- /dev/null +++ b/packages/next/i18n/navigation.ts @@ -0,0 +1,6 @@ +import { createNavigation } from "next-intl/navigation"; +import { routing } from "./routing"; + +// Lightweight wrappers around Next.js' navigation +// APIs that consider the routing configuration +export const { Link, redirect, usePathname, useRouter, getPathname } = createNavigation(routing); diff --git a/packages/next/i18n/request.ts b/packages/next/i18n/request.ts new file mode 100644 index 0000000..ca75fef --- /dev/null +++ b/packages/next/i18n/request.ts @@ -0,0 +1,21 @@ +import { getRequestConfig } from "next-intl/server"; +import { hasLocale } from "next-intl"; +import { routing } from "./routing"; +import zh from "./strings/zh.json"; +import en from "./strings/en.json"; + +const stringsMap = { + zh: zh, + en: en +}; + +export default getRequestConfig(async ({ requestLocale }) => { + // Typically corresponds to the `[locale]` segment + const requested = await requestLocale; + const locale = hasLocale(routing.locales, requested) ? requested : routing.defaultLocale; + + return { + locale, + messages: stringsMap[locale] + }; +}); diff --git a/packages/next/i18n/routing.ts b/packages/next/i18n/routing.ts new file mode 100644 index 0000000..d0a7470 --- /dev/null +++ b/packages/next/i18n/routing.ts @@ -0,0 +1,11 @@ +import { defineRouting } from "next-intl/routing"; + +export const routing = defineRouting({ + // A list of all locales that are supported + locales: ["en", "zh"], + + // Used when no locale matches + defaultLocale: "zh", + + localePrefix: "as-needed" +}); diff --git a/packages/next/i18n/strings/en.json b/packages/next/i18n/strings/en.json new file mode 100644 index 0000000..d26dcd9 --- /dev/null +++ b/packages/next/i18n/strings/en.json @@ -0,0 +1,6 @@ +{ + "not_found": { + "title": "The page you requested cannot be found.", + "back_to_home": "Back to Home" + } +} diff --git a/packages/next/i18n/strings/zh.json b/packages/next/i18n/strings/zh.json new file mode 100644 index 0000000..66017e1 --- /dev/null +++ b/packages/next/i18n/strings/zh.json @@ -0,0 +1,36 @@ +{ + "yup_errors": { + "field_too_short": "{field}至少需要 {min} 个字符。", + "field_too_big": "{field}不能多于 {max} 个字符。", + "field_required": "请填写{field}。" + }, + "username": "用户名", + "password": "密码", + "nickname": "昵称", + "backend": { + "error": { + "captcha_failed": "无法完成安全验证。", + "user_exists": "用户名 “{username}” 已被占用。", + "user_not_found_after_register": "我们的服务器出现错误:找不到名为'{username}'的用户。请联系我们的支持团队,反馈此问题。", + "captcha_not_found": "无法完成安全验证。你可以刷新页面并重试。如果此问题反复出现,你可以联系我们的支持团队,反馈此问题。" + }, + "error_code": { + "INVALID_QUERY_PARAMS": "查询无效", + "UNKNOWN_ERROR": "未知错误", + "INVALID_PAYLOAD": "请求格式错误", + "INVALID_FORMAT": "数据格式错误", + "INVALID_HEADER": "请求头无效", + "BODY_TOO_LARGE": "请求体过大", + "UNAUTHORIZED": "未授权", + "INVALID_CREDENTIALS": "凭证无效", + "ENTITY_NOT_FOUND": "实体不存在", + "SERVER_ERROR": "服务器错误", + "RATE_LIMIT_EXCEEDED": "请求过于频繁", + "ENTITY_EXISTS": "实体已存在" + } + }, + "not_found": { + "title": "咦……页面去哪里了(゚Д゚≡゚д゚)!?", + "back_to_home": "带我回首页!" + } +} diff --git a/packages/next/lib/const.ts b/packages/next/lib/const.ts new file mode 100644 index 0000000..f6bf80c --- /dev/null +++ b/packages/next/lib/const.ts @@ -0,0 +1,25 @@ +const N_1024 = BigInt( + "129023318876534346704360951712586568674758913224876821534686030409476129469193481910786173836188085930974906857867802234113909470848523288588793477904039083513378341278558405407018889387577114155572311708428733260891448259786041525189132461448841652472631435226032063278124857443496954605482776113964107326943" +); + +const N_2048 = BigInt( + "23987552118069940970878653610463005981599204778388399885550631951871084945075866571231062435627294546200946516668493107358732376187241747090707087544153108117326163500579370560400058549184722138636116585329496684877258304519458316233517215780035360354808658620079068489084797380781488445517430961701007542207001544091884001098497324624368085682074645221148086075871342544591022944384890014176612259729018968864426602901247715051556212559854689574013699665035317257438297910516976812428036717668766321871780963854649899276251822244719887233041422346429752896925499321431273560130952088238625622570366815755926694833109" +); + +const N_1792 = BigInt( + "23987552118069940970878653610463005981599204778388399885550631951871084945075866571231062435627294546200946516668493107358732376187241747090707087544153108117326163500579370560400058549184722138636116585329496684877258304519458316233517215780035360354808658620079068489084797380781488445517430961701007542207001544091884001098497324624368085682074645221148086075871342544591022944384890014176612259729018968864426602901247715051556212559854689574013699665035317257438297910516976812428036717668766321871780963854649899276251822244719887233041422346429752896925499321431273560130952088238625622570366815755926694833109" +); + +const N_1536 = BigInt( + "1694330250214463438908848400950857073137355630337290254958754184668036770489801447652464038218330711288158361242955860326168191830448553710492926795708495297280933502917598985378231124113971732841791156356676046934277122699383776036675381503510992810963611269045078440132744168908318454891211962146563551929591147663448816841024591820348784855441153716551049843185172472891407933214238000452095646085222944171689449292644270516031799660928056315886939284985905227" +); + +const N_3072 = BigInt( + "4432919939296042464443862503456460073874727648022810391370558006281079088795179408238989283371442564716849343712703672836423961818025813387453469700639513190304802553045342607888612037304066433501317127429264242784608682213025490491212489901736408833027611579294436675682774458141490718959615677971745638214649336218217578937534746160749039668886450447773018369168258067682196337978245372237157696236362344796867228581553446331915147012787367438751646936429739232247148712001806846526947508445039707404287951727838234648917450736371192435665040644040487427986702098273581288935278964444790007953559851323281510927332862225214878776790605026472021669614552481167977412450477230442015077669503312683966631454347169703030544483487968842349634064181183599641180349414682042575010303056241481622837185325228233789954078775053744988023738762706404546546146837242590884760044438874357295029411988267287001033032827035809135092270843" +); + +const N_4096 = BigInt( + "703671044356805218391078271512201582198770553281951369783674142891088501340774249238173262580562112786670043634665390581120113644316651934154746357220932310140476300088580654571796404198410555061275065442553506658401183560336140989074165998202690496991174269748740565700402715364422506782445179963440819952745241176450402011121226863984008975377353558155910994380700267903933205531681076494639818328879475919332604951949178075254600102192323286738973253864238076198710173840170988339024438220034106150475640983877458155141500313471699516670799821379238743709125064098477109094533426340852518505385314780319279862586851512004686798362431227795743253799490998475141728082088984359237540124375439664236138519644100625154580910233437864328111620708697941949936338367445851449766581651338876219676721272448769082914348242483068204896479076062102236087066428603930888978596966798402915747531679758905013008059396214343112694563043918465373870648649652122703709658068801764236979191262744515840224548957285182453209028157886219424802426566456408109642062498413592155064289314088837031184200671561102160059065729282902863248815224399131391716503171191977463328439766546574118092303414702384104112719959325482439604572518549918705623086363111" +); + +export const N_ARRAY = [N_1024, N_1536, N_1792, N_2048, N_3072, N_4096]; diff --git a/packages/next/lib/db/bilibili_metadata/aidExists.ts b/packages/next/lib/db/bilibili_metadata/aidExists.ts new file mode 100644 index 0000000..72ee127 --- /dev/null +++ b/packages/next/lib/db/bilibili_metadata/aidExists.ts @@ -0,0 +1,8 @@ +import { sql } from "@cvsa/core"; + +export async function aidExists(aid: number) { + const res = await sql` + SELECT 1 FROM bilibili_metadata WHERE aid = ${aid} + `; + return res.length > 0; +} diff --git a/packages/next/lib/db/bilibili_metadata/getAidFromBV.ts b/packages/next/lib/db/bilibili_metadata/getAidFromBV.ts new file mode 100644 index 0000000..afa925f --- /dev/null +++ b/packages/next/lib/db/bilibili_metadata/getAidFromBV.ts @@ -0,0 +1,15 @@ +import { sql } from "@cvsa/core"; + +export async function getAidFromBV(bv: string) { + const res = await sql` + SELECT aid FROM bilibili_metadata WHERE bvid = ${bv} + `; + if (res.length <= 0) { + return null; + } + const row = res[0]; + if (row && row.aid) { + return Number(row.aid); + } + return null; +} diff --git a/packages/next/lib/db/bilibili_metadata/getVideoMetadata.ts b/packages/next/lib/db/bilibili_metadata/getVideoMetadata.ts new file mode 100644 index 0000000..a8f12b6 --- /dev/null +++ b/packages/next/lib/db/bilibili_metadata/getVideoMetadata.ts @@ -0,0 +1,15 @@ +import { BiliVideoMetadataType, sql } from "@cvsa/core"; + +export async function getVideoMetadata(aid: number) { + const res = await sql` + SELECT * FROM bilibili_metadata WHERE aid = ${aid} + `; + if (res.length <= 0) { + return null; + } + const row = res[0]; + if (row) { + return row; + } + return null; +} diff --git a/packages/next/lib/db/snapshots/getAllSnapshots.ts b/packages/next/lib/db/snapshots/getAllSnapshots.ts new file mode 100644 index 0000000..655600b --- /dev/null +++ b/packages/next/lib/db/snapshots/getAllSnapshots.ts @@ -0,0 +1,11 @@ +import { VideoSnapshotType, sql } from "@cvsa/core"; + +export async function getAllSnapshots(aid: number) { + const res = await sql` + SELECT * FROM video_snapshot WHERE aid = ${aid} ORDER BY created_at DESC + `; + if (res.length <= 0) { + return null; + } + return res; +} diff --git a/packages/next/lib/db/user.ts b/packages/next/lib/db/user.ts new file mode 100644 index 0000000..cf3be0b --- /dev/null +++ b/packages/next/lib/db/user.ts @@ -0,0 +1,19 @@ +import { UserType, sqlCred } from "@cvsa/core"; + +export const getUserBySession = async (sessionID: string) => { + const users = await sqlCred` + SELECT u.* + FROM users u + JOIN login_sessions ls ON u.id = ls.uid + WHERE ls.id = ${sessionID}; + `; + if (users.length === 0) { + return undefined; + } + const user = users[0]; + return { + username: user.username, + nickname: user.nickname, + role: user.role + }; +}; diff --git a/packages/next/lib/net.ts b/packages/next/lib/net.ts new file mode 100644 index 0000000..87cfbe5 --- /dev/null +++ b/packages/next/lib/net.ts @@ -0,0 +1,57 @@ +import axios, { AxiosRequestConfig, AxiosError, Method } from "axios"; + +export class ApiRequestError extends Error { + public code: number | undefined; + public response: unknown | undefined; + constructor(message: string, res?: unknown, code?: number) { + super(message); + this.name = "ApiRequestError"; + this.code = code; + this.response = res; + } +} + +type HttpMethod = Extract; + +const httpMethods = { + get: axios.get, + post: axios.post, + put: axios.put, + delete: axios.delete, + patch: axios.patch +}; + +export async function fetcher( + url: string, + init?: Omit & { method?: HttpMethod } +): Promise { + const { method = "get", data, ...config } = init || {}; + + const fullConfig: AxiosRequestConfig = { + method, + ...config, + timeout: 10000 + }; + + try { + const m = method.toLowerCase() as keyof typeof httpMethods; + if (["post", "patch", "put"].includes(m)) { + const response = await httpMethods[m](url, data, fullConfig); + return response.data; + } else { + const response = await httpMethods[m](url, fullConfig); + return response.data; + } + } catch (error) { + const axiosError = error as AxiosError; + + if (axiosError.response) { + const { status, data } = axiosError.response; + throw new ApiRequestError(`HTTP error! status: ${status}`, data, status); + } else if (axiosError.request) { + throw new ApiRequestError("No response received", undefined, -1); + } else { + throw new ApiRequestError(axiosError.message || "Unknown error"); + } + } +} diff --git a/packages/next/lib/userAuth.ts b/packages/next/lib/userAuth.ts new file mode 100644 index 0000000..eadf81c --- /dev/null +++ b/packages/next/lib/userAuth.ts @@ -0,0 +1,17 @@ +import { cookies } from "next/headers"; +import { getUserBySession } from "@/lib/db/user"; +import type { UserResponse } from "@cvsa/backend"; + +export async function getCurrentUser(): Promise { + const cookieStore = await cookies(); + const sessionID = cookieStore.get("session_id"); + + if (!sessionID) return null; + + try { + const user = await getUserBySession(sessionID.value); + return user ?? null; + } catch (error) { + return null; + } +} diff --git a/packages/next/lib/vdf.ts b/packages/next/lib/vdf.ts new file mode 100644 index 0000000..97f2b90 --- /dev/null +++ b/packages/next/lib/vdf.ts @@ -0,0 +1,117 @@ +// Define interfaces for input and output +interface VdfProgressCallback { + (progress: number): void; +} + +interface VdfResult { + result: bigint; + time: number; // Time taken in milliseconds +} + +// The content of the Web Worker script +const workerContent = `addEventListener("message", async (event) => { + const { g, N, difficulty } = event.data; + + // Although pow is not used in the iterative VDF, it's good to keep the original worker code structure. + // The iterative computeVDFWithProgress is better for progress reporting. + function pow(base, exponent, mod) { + let result = 1n; + base = base % mod; + while (exponent > 0n) { + if (exponent % 2n === 1n) { + result = (result * base) % mod; + } + base = (base * base) % mod; + exponent = exponent / 2n; + // Using BigInt division (/) which performs integer division + } + return result; + } + + // Compute VDF iteratively to report progress + function computeVDFWithProgress(g, N, T, postProgress) { + let result = g; + let latestTime = performance.now(); + const totalSteps = T; // T is the difficulty, representing 2^T squaring steps + + for (let i = 0n; i < totalSteps; i++) { + result = (result * result) % N; + // Report progress periodically (approx. every 16ms to match typical frame rate) + if (performance.now() - latestTime > 16) { + // Calculate progress as a percentage + const progress = Number((i + 1n) * 10000n / totalSteps) / 100; // Using 10000 for better precision before dividing by 100 + postProgress(progress); + latestTime = performance.now(); + } + } + // Ensure final progress is reported + postProgress(100); + return result; + } + + const startTime = performance.now(); + // The worker computes g^(2^difficulty) mod N. The loop runs 'difficulty' times, performing squaring. + const result = computeVDFWithProgress(g, N, difficulty, (progress) => { + // Post progress back to the main thread + postMessage({ type: "progress", progress: progress }); + }); + const endTime = performance.now(); + const timeTaken = endTime - startTime; + + // Post the final result and time taken back to the main thread + postMessage({ type: "result", result: result.toString(), time: timeTaken }); +}); +`; + +/** + * Computes the Verifiable Delay Function (VDF) result g^(2^difficulty) mod N + * in a Web Worker and reports progress. + * @param g - The base (bigint). + * @param N - The modulus (bigint). + * @param difficulty - The number of squaring steps (T) (bigint). + * @param onProgress - Optional callback function to receive progress updates (0-100). + * @returns A Promise that resolves with the VDF result and time taken. + */ +export function computeVdfInWorker( + g: bigint, + N: bigint, + difficulty: bigint, + onProgress?: VdfProgressCallback +): Promise { + return new Promise((resolve, reject) => { + // Create a Blob containing the worker script + const blob = new Blob([workerContent], { type: "text/javascript" }); + // Create a URL for the Blob + const workerUrl = URL.createObjectURL(blob); + // Create a new Web Worker + const worker = new window.Worker(workerUrl); + + // Handle messages from the worker + worker.onmessage = (event) => { + const { type, progress, result, time } = event.data; + + if (type === "progress") { + if (onProgress) { + onProgress(progress); + } + } else if (type === "result") { + // Resolve the promise with the result and time + resolve({ result: BigInt(result), time }); + // Terminate the worker and revoke the URL + worker.terminate(); + URL.revokeObjectURL(workerUrl); + } + }; + + // Handle potential errors in the worker + worker.onerror = (error) => { + reject(error); + // Terminate the worker and revoke the URL in case of error + worker.terminate(); + URL.revokeObjectURL(workerUrl); + }; + + // Post the data to the worker to start the computation + worker.postMessage({ g, N, difficulty }); + }); +} diff --git a/packages/next/middleware.ts b/packages/next/middleware.ts new file mode 100644 index 0000000..2396cbc --- /dev/null +++ b/packages/next/middleware.ts @@ -0,0 +1,11 @@ +import createMiddleware from "next-intl/middleware"; +import { routing } from "@/i18n/routing"; + +export default createMiddleware(routing); + +export const config = { + // Match all pathnames except for + // - … if they start with `/api`, `/trpc`, `/_next` or `/_vercel` + // - … the ones containing a dot (e.g. `favicon.ico`) + matcher: "/((?!api|trpc|_next|_vercel|.*\\..*).*)" +}; diff --git a/packages/next/next.config.ts b/packages/next/next.config.ts new file mode 100644 index 0000000..65522c6 --- /dev/null +++ b/packages/next/next.config.ts @@ -0,0 +1,17 @@ +import type { NextConfig } from "next"; +import createNextIntlPlugin from "next-intl/plugin"; +import { createMDX } from "fumadocs-mdx/next"; + +const nextConfig: NextConfig = { + devIndicators: false, + experimental: { + externalDir: true + }, + pageExtensions: ["js", "jsx", "md", "mdx", "ts", "tsx"] +}; + +const withNextIntl = createNextIntlPlugin(); + +const withMDX = createMDX(); + +export default withNextIntl(withMDX(nextConfig)); diff --git a/packages/next/package.json b/packages/next/package.json new file mode 100644 index 0000000..f0f4bf5 --- /dev/null +++ b/packages/next/package.json @@ -0,0 +1,40 @@ +{ + "name": "next", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev --turbopack -p 7400", + "build": "next build", + "start": "next start -p 7400", + "lint": "next lint", + "format": "prettier --write ." + }, + "dependencies": { + "@cvsa/backend": "^0.5.3", + "@cvsa/core": "^0.0.5", + "@mdx-js/loader": "^3.1.0", + "@mdx-js/react": "^3.1.0", + "@next/mdx": "^15.3.3", + "@types/mdx": "^2.0.13", + "axios": "^1.9.0", + "date-fns": "^4.1.0", + "framer-motion": "^12.15.0", + "fumadocs-mdx": "^11.6.6", + "i18next": "^25.2.1", + "next": "^15.3.3", + "next-intl": "^4.1.0", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "swr": "^2.3.3", + "ua-parser-js": "^2.0.3", + "yup": "^1.6.1" + }, + "devDependencies": { + "typescript": "^5.8.3", + "@types/node": "^20.17.57", + "@types/react": "^19.1.6", + "@types/react-dom": "^19.1.5", + "@tailwindcss/postcss": "^4.1.8", + "tailwindcss": "^4.1.8" + } +} diff --git a/packages/next/postcss.config.mjs b/packages/next/postcss.config.mjs new file mode 100644 index 0000000..6f4b2ef --- /dev/null +++ b/packages/next/postcss.config.mjs @@ -0,0 +1,5 @@ +const config = { + plugins: ["@tailwindcss/postcss"] +}; + +export default config; diff --git a/packages/next/public/icons/TitleBar Mobile Dark.svg b/packages/next/public/icons/TitleBar Mobile Dark.svg new file mode 100644 index 0000000..7a48bfb --- /dev/null +++ b/packages/next/public/icons/TitleBar Mobile Dark.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/packages/next/public/icons/TitleBar Mobile Light.svg b/packages/next/public/icons/TitleBar Mobile Light.svg new file mode 100644 index 0000000..87ffa43 --- /dev/null +++ b/packages/next/public/icons/TitleBar Mobile Light.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/packages/next/public/icons/标题-浅色.svg b/packages/next/public/icons/标题-浅色.svg new file mode 100644 index 0000000..c32ce5f --- /dev/null +++ b/packages/next/public/icons/标题-浅色.svg @@ -0,0 +1,15 @@ + + + Created with Pixso. + + + + + + + + + + + + diff --git a/packages/next/public/icons/标题-深色.svg b/packages/next/public/icons/标题-深色.svg new file mode 100644 index 0000000..acd623a --- /dev/null +++ b/packages/next/public/icons/标题-深色.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/next/source.config.ts b/packages/next/source.config.ts new file mode 100644 index 0000000..e74c9d9 --- /dev/null +++ b/packages/next/source.config.ts @@ -0,0 +1,5 @@ +import { defineConfig } from "fumadocs-mdx/config"; + +export default defineConfig({ + mdxOptions: {} +}); diff --git a/packages/next/tsconfig.json b/packages/next/tsconfig.json new file mode 100644 index 0000000..57002be --- /dev/null +++ b/packages/next/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2020", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +}