diff --git a/.dockerignore b/.dockerignore index a3913dc28..db3d1a13e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -60,3 +60,5 @@ node_modules example* .git/ + +js/coverage/ diff --git a/.github/composite/test/frontend-test/action.yml b/.github/composite/test/frontend-test/action.yml index 72ad5875f..cb27361bc 100644 --- a/.github/composite/test/frontend-test/action.yml +++ b/.github/composite/test/frontend-test/action.yml @@ -8,6 +8,10 @@ inputs: GPG_PASSPHRASE: description: "GPG Passphrase" required: true + UPLOAD_TEST_COV: + description: "Boolean indicating whether tests should be uploaded to Codecov or not." + required: false + default: false runs: using: "composite" @@ -33,6 +37,11 @@ runs: java-version: "25" cache: "maven" + - name: Expose GitHub Runtime + uses: crazy-max/ghaction-github-runtime@v3 + - name: Run script shell: bash run: bun .github/scripts/test/run-frontend-tests + env: + UPLOAD_TEST_COV: ${{ inputs.UPLOAD_TEST_COV }} diff --git a/.github/scripts/test/run-frontend-tests.ts b/.github/scripts/test/run-frontend-tests.ts index 805a201e4..1c8f2cef7 100644 --- a/.github/scripts/test/run-frontend-tests.ts +++ b/.github/scripts/test/run-frontend-tests.ts @@ -2,9 +2,15 @@ import { $ } from "bun"; import { getEnvVariables } from "load-secrets/env/load"; import { backend } from "utils/run-backend-instance"; import { db } from "utils/run-local-db"; +import { uploadFrontendTests } from "utils/upload"; async function main() { try { + const shouldUploadCoverage = process.env.UPLOAD_TEST_COV === "true"; + const ciEnv = + shouldUploadCoverage ? await getEnvVariables(["ci"]) : undefined; + const codecovToken = ciEnv ? parseCiEnv(ciEnv).codecovToken : undefined; + const ciAppEnv = await getEnvVariables(["ci-app"]); const localDbEnv = await db.start(); await backend.start({ ...ciAppEnv, ...localDbEnv }); @@ -19,12 +25,28 @@ async function main() { await $`pnpm --dir js i --frozen-lockfile`; await $$`pnpm --dir js run generate`; await $$`pnpm --dir js run test`; + + if (shouldUploadCoverage && codecovToken) { + await uploadFrontendTests(codecovToken); + } } finally { await backend.end(); await db.end(); } } +function parseCiEnv(ciEnv: Record) { + const codecovToken = (() => { + const v = ciEnv["CODECOV_TOKEN"]; + if (!v) { + throw new Error("Missing CODECOV_TOKEN from .env.ci"); + } + return v; + })(); + + return { codecovToken }; +} + main() .then(() => { process.exit(0); diff --git a/.github/scripts/utils/upload.ts b/.github/scripts/utils/upload.ts index 798da71b1..7e6454906 100644 --- a/.github/scripts/utils/upload.ts +++ b/.github/scripts/utils/upload.ts @@ -6,10 +6,17 @@ export async function uploadBackendTests(token: string) { const dir = path.join(process.cwd(), "target/site/jacoco/"); await uploadArtifact(dir, "backend-jacoco-report"); - await uploadToCodecov(token, dir); + await uploadToCodecov(token, dir, "backend"); } -async function uploadToCodecov(token: string, dir: string) { +export async function uploadFrontendTests(token: string) { + const dir = path.join(process.cwd(), "js/coverage/"); + + await uploadArtifact(dir, "frontend-coverage-report"); + await uploadToCodecov(token, dir, "frontend"); +} + +async function uploadToCodecov(token: string, dir: string, flag: string) { try { const { exitCode } = Bun.spawnSync(["./codecov", "--help"]); if (exitCode != 0) { @@ -37,8 +44,17 @@ async function uploadToCodecov(token: string, dir: string) { } try { - console.log(`Uploading reports from ${dir} to Codecov...`); - const p2 = Bun.spawnSync(["./codecov", "do-upload", "--dir", dir]); + console.log( + `Uploading reports from ${dir} to Codecov with flag: ${flag}...`, + ); + const p2 = Bun.spawnSync([ + "./codecov", + "do-upload", + "--dir", + dir, + "--flag", + flag, + ]); if (p2.exitCode != 0) { throw new Error(`Failed to load Codecov process\n\n${p2.stderr}`); } diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 7701cfce3..4a4985080 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,6 +58,7 @@ jobs: with: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + UPLOAD_TEST_COV: true testBuildImage: name: Build Test Docker Image diff --git a/.gitignore b/.gitignore index 15e65a900..742e3903e 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,5 @@ node_modules scripts/**/index.js /node_modules + +js/coverage/ diff --git a/.vscode/extensions.json b/.vscode/extensions.json index db1e01286..fa317c4e1 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -12,7 +12,7 @@ "vmware.vscode-boot-dev-pack", "bradlc.vscode-tailwindcss", "redhat.vscode-xml", - "emeraldwalk.runonsave" + "emeraldwalk.runonsave", + "vitest.explorer" ] } - diff --git a/codecov.yml b/codecov.yml index 2ef90639b..d63e4c5bc 100644 --- a/codecov.yml +++ b/codecov.yml @@ -2,19 +2,54 @@ codecov: require_ci_to_pass: false notify: wait_for_ci: false + after_n_builds: 2 + +flags: + backend: + paths: + - src/main/java/ + carryforward: true + frontend: + paths: + - js/src/ + carryforward: true + coverage: status: project: default: + target: 60% + informational: true + backend: target: 60% flags: - backend informational: true + frontend: + target: 60% + flags: + - frontend + informational: true patch: default: informational: false target: 80% threshold: 5% only_pulls: true + backend: + target: 80% + threshold: 5% + only_pulls: true + flags: + - backend + informational: false + frontend: + target: 80% + threshold: 5% + only_pulls: true + flags: + - frontend + informational: false + comment: behavior: new # delete old and post new. diff --git a/example.env b/example.env index d3b4430af..5043a4efe 100644 --- a/example.env +++ b/example.env @@ -83,3 +83,6 @@ ACTUATOR_PASSWORD= # (Optional for dev) # Check `.env.example.ci` for details on how it's used, or the CI tech doc page on the wiki REDIS_URL= + +# set to "true" to enable mocked APIs in frontend. +VITE_MOCK= diff --git a/example.env.staging b/example.env.staging index ff98b2b33..fa1a64e88 100644 --- a/example.env.staging +++ b/example.env.staging @@ -51,3 +51,7 @@ SECRET_KEY= DOCKER_HUB_PAT= DIGITAL_OCEAN_PAT= DIGITAL_OCEAN_APP_ID= + +# used by the frontend to load certain feature flags. +# looks for the string literal "true" +VITE_STAGING=true diff --git a/js/package.json b/js/package.json index 870067f86..da54d1a93 100644 --- a/js/package.json +++ b/js/package.json @@ -7,7 +7,8 @@ "dev": "vite", "build": "vite build", "typecheck": "tsc -b --noEmit", - "test": "pnpm run typecheck && pnpm run prettier && pnpm run lint && pnpm run build", + "vt": "vitest run --coverage", + "test": "pnpm run typecheck && pnpm run prettier && pnpm run lint && pnpm run build && pnpm run vt", "fix": "pnpm run eslint:fix && pnpm run stylelint:fix && pnpm run prettier:fix", "lint": "pnpm run eslint && pnpm run stylelint", "generate": "openapi-typescript http://localhost:8080/v3/api-docs -o src/lib/api/types/schema.ts --properties-required-by-default --enum --make-paths-enum --dedupe-enums && prettier --write \"src/lib/api/types/schema.ts\"", @@ -50,10 +51,15 @@ "@eslint/js": "^9.17.0", "@eslint/plugin-kit": ">=0.3.4", "@tailwindcss/postcss": "^4.1.14", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@testing-library/user-event": "^14.6.1", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "@types/react-syntax-highlighter": "^15.5.13", "@vitejs/plugin-react": "^4.3.4", + "@vitest/coverage-v8": "4.0.18", "eslint": "^9.17.0", "eslint-plugin-no-relative-import-paths": "^1.6.1", "eslint-plugin-perfectionist": "^4.8.0", @@ -61,6 +67,8 @@ "eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-refresh": "^0.4.16", "globals": "^15.14.0", + "jsdom": "^27.4.0", + "msw": "^2.12.7", "nodemon": "^3.1.10", "openapi-typescript": "7.8.0", "postcss": "^8.4.49", @@ -75,8 +83,10 @@ "tailwindcss": "^4.1.14", "typescript": "~5.6.3", "typescript-eslint": "^8.19.0", + "uuid": "^13.0.0", "vite": ">=6.4.1", - "vite-tsconfig-paths": "^5.1.4" + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^4.0.18" }, "packageManager": "pnpm@10.24.0", "pnpm": { diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 6323d7a9f..8d69db96a 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -101,6 +101,18 @@ importers: '@tailwindcss/postcss': specifier: ^4.1.14 version: 4.1.14 + '@testing-library/dom': + specifier: ^10.4.1 + version: 10.4.1 + '@testing-library/jest-dom': + specifier: ^6.9.1 + version: 6.9.1 + '@testing-library/react': + specifier: ^16.3.2 + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@testing-library/user-event': + specifier: ^14.6.1 + version: 14.6.1(@testing-library/dom@10.4.1) '@types/react': specifier: ^18.3.18 version: 18.3.18 @@ -113,6 +125,9 @@ importers: '@vitejs/plugin-react': specifier: ^4.3.4 version: 4.3.4(vite@7.3.0(@types/node@24.0.10)(jiti@2.6.1)(lightningcss@1.30.1)(sass@1.83.1)(yaml@2.7.0)) + '@vitest/coverage-v8': + specifier: 4.0.18 + version: 4.0.18(vitest@4.0.18(@types/node@24.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.1)(msw@2.12.7(@types/node@24.0.10)(typescript@5.6.3))(sass@1.83.1)(yaml@2.7.0)) eslint: specifier: ^9.17.0 version: 9.17.0(jiti@2.6.1) @@ -134,6 +149,12 @@ importers: globals: specifier: ^15.14.0 version: 15.14.0 + jsdom: + specifier: ^27.4.0 + version: 27.4.0 + msw: + specifier: ^2.12.7 + version: 2.12.7(@types/node@24.0.10)(typescript@5.6.3) nodemon: specifier: ^3.1.10 version: 3.1.10 @@ -176,15 +197,27 @@ importers: typescript-eslint: specifier: ^8.19.0 version: 8.19.0(eslint@9.17.0(jiti@2.6.1))(typescript@5.6.3) + uuid: + specifier: ^13.0.0 + version: 13.0.0 vite: specifier: '>=6.4.1' version: 7.3.0(@types/node@24.0.10)(jiti@2.6.1)(lightningcss@1.30.1)(sass@1.83.1)(yaml@2.7.0) vite-tsconfig-paths: specifier: ^5.1.4 version: 5.1.4(typescript@5.6.3)(vite@7.3.0(@types/node@24.0.10)(jiti@2.6.1)(lightningcss@1.30.1)(sass@1.83.1)(yaml@2.7.0)) + vitest: + specifier: ^4.0.18 + version: 4.0.18(@types/node@24.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.1)(msw@2.12.7(@types/node@24.0.10)(typescript@5.6.3))(sass@1.83.1)(yaml@2.7.0) packages: + '@acemir/cssom@0.9.31': + resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} + + '@adobe/css-tools@4.4.4': + resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -193,6 +226,15 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@asamuzakjp/css-color@4.1.1': + resolution: {integrity: sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==} + + '@asamuzakjp/dom-selector@6.7.6': + resolution: {integrity: sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==} + + '@asamuzakjp/nwsapi@2.3.9': + resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@babel/code-frame@7.26.2': resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} @@ -231,10 +273,18 @@ packages: resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} @@ -248,6 +298,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.28.6': + resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-transform-react-jsx-self@7.25.9': resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} engines: {node: '>=6.9.0'} @@ -276,16 +331,55 @@ packages: resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.6': + resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + '@csstools/css-parser-algorithms@3.0.4': resolution: {integrity: sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==} engines: {node: '>=18'} peerDependencies: '@csstools/css-tokenizer': ^3.0.3 + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-syntax-patches-for-csstree@1.0.26': + resolution: {integrity: sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==} + '@csstools/css-tokenizer@3.0.3': resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==} engines: {node: '>=18'} + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + '@csstools/media-query-list-parser@4.0.2': resolution: {integrity: sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A==} engines: {node: '>=18'} @@ -496,6 +590,15 @@ packages: resolution: {integrity: sha512-rSXBsAcmx80jI9OUevyNBU0f5pZRQJkNmk4bLX6hCbm1qKe5Z/TcU7vwXc2nR8814mhRlgbZIHL1+HSiYS0VkQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@exodus/bytes@1.10.0': + resolution: {integrity: sha512-tf8YdcbirXdPnJ+Nd4UN1EXnz+IP2DI45YVEr3vvzcVTOyrApkmIB4zvOQVd3XPr7RXnfBtAx+PXImXOIU0Ajg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@noble/hashes': ^1.8.0 || ^2.0.0 + peerDependenciesMeta: + '@noble/hashes': + optional: true + '@floating-ui/core@1.7.2': resolution: {integrity: sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==} @@ -537,6 +640,41 @@ packages: resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} engines: {node: '>=18.18'} + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} + engines: {node: '>=18'} + + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + engines: {node: '>=18'} + + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} @@ -565,6 +703,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@keyv/serialize@1.0.2': resolution: {integrity: sha512-+E/LyaAeuABniD/RvUezWVXKpeuvwLEA9//nE9952zBaOdBd2mQ3pPoM8cUe2X6IcMByfuSLzmYqnYshG60+HQ==} @@ -610,6 +751,10 @@ packages: '@microsoft/fetch-event-source@2.0.1': resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==} + '@mswjs/interceptors@0.40.0': + resolution: {integrity: sha512-EFd6cVbHsgLa6wa4RljGj6Wk75qoHxUSyc5asLyyPSyuhIcdS2Q3Phw6ImS1q+CkALthJRShiYfKANcQMuMqsQ==} + engines: {node: '>=18'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -622,6 +767,15 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@parcel/watcher-android-arm64@2.5.0': resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==} engines: {node: '>= 10.0.0'} @@ -839,6 +993,9 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@tabler/icons-react@3.30.0': resolution: {integrity: sha512-9KZ9D1UNAyjlLkkYp2HBPHdf6lAJ2aelDqh8YYAnnmLF3xwprWKxxW8+zw5jlI0IwdfN4XFFuzqePkaw+DpIOg==} peerDependencies: @@ -952,6 +1109,38 @@ packages: peerDependencies: react: ^18 || ^19 + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react@16.3.2': + resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -964,9 +1153,15 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} @@ -1005,6 +1200,9 @@ packages: '@types/react@18.3.18': resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} + '@types/statuses@2.0.6': + resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -1092,6 +1290,44 @@ packages: peerDependencies: vite: '>=6.4.1' + '@vitest/coverage-v8@4.0.18': + resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==} + peerDependencies: + '@vitest/browser': 4.0.18 + vitest: 4.0.18 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@4.0.18': + resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} + + '@vitest/mocker@4.0.18': + resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} + peerDependencies: + msw: ^2.4.9 + vite: '>=6.4.1' + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.0.18': + resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} + + '@vitest/runner@4.0.18': + resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} + + '@vitest/snapshot@4.0.18': + resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} + + '@vitest/spy@4.0.18': + resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} + + '@vitest/utils@4.0.18': + resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1124,6 +1360,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -1131,6 +1371,9 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + array-buffer-byte-length@1.0.2: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} @@ -1163,6 +1406,13 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-v8-to-istanbul@0.3.10: + resolution: {integrity: sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==} + astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -1184,6 +1434,9 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -1232,6 +1485,10 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -1263,6 +1520,14 @@ packages: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -1289,6 +1554,10 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + cosmiconfig@9.0.0: resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} @@ -1310,14 +1579,25 @@ packages: resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true + cssstyle@5.3.7: + resolution: {integrity: sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==} + engines: {node: '>=20'} + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + data-urls@6.0.1: + resolution: {integrity: sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==} + engines: {node: '>=20'} + data-view-buffer@1.0.2: resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} engines: {node: '>= 0.4'} @@ -1342,6 +1622,9 @@ packages: supports-color: optional: true + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decode-named-character-reference@1.2.0: resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} @@ -1383,6 +1666,12 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} @@ -1400,6 +1689,10 @@ packages: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -1423,6 +1716,9 @@ packages: resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -1519,10 +1815,17 @@ packages: estree-util-is-identifier-name@3.0.0: resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1607,6 +1910,10 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -1675,6 +1982,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphql@16.12.0: + resolution: {integrity: sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -1715,9 +2026,19 @@ packages: hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + hookified@1.14.0: resolution: {integrity: sha512-pi1ynXIMFx/uIIwpWJ/5CEtOHLGtnUB0WhGeeYT+fKcQ+WCQbm3/rrkAXnpfph++PgepNqPdTC2WTj8A6k6zoQ==} + html-encoding-sniffer@6.0.0: + resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-tags@3.3.1: resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} engines: {node: '>=8'} @@ -1725,6 +2046,10 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -1757,6 +2082,10 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + index-to-position@1.1.0: resolution: {integrity: sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==} engines: {node: '>=18'} @@ -1850,6 +2179,9 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -1862,6 +2194,9 @@ packages: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -1904,6 +2239,18 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + iterator.prototype@1.1.5: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} @@ -1919,10 +2266,22 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsdom@27.4.0: + resolution: {integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -2057,12 +2416,30 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lru-cache@11.2.5: + resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + magic-string@0.30.19: resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.5.1: + resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + mantine-form-zod-resolver@1.3.0: resolution: {integrity: sha512-XlXXkJCYuUuOllW0zedYW+m/lbdFQ/bso1Vz+pJOYkxgjhoGvzN2EXWCS2+0iTOT9Q7WnOwWvHmvpTJN3PxSXw==} engines: {node: '>=16.6.0'} @@ -2182,6 +2559,10 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2204,6 +2585,20 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + msw@2.12.7: + resolution: {integrity: sha512-retd5i3xCZDVWMYjHEVuKTmhqY8lSsxujjVrZiGbbdoxxIBg5S7rCuYy/YQpfrTYIxpd/o0Kyb/3H+1udBMoYg==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2264,6 +2659,9 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + oniguruma-parser@0.12.1: resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} @@ -2280,6 +2678,9 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + own-keys@1.0.1: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} @@ -2307,6 +2708,9 @@ packages: resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} engines: {node: '>=18'} + parse5@8.0.0: + resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2318,10 +2722,16 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2420,6 +2830,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -2449,6 +2863,9 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-number-format@5.4.4: resolution: {integrity: sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==} peerDependencies: @@ -2539,6 +2956,10 @@ packages: resolution: {integrity: sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==} engines: {node: '>= 14.18.0'} + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -2556,6 +2977,10 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} @@ -2572,6 +2997,9 @@ packages: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true + rettime@0.7.0: + resolution: {integrity: sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==} + reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2601,6 +3029,10 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -2652,6 +3084,9 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} @@ -2675,10 +3110,23 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2709,6 +3157,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -2803,6 +3255,9 @@ packages: svg-tags@1.0.0: resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} @@ -2825,10 +3280,28 @@ packages: resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==} engines: {node: '>=18'} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + + tldts-core@7.0.19: + resolution: {integrity: sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==} + + tldts@7.0.19: + resolution: {integrity: sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==} + hasBin: true + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -2837,6 +3310,14 @@ packages: resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} hasBin: true + tough-cookie@6.0.0: + resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} + engines: {node: '>=16'} + + tr46@6.0.0: + resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} + engines: {node: '>=20'} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -2873,6 +3354,10 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + type-fest@5.4.1: + resolution: {integrity: sha512-xygQcmneDyzsEuKZrFbRMne5HDqMs++aFzefrJTgEIKjQ3rekM+RPfFCVq2Gp1VIDqddoYeppCj4Pcb+RZW0GQ==} + engines: {node: '>=20'} + type-fest@https://codeload.github.com/tahminator/type-fest/tar.gz/fa55f482694f080ad051297bbb53f42bbbe4ae4b: resolution: {tarball: https://codeload.github.com/tahminator/type-fest/tar.gz/fa55f482694f080ad051297bbb53f42bbbe4ae4b} version: 5.4.1 @@ -2931,6 +3416,9 @@ packages: unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + until-async@3.0.2: + resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} + update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -3005,6 +3493,10 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@13.0.0: + resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} + hasBin: true + vfile-message@4.0.3: resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} @@ -3059,6 +3551,60 @@ packages: yaml: optional: true + vitest@4.0.18: + resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.18 + '@vitest/browser-preview': 4.0.18 + '@vitest/browser-webdriverio': 4.0.18 + '@vitest/ui': 4.0.18 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + webidl-conversions@8.0.1: + resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} + engines: {node: '>=20'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-mimetype@5.0.0: + resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} + engines: {node: '>=20'} + + whatwg-url@15.1.0: + resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==} + engines: {node: '>=20'} + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -3084,14 +3630,50 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + write-file-atomic@5.0.1: resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -3111,10 +3693,18 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -3123,6 +3713,10 @@ packages: snapshots: + '@acemir/cssom@0.9.31': {} + + '@adobe/css-tools@4.4.4': {} + '@alloc/quick-lru@5.2.0': {} '@ampproject/remapping@2.3.0': @@ -3130,6 +3724,24 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 + '@asamuzakjp/css-color@4.1.1': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 11.2.5 + + '@asamuzakjp/dom-selector@6.7.6': + dependencies: + '@asamuzakjp/nwsapi': 2.3.9 + bidi-js: 1.0.3 + css-tree: 3.1.0 + is-potential-custom-element-name: 1.0.1 + lru-cache: 11.2.5 + + '@asamuzakjp/nwsapi@2.3.9': {} + '@babel/code-frame@7.26.2': dependencies: '@babel/helper-validator-identifier': 7.25.9 @@ -3194,8 +3806,12 @@ snapshots: '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-option@7.25.9': {} '@babel/helpers@7.26.0': @@ -3207,6 +3823,10 @@ snapshots: dependencies: '@babel/types': 7.26.3 + '@babel/parser@7.28.6': + dependencies: + '@babel/types': 7.28.6 + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -3242,12 +3862,41 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@babel/types@7.28.6': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@bcoe/v8-coverage@1.0.2': {} + + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3)': dependencies: '@csstools/css-tokenizer': 3.0.3 + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-syntax-patches-for-csstree@1.0.26': {} + '@csstools/css-tokenizer@3.0.3': {} + '@csstools/css-tokenizer@3.0.4': {} + '@csstools/media-query-list-parser@4.0.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) @@ -3383,6 +4032,8 @@ snapshots: '@eslint/core': 1.0.0 levn: 0.4.1 + '@exodus/bytes@1.10.0': {} + '@floating-ui/core@1.7.2': dependencies: '@floating-ui/utils': 0.2.10 @@ -3421,6 +4072,34 @@ snapshots: '@humanwhocodes/retry@0.4.1': {} + '@inquirer/ansi@1.0.2': {} + + '@inquirer/confirm@5.1.21(@types/node@24.0.10)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.0.10) + '@inquirer/type': 3.0.10(@types/node@24.0.10) + optionalDependencies: + '@types/node': 24.0.10 + + '@inquirer/core@10.3.2(@types/node@24.0.10)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.0.10) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.0.10 + + '@inquirer/figures@1.0.15': {} + + '@inquirer/type@3.0.10(@types/node@24.0.10)': + optionalDependencies: + '@types/node': 24.0.10 + '@isaacs/fs-minipass@4.0.1': dependencies: minipass: 7.1.2 @@ -3449,6 +4128,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + '@keyv/serialize@1.0.2': dependencies: buffer: 6.0.3 @@ -3501,6 +4185,15 @@ snapshots: '@microsoft/fetch-event-source@2.0.1': {} + '@mswjs/interceptors@0.40.0': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3513,6 +4206,15 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.18.0 + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + '@parcel/watcher-android-arm64@2.5.0': optional: true @@ -3692,6 +4394,8 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} + '@standard-schema/spec@1.1.0': {} + '@tabler/icons-react@3.30.0(react@18.3.1)': dependencies: '@tabler/icons': 3.30.0 @@ -3786,6 +4490,42 @@ snapshots: '@tanstack/query-core': 5.64.2 react: 18.3.1 + '@testing-library/dom@10.4.1': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/runtime': 7.27.6 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.4.4 + aria-query: 5.3.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 + + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.27.6 + '@testing-library/dom': 10.4.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': + dependencies: + '@testing-library/dom': 10.4.1 + + '@types/aria-query@5.0.4': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.26.3 @@ -3807,10 +4547,17 @@ snapshots: dependencies: '@babel/types': 7.26.3 + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + '@types/debug@4.1.12': dependencies: '@types/ms': 2.1.0 + '@types/deep-eql@4.0.2': {} + '@types/estree-jsx@1.0.5': dependencies: '@types/estree': 1.0.8 @@ -3851,6 +4598,8 @@ snapshots: '@types/prop-types': 15.7.14 csstype: 3.1.3 + '@types/statuses@2.0.6': {} + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} @@ -3982,6 +4731,60 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@types/node@24.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.1)(msw@2.12.7(@types/node@24.0.10)(typescript@5.6.3))(sass@1.83.1)(yaml@2.7.0))': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.0.18 + ast-v8-to-istanbul: 0.3.10 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + magicast: 0.5.1 + obug: 2.1.1 + std-env: 3.10.0 + tinyrainbow: 3.0.3 + vitest: 4.0.18(@types/node@24.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.1)(msw@2.12.7(@types/node@24.0.10)(typescript@5.6.3))(sass@1.83.1)(yaml@2.7.0) + + '@vitest/expect@4.0.18': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + chai: 6.2.2 + tinyrainbow: 3.0.3 + + '@vitest/mocker@4.0.18(msw@2.12.7(@types/node@24.0.10)(typescript@5.6.3))(vite@7.3.0(@types/node@24.0.10)(jiti@2.6.1)(lightningcss@1.30.1)(sass@1.83.1)(yaml@2.7.0))': + dependencies: + '@vitest/spy': 4.0.18 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + msw: 2.12.7(@types/node@24.0.10)(typescript@5.6.3) + vite: 7.3.0(@types/node@24.0.10)(jiti@2.6.1)(lightningcss@1.30.1)(sass@1.83.1)(yaml@2.7.0) + + '@vitest/pretty-format@4.0.18': + dependencies: + tinyrainbow: 3.0.3 + + '@vitest/runner@4.0.18': + dependencies: + '@vitest/utils': 4.0.18 + pathe: 2.0.3 + + '@vitest/snapshot@4.0.18': + dependencies: + '@vitest/pretty-format': 4.0.18 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.0.18': {} + + '@vitest/utils@4.0.18': + dependencies: + '@vitest/pretty-format': 4.0.18 + tinyrainbow: 3.0.3 + acorn-jsx@5.3.2(acorn@8.14.0): dependencies: acorn: 8.14.0 @@ -4012,6 +4815,8 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -4019,6 +4824,10 @@ snapshots: argparse@2.0.1: {} + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + array-buffer-byte-length@1.0.2: dependencies: call-bound: 1.0.4 @@ -4078,6 +4887,14 @@ snapshots: get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 + assertion-error@2.0.1: {} + + ast-v8-to-istanbul@0.3.10: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 9.0.1 + astral-regex@2.0.0: {} async-function@1.0.0: {} @@ -4092,6 +4909,10 @@ snapshots: base64-js@1.5.1: {} + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + binary-extensions@2.3.0: {} brace-expansion@1.1.11: @@ -4145,6 +4966,8 @@ snapshots: ccount@2.0.1: {} + chai@6.2.2: {} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -4178,6 +5001,14 @@ snapshots: chownr@3.0.0: {} + cli-width@4.1.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + clsx@2.1.1: {} color-convert@2.0.1: @@ -4196,6 +5027,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie@1.1.1: {} + cosmiconfig@9.0.0(typescript@5.6.3): dependencies: env-paths: 2.2.1 @@ -4218,10 +5051,24 @@ snapshots: mdn-data: 2.12.2 source-map-js: 1.2.1 + css.escape@1.5.1: {} + cssesc@3.0.0: {} + cssstyle@5.3.7: + dependencies: + '@asamuzakjp/css-color': 4.1.1 + '@csstools/css-syntax-patches-for-csstree': 1.0.26 + css-tree: 3.1.0 + lru-cache: 11.2.5 + csstype@3.1.3: {} + data-urls@6.0.1: + dependencies: + whatwg-mimetype: 5.0.0 + whatwg-url: 15.1.0 + data-view-buffer@1.0.2: dependencies: call-bound: 1.0.4 @@ -4258,6 +5105,8 @@ snapshots: optionalDependencies: supports-color: 5.5.0 + decimal.js@10.6.0: {} + decode-named-character-reference@1.2.0: dependencies: character-entities: 2.0.2 @@ -4297,6 +5146,10 @@ snapshots: dependencies: esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + dom-helpers@5.2.1: dependencies: '@babel/runtime': 7.27.6 @@ -4317,6 +5170,8 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.3.0 + entities@6.0.1: {} + env-paths@2.2.1: {} error-ex@1.3.2: @@ -4403,6 +5258,8 @@ snapshots: iterator.prototype: 1.1.5 safe-array-concat: 1.1.3 + es-module-lexer@1.7.0: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -4567,8 +5424,14 @@ snapshots: estree-util-is-identifier-name@3.0.0: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + esutils@2.0.3: {} + expect-type@1.3.0: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.2: @@ -4655,6 +5518,8 @@ snapshots: gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -4729,6 +5594,8 @@ snapshots: graphemer@1.4.0: {} + graphql@16.12.0: {} + has-bigints@1.1.0: {} has-flag@3.0.0: {} @@ -4791,12 +5658,36 @@ snapshots: dependencies: '@types/hast': 3.0.4 + headers-polyfill@4.0.3: {} + hookified@1.14.0: {} + html-encoding-sniffer@6.0.0: + dependencies: + '@exodus/bytes': 1.10.0 + transitivePeerDependencies: + - '@noble/hashes' + + html-escaper@2.0.2: {} + html-tags@3.3.1: {} html-void-elements@3.0.0: {} + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + https-proxy-agent@7.0.6(supports-color@10.0.0): dependencies: agent-base: 7.1.3 @@ -4823,6 +5714,8 @@ snapshots: imurmurhash@0.1.4: {} + indent-string@4.0.0: {} + index-to-position@1.1.0: {} ini@1.3.8: {} @@ -4915,6 +5808,8 @@ snapshots: is-negative-zero@2.0.3: {} + is-node-process@1.2.0: {} + is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -4924,6 +5819,8 @@ snapshots: is-plain-object@5.0.0: {} + is-potential-custom-element-name@1.0.1: {} + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -4967,6 +5864,19 @@ snapshots: isexe@2.0.0: {} + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + iterator.prototype@1.1.5: dependencies: define-data-property: 1.1.4 @@ -4982,10 +5892,40 @@ snapshots: js-tokens@4.0.0: {} + js-tokens@9.0.1: {} + js-yaml@4.1.0: dependencies: argparse: 2.0.1 + jsdom@27.4.0: + dependencies: + '@acemir/cssom': 0.9.31 + '@asamuzakjp/dom-selector': 6.7.6 + '@exodus/bytes': 1.10.0 + cssstyle: 5.3.7 + data-urls: 6.0.1 + decimal.js: 10.6.0 + html-encoding-sniffer: 6.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + parse5: 8.0.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 6.0.0 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 8.0.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 15.1.0 + ws: 8.19.0 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - '@noble/hashes' + - bufferutil + - supports-color + - utf-8-validate + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -5087,14 +6027,32 @@ snapshots: dependencies: js-tokens: 4.0.0 + lru-cache@11.2.5: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 + lz-string@1.5.0: {} + magic-string@0.30.19: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.5.1: + dependencies: + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.6.3 + mantine-form-zod-resolver@1.3.0(@mantine/form@8.1.2(react@18.3.1))(zod@3.25.76): dependencies: '@mantine/form': 8.1.2(react@18.3.1) @@ -5339,6 +6297,8 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + min-indent@1.0.1: {} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -5359,6 +6319,33 @@ snapshots: ms@2.1.3: {} + msw@2.12.7(@types/node@24.0.10)(typescript@5.6.3): + dependencies: + '@inquirer/confirm': 5.1.21(@types/node@24.0.10) + '@mswjs/interceptors': 0.40.0 + '@open-draft/deferred-promise': 2.2.0 + '@types/statuses': 2.0.6 + cookie: 1.1.1 + graphql: 16.12.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + rettime: 0.7.0 + statuses: 2.0.2 + strict-event-emitter: 0.5.1 + tough-cookie: 6.0.0 + type-fest: 5.4.1 + until-async: 3.0.2 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - '@types/node' + + mute-stream@2.0.0: {} + nanoid@3.3.11: {} nanoid@3.3.8: {} @@ -5423,6 +6410,8 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + obug@2.1.1: {} + oniguruma-parser@0.12.1: {} oniguruma-to-es@4.3.4: @@ -5450,6 +6439,8 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + outvariant@1.4.3: {} + own-keys@1.0.1: dependencies: get-intrinsic: 1.3.0 @@ -5491,14 +6482,22 @@ snapshots: index-to-position: 1.1.0 type-fest: 4.41.0 + parse5@8.0.0: + dependencies: + entities: 6.0.1 + path-exists@4.0.0: {} path-key@3.1.1: {} path-parse@1.0.7: {} + path-to-regexp@6.3.0: {} + path-type@4.0.0: {} + pathe@2.0.3: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -5583,6 +6582,12 @@ snapshots: prettier@3.5.0: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -5609,6 +6614,8 @@ snapshots: react-is@16.13.1: {} + react-is@17.0.2: {} + react-number-format@5.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: react: 18.3.1 @@ -5698,6 +6705,11 @@ snapshots: readdirp@4.1.1: {} + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -5728,6 +6740,8 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + require-directory@2.1.1: {} + require-from-string@2.0.2: {} resolve-from@4.0.0: {} @@ -5740,6 +6754,8 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + rettime@0.7.0: {} + reusify@1.0.4: {} rollup@4.44.0: @@ -5799,6 +6815,10 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.5.0 + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + scheduler@0.23.2: dependencies: loose-envify: 1.4.0 @@ -5874,6 +6894,8 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} + signal-exit@4.1.0: {} simple-update-notifier@2.0.0: @@ -5892,11 +6914,19 @@ snapshots: space-separated-tokens@2.0.2: {} + stackback@0.0.2: {} + + statuses@2.0.2: {} + + std-env@3.10.0: {} + stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 internal-slot: 1.1.0 + strict-event-emitter@0.5.1: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -5956,6 +6986,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + strip-json-comments@3.1.1: {} style-to-js@1.1.21: @@ -6080,6 +7114,8 @@ snapshots: svg-tags@1.0.0: {} + symbol-tree@3.2.4: {} + tabbable@6.2.0: {} table@6.9.0: @@ -6104,17 +7140,37 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 + tinybench@2.9.0: {} + + tinyexec@1.0.2: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyrainbow@3.0.3: {} + + tldts-core@7.0.19: {} + + tldts@7.0.19: + dependencies: + tldts-core: 7.0.19 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 touch@3.1.1: {} + tough-cookie@6.0.0: + dependencies: + tldts: 7.0.19 + + tr46@6.0.0: + dependencies: + punycode: 2.3.1 + trim-lines@3.0.1: {} ts-api-utils@1.4.3(typescript@5.6.3): @@ -6137,6 +7193,10 @@ snapshots: type-fest@4.41.0: {} + type-fest@5.4.1: + dependencies: + tagged-tag: 1.0.0 + type-fest@https://codeload.github.com/tahminator/type-fest/tar.gz/fa55f482694f080ad051297bbb53f42bbbe4ae4b: dependencies: tagged-tag: 1.0.0 @@ -6221,6 +7281,8 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 + until-async@3.0.2: {} + update-browserslist-db@1.1.1(browserslist@4.24.3): dependencies: browserslist: 4.24.3 @@ -6278,6 +7340,8 @@ snapshots: util-deprecate@1.0.2: {} + uuid@13.0.0: {} + vfile-message@4.0.3: dependencies: '@types/unist': 3.0.3 @@ -6315,6 +7379,59 @@ snapshots: sass: 1.83.1 yaml: 2.7.0 + vitest@4.0.18(@types/node@24.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.1)(msw@2.12.7(@types/node@24.0.10)(typescript@5.6.3))(sass@1.83.1)(yaml@2.7.0): + dependencies: + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(msw@2.12.7(@types/node@24.0.10)(typescript@5.6.3))(vite@7.3.0(@types/node@24.0.10)(jiti@2.6.1)(lightningcss@1.30.1)(sass@1.83.1)(yaml@2.7.0)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.0(@types/node@24.0.10)(jiti@2.6.1)(lightningcss@1.30.1)(sass@1.83.1)(yaml@2.7.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.0.10 + jsdom: 27.4.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + webidl-conversions@8.0.1: {} + + whatwg-mimetype@4.0.0: {} + + whatwg-mimetype@5.0.0: {} + + whatwg-url@15.1.0: + dependencies: + tr46: 6.0.0 + webidl-conversions: 8.0.1 + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -6364,13 +7481,38 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + write-file-atomic@5.0.1: dependencies: imurmurhash: 0.1.4 signal-exit: 4.1.0 + ws@8.19.0: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + + y18n@5.0.8: {} + yallist@3.1.1: {} yallist@5.0.0: {} @@ -6382,8 +7524,20 @@ snapshots: yargs-parser@21.1.1: {} + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + yocto-queue@0.1.0: {} + yoctocolors-cjs@2.1.3: {} + zod@3.25.76: {} zwitch@2.0.4: {} diff --git a/js/src/__mocks__/index.tsx b/js/src/__mocks__/index.tsx new file mode 100644 index 000000000..6896556a8 --- /dev/null +++ b/js/src/__mocks__/index.tsx @@ -0,0 +1,8 @@ +import { successfulLeaderboardHandlers } from "@/__mocks__/leaderboard"; +import { setupWorker } from "msw/browser"; + +export const handlers = [...successfulLeaderboardHandlers]; +export const launchMockServer = () => { + const worker = setupWorker(...handlers); + return worker.start(); +}; diff --git a/js/src/__mocks__/leaderboard/index.ts b/js/src/__mocks__/leaderboard/index.ts new file mode 100644 index 000000000..6244f1a7d --- /dev/null +++ b/js/src/__mocks__/leaderboard/index.ts @@ -0,0 +1,109 @@ +import { ApiURL } from "@/lib/api/common/apiURL"; +import d from "dayjs"; +import { http, HttpResponse } from "msw"; +import { v4 as uuid } from "uuid"; + +const currentMetadata = ApiURL.create("/api/leaderboard/current/metadata", { + method: "GET", +}); + +export const MOCK_LEADERBOARD_ID = uuid(); +const metadataById = ApiURL.create( + "/api/leaderboard/{leaderboardId}/metadata", + { + method: "GET", + params: { + leaderboardId: MOCK_LEADERBOARD_ID, + }, + }, +); + +export const currentMetadataNoSyntaxHighlightingHandler = http.get( + currentMetadata.url.toString(), + () => { + return HttpResponse.json({ + payload: { + id: uuid(), + createdAt: d().toISOString(), + shouldExpireBy: d().add(10, "days").toISOString(), + syntaxHighlightingLanguage: null, + name: "haiii", + deletedAt: null, + }, + success: true, + message: "Leaderboard metadata loaded!", + } satisfies ReturnType); + }, +); +export const metadataByIdNoSyntaxHighlightingHandler = http.get( + metadataById.url.toString(), + () => { + return HttpResponse.json({ + payload: { + id: uuid(), + createdAt: d().toISOString(), + shouldExpireBy: d().add(10, "days").toISOString(), + syntaxHighlightingLanguage: null, + name: "haiii", + deletedAt: null, + }, + success: true, + message: "Leaderboard metadata loaded!", + } satisfies ReturnType); + }, +); + +export const successfulLeaderboardHandlers = [ + http.get(currentMetadata.url.toString(), () => { + return HttpResponse.json({ + payload: { + id: uuid(), + createdAt: d().toISOString(), + shouldExpireBy: d().add(10, "days").toISOString(), + syntaxHighlightingLanguage: "cpp", + name: 'std::string november = "hello world"', + deletedAt: null, + }, + success: true, + message: "Leaderboard metadata loaded!", + } satisfies ReturnType); + }), + http.get(metadataById.url.toString(), () => { + return HttpResponse.json({ + payload: { + id: uuid(), + createdAt: d().toISOString(), + shouldExpireBy: d().add(10, "days").toISOString(), + syntaxHighlightingLanguage: "cpp", + name: 'std::string november = "hello world"', + deletedAt: null, + }, + success: true, + message: "Leaderboard metadata loaded!", + } satisfies ReturnType); + }), +]; + +export const failedLeaderboardHandlers = [ + http.get(currentMetadata.url.toString(), () => { + return HttpResponse.json({ + success: false, + message: "Leaderboard metadata failed to load", + } satisfies ReturnType); + }), + http.get(metadataById.url.toString(), () => { + return HttpResponse.json({ + success: false, + message: "Leaderboard metadata failed to load", + } satisfies ReturnType); + }), +]; + +export const catastrophicLeaderboardHandlers = [ + http.get(currentMetadata.url.toString(), () => { + return HttpResponse.error(); + }), + http.get(metadataById.url.toString(), () => { + return HttpResponse.error(); + }), +]; diff --git a/js/src/app/leaderboard/_components/LeaderboardMetadata/LeaderboardMetadata.test.tsx b/js/src/app/leaderboard/_components/LeaderboardMetadata/LeaderboardMetadata.test.tsx new file mode 100644 index 000000000..822749e69 --- /dev/null +++ b/js/src/app/leaderboard/_components/LeaderboardMetadata/LeaderboardMetadata.test.tsx @@ -0,0 +1,406 @@ +import { + catastrophicLeaderboardHandlers, + currentMetadataNoSyntaxHighlightingHandler, + failedLeaderboardHandlers, + metadataByIdNoSyntaxHighlightingHandler, + MOCK_LEADERBOARD_ID, + successfulLeaderboardHandlers, +} from "@/__mocks__/leaderboard"; +import { + CurrentLeaderboardMetadata, + LeaderboardMetadataById, +} from "@/app/leaderboard/_components/LeaderboardMetadata/LeaderboardMetadata"; +import { TestUtils, TestUtilTypes } from "@/lib/test"; +import { screen, waitFor } from "@testing-library/react"; +import { setupServer } from "msw/node"; + +describe("CurrentLeaderboardMetadata API Succeeded", () => { + const server = setupServer(...successfulLeaderboardHandlers); + + beforeAll(() => server.listen()); + afterEach(() => { + server.resetHandlers(); + }); + afterAll(() => server.close()); + + let renderProviderFn: TestUtilTypes.RenderWithAllProvidersFn | null = null; + beforeEach(() => { + renderProviderFn = TestUtils.getRenderWithAllProvidersFn(); + }); + + it("should render loading state initially", () => { + renderProviderFn?.(); + + const element = screen.getByTestId("leaderboard-skeleton-name"); + expect(element).toBeInTheDocument(); + expect(element).toBeVisible(); + }); + + it("should render leaderboard name after successful API call", async () => { + renderProviderFn?.(); + + await waitFor(() => { + const heading = screen.getByTestId("LeaderboardMetadata-title"); + expect(heading).toHaveTextContent('std::string november = "hello world"'); + expect(heading).toBeVisible(); + }); + }); + + it("should render leaderboard title with syntax highlighting", async () => { + renderProviderFn?.(); + + await waitFor(() => { + const titleElement = screen.getByTestId("shiki-container"); + expect(titleElement).toBeInTheDocument(); + expect(titleElement).toBeVisible(); + }); + }); + + it("should render leaderboard title without syntax highlighting", async () => { + server.use(currentMetadataNoSyntaxHighlightingHandler); + + renderProviderFn?.(); + + await waitFor(() => { + const titleElement = screen.queryByTestId("shiki-container"); + expect(titleElement).not.toBeInTheDocument(); + }); + + await waitFor(() => { + const titleElement = screen.queryByText("haiii"); + expect(titleElement).toBeInTheDocument(); + expect(titleElement).toBeVisible(); + }); + }); + + it("should render clock in leaderboard if prop is enabled", async () => { + renderProviderFn?.(); + + await waitFor(() => { + const counter = screen.getByTestId("PrettyCounter"); + expect(counter).toBeInTheDocument(); + expect(counter).toBeVisible(); + }); + }); + + it("should not render clock in leaderboard if prop is disabled", async () => { + renderProviderFn?.(); + + await waitFor(() => { + expect( + screen.queryByTestId("leaderboard-skeleton-name"), + ).not.toBeInTheDocument(); + }); + + const counter = screen.queryByTestId("PrettyCounter"); + expect(counter).not.toBeInTheDocument(); + }); + + it("should render Show All Leaderboards button in leaderboard if prop is enabled", async () => { + renderProviderFn?.(); + + await waitFor(() => { + const button = screen.getByTestId("ShowAllLeaderboardsButton"); + expect(button).toBeInTheDocument(); + expect(button).toBeVisible(); + expect(button).toHaveAttribute("href", "/leaderboard/all"); + }); + }); + + it("should not render Show All Leaderboards button in leaderboard if prop is disabled", async () => { + renderProviderFn?.(); + + await waitFor(() => { + expect( + screen.queryByTestId("leaderboard-skeleton-name"), + ).not.toBeInTheDocument(); + }); + + const button = screen.queryByTestId("ShowAllLeaderboardsButton"); + expect(button).not.toBeInTheDocument(); + }); + + it("should set document title after successful API call", async () => { + renderProviderFn?.(); + + await waitFor(() => { + expect(document.title).toBe( + 'CodeBloom - std::string november = "hello world"', + ); + }); + }); + + it("should set document description after successful API call", async () => { + renderProviderFn?.(); + + await waitFor(() => { + const metaDescription = document.querySelector( + 'meta[name="description"]', + ); + expect(metaDescription).toBeInTheDocument(); + expect(metaDescription).toHaveAttribute( + "content", + "CodeBloom - View your rank in the leaderboard", + ); + }); + }); +}); + +describe("CurrentLeaderboardMetadata API Failed", () => { + const server = setupServer(...failedLeaderboardHandlers); + + beforeAll(() => server.listen()); + afterEach(() => { + server.resetHandlers(); + }); + afterAll(() => server.close()); + + let renderProviderFn: TestUtilTypes.RenderWithAllProvidersFn | null = null; + beforeEach(() => { + renderProviderFn = TestUtils.getRenderWithAllProvidersFn(); + }); + + it("should render loading state initially", async () => { + renderProviderFn?.(); + + await waitFor(() => { + const element = screen.getByText("Leaderboard metadata failed to load"); + expect(element).toBeInTheDocument(); + expect(element).toBeVisible(); + }); + }); +}); + +describe("CurrentLeaderboardMetadata API Crashed", () => { + const server = setupServer(...catastrophicLeaderboardHandlers); + + beforeAll(() => server.listen()); + afterEach(() => { + server.resetHandlers(); + }); + afterAll(() => server.close()); + + let renderProviderFn: TestUtilTypes.RenderWithAllProvidersFn | null = null; + beforeEach(() => { + renderProviderFn = TestUtils.getRenderWithAllProvidersFn(); + }); + + it("should render loading state initially", async () => { + renderProviderFn?.(); + + await waitFor(() => { + const element = screen.getByText("Sorry, something went wrong."); + expect(element).toBeInTheDocument(); + expect(element).toBeVisible(); + }); + }); +}); + +describe("LeaderboardMetadataById API Succeeded", () => { + const server = setupServer(...successfulLeaderboardHandlers); + + beforeAll(() => server.listen()); + afterEach(() => { + server.resetHandlers(); + }); + afterAll(() => server.close()); + + let renderProviderFn: TestUtilTypes.RenderWithAllProvidersFn | null = null; + beforeEach(() => { + renderProviderFn = TestUtils.getRenderWithAllProvidersFn(); + }); + + it("should render loading state initially", () => { + renderProviderFn?.( + , + ); + + const element = screen.getByTestId("leaderboard-skeleton-name"); + expect(element).toBeInTheDocument(); + expect(element).toBeVisible(); + }); + + it("should render leaderboard name after successful API call", async () => { + renderProviderFn?.( + , + ); + + await waitFor(() => { + const heading = screen.getByTestId("LeaderboardMetadata-title"); + expect(heading).toHaveTextContent('std::string november = "hello world"'); + expect(heading).toBeVisible(); + }); + }); + + it("should render leaderboard title with syntax highlighting", async () => { + renderProviderFn?.( + , + ); + + await waitFor(() => { + const titleElement = screen.getByTestId("shiki-container"); + expect(titleElement).toBeInTheDocument(); + expect(titleElement).toBeVisible(); + }); + }); + + it("should render leaderboard title without syntax highlighting", async () => { + server.use(metadataByIdNoSyntaxHighlightingHandler); + + renderProviderFn?.( + , + ); + + await waitFor(() => { + const titleElement = screen.queryByTestId("shiki-container"); + expect(titleElement).not.toBeInTheDocument(); + }); + + await waitFor(() => { + const titleElement = screen.queryByText("haiii"); + expect(titleElement).toBeInTheDocument(); + expect(titleElement).toBeVisible(); + }); + }); + + it("should render clock in leaderboard if prop is enabled", async () => { + renderProviderFn?.( + , + ); + + await waitFor(() => { + const counter = screen.getByTestId("PrettyCounter"); + expect(counter).toBeInTheDocument(); + expect(counter).toBeVisible(); + }); + }); + + it("should not render clock in leaderboard if prop is disabled", async () => { + renderProviderFn?.( + , + ); + + await waitFor(() => { + expect( + screen.queryByTestId("leaderboard-skeleton-name"), + ).not.toBeInTheDocument(); + }); + + const counter = screen.queryByTestId("PrettyCounter"); + expect(counter).not.toBeInTheDocument(); + }); + + it("should render Show All Leaderboards button in leaderboard if prop is enabled", async () => { + renderProviderFn?.( + , + ); + + await waitFor(() => { + const button = screen.getByTestId("ShowAllLeaderboardsButton"); + expect(button).toBeInTheDocument(); + expect(button).toBeVisible(); + expect(button).toHaveAttribute("href", "/leaderboard/all"); + }); + }); + + it("should not render Show All Leaderboards button in leaderboard if prop is disabled", async () => { + renderProviderFn?.( + , + ); + + await waitFor(() => { + expect( + screen.queryByTestId("leaderboard-skeleton-name"), + ).not.toBeInTheDocument(); + }); + + const button = screen.queryByTestId("ShowAllLeaderboardsButton"); + expect(button).not.toBeInTheDocument(); + }); + + it("should set document title after successful API call", async () => { + renderProviderFn?.( + , + ); + + await waitFor(() => { + expect(document.title).toBe( + 'CodeBloom - std::string november = "hello world"', + ); + }); + }); + + it("should set document description after successful API call", async () => { + renderProviderFn?.( + , + ); + + await waitFor(() => { + const metaDescription = document.querySelector( + 'meta[name="description"]', + ); + expect(metaDescription).toBeInTheDocument(); + expect(metaDescription).toHaveAttribute( + "content", + "CodeBloom - View your rank in the leaderboard", + ); + }); + }); +}); + +describe("LeaderboardMetadataById API Failed", () => { + const server = setupServer(...failedLeaderboardHandlers); + + beforeAll(() => server.listen()); + afterEach(() => { + server.resetHandlers(); + }); + afterAll(() => server.close()); + + let renderProviderFn: TestUtilTypes.RenderWithAllProvidersFn | null = null; + beforeEach(() => { + renderProviderFn = TestUtils.getRenderWithAllProvidersFn(); + }); + + it("should render loading state initially", async () => { + renderProviderFn?.( + , + ); + + await waitFor(() => { + const element = screen.getByText("Leaderboard metadata failed to load"); + expect(element).toBeInTheDocument(); + expect(element).toBeVisible(); + }); + }); +}); + +describe("LeaderboardMetadataById API Crashed", () => { + const server = setupServer(...catastrophicLeaderboardHandlers); + + beforeAll(() => server.listen()); + afterEach(() => { + server.resetHandlers(); + }); + afterAll(() => server.close()); + + let renderProviderFn: TestUtilTypes.RenderWithAllProvidersFn | null = null; + beforeEach(() => { + renderProviderFn = TestUtils.getRenderWithAllProvidersFn(); + }); + + it("should render loading state initially", async () => { + renderProviderFn?.( + , + ); + + await waitFor(() => { + const element = screen.getByText("Sorry, something went wrong."); + expect(element).toBeInTheDocument(); + expect(element).toBeVisible(); + }); + }); +}); diff --git a/js/src/app/leaderboard/_components/LeaderboardMetadata/LeaderboardMetadata.tsx b/js/src/app/leaderboard/_components/LeaderboardMetadata/LeaderboardMetadata.tsx index c1132abdd..00a559782 100644 --- a/js/src/app/leaderboard/_components/LeaderboardMetadata/LeaderboardMetadata.tsx +++ b/js/src/app/leaderboard/_components/LeaderboardMetadata/LeaderboardMetadata.tsx @@ -58,13 +58,17 @@ function LeaderboardMetadata({ <>
- <Skeleton visible>Really long tNameV</Skeleton> + <Skeleton visible data-testid="leaderboard-skeleton-name"> + Really long tNameV + </Skeleton>
{showClock && ( - <Skeleton visible>Long Time value</Skeleton> + <Skeleton visible data-testid="leaderboard-skeleton-timer"> + Long Time value + </Skeleton> )}
@@ -112,7 +116,12 @@ function LeaderboardMetadata({ - + <Title + order={4} + ta={"center"} + mb={"xs"} + data-testid="LeaderboardMetadata-title" + > {leaderboardData.syntaxHighlightingLanguage ? <SyntaxStrip size={syntaxStripSize} @@ -128,7 +137,11 @@ function LeaderboardMetadata({ {showAllLeaderboardButton && ( - diff --git a/js/src/components/ui/pretty-counter/PrettyCounter.tsx b/js/src/components/ui/pretty-counter/PrettyCounter.tsx index 8353c73ca..d3709a342 100644 --- a/js/src/components/ui/pretty-counter/PrettyCounter.tsx +++ b/js/src/components/ui/pretty-counter/PrettyCounter.tsx @@ -12,5 +12,9 @@ const formatCountdown = (seconds: number): string => { type CounterProps = TextProps & { time: number }; export default function PrettyCounter({ time, ...props }: CounterProps) { - return {formatCountdown(time)}; + return ( + + {formatCountdown(time)} + + ); } diff --git a/js/src/lib/api/common/apiResponse.ts b/js/src/lib/api/common/apiResponse.ts index 693f9e077..caae77251 100644 --- a/js/src/lib/api/common/apiResponse.ts +++ b/js/src/lib/api/common/apiResponse.ts @@ -13,7 +13,7 @@ type ApiError = Prettify<{ * You can confirm if payload is of type `T` * by checking if success is true, */ - payload: undefined; + payload?: undefined; }>; /** diff --git a/js/src/lib/test/defaults.tsx b/js/src/lib/test/defaults.tsx new file mode 100644 index 000000000..bf1eff2c4 --- /dev/null +++ b/js/src/lib/test/defaults.tsx @@ -0,0 +1,19 @@ +import "@testing-library/jest-dom"; +import "@/patches"; + +// https://stackoverflow.com/a/42685938 +beforeAll(() => { + Object.defineProperty(window, "matchMedia", { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // Deprecated + removeListener: vi.fn(), // Deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), + }); +}); diff --git a/js/src/lib/test/index.tsx b/js/src/lib/test/index.tsx new file mode 100644 index 000000000..77a8c0ffb --- /dev/null +++ b/js/src/lib/test/index.tsx @@ -0,0 +1,40 @@ +import { themeOverride } from "@/lib/theme"; +import { MantineProvider } from "@mantine/core"; +import { Notifications } from "@mantine/notifications"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { render, RenderResult } from "@testing-library/react"; +import { ReactElement } from "react"; +import { MemoryRouter } from "react-router"; + +export namespace TestUtilTypes { + export type RenderWithAllProvidersFn = ( + ui: ReactElement, + ) => RenderResult< + typeof import("@testing-library/dom/types/queries"), + HTMLElement, + HTMLElement + >; +} + +export class TestUtils { + static getRenderWithAllProvidersFn(): TestUtilTypes.RenderWithAllProvidersFn { + const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, + }); + + return (ui: ReactElement) => { + return render( + + + {ui} + + + , + ); + }; + } +} diff --git a/js/src/main.tsx b/js/src/main.tsx index 14b17eab6..7fbd5d62c 100644 --- a/js/src/main.tsx +++ b/js/src/main.tsx @@ -1,13 +1,14 @@ -import ReactQueryProvider from "@/lib/queryProvider"; +import { launchMockServer } from "@/__mocks__"; import "@mantine/core/styles.css"; import "@/patches"; +import ReactQueryProvider from "@/lib/queryProvider"; import { router } from "@/lib/router"; -import { themeOverride } from "@/lib/theme"; import "@mantine/notifications/styles.css"; +import { themeOverride } from "@/lib/theme"; import { MantineProvider } from "@mantine/core"; -import { Notifications } from "@mantine/notifications"; import "@/index.css"; import "@mantine/dates/styles.css"; +import { Notifications } from "@mantine/notifications"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import dayjs from "dayjs"; import customParseFormat from "dayjs/plugin/customParseFormat"; @@ -19,6 +20,10 @@ import { RouterProvider } from "react-router"; dayjs.extend(utc); dayjs.extend(customParseFormat); +if (import.meta.env.VITE_MOCK === "true") { + await launchMockServer(); +} + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion createRoot(document.getElementById("root")!).render( diff --git a/js/tsconfig.app.json b/js/tsconfig.app.json index 6da3df919..6bfa14b22 100644 --- a/js/tsconfig.app.json +++ b/js/tsconfig.app.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "types": [], "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, @@ -27,5 +28,6 @@ "@/*": ["src/*"] } }, - "include": ["src"] + "include": ["src"], + "exclude": ["src/**/*.test.ts", "src/**/*.test.tsx", "src/lib/test"] } diff --git a/js/tsconfig.json b/js/tsconfig.json index f6df6c7c5..3d213f5dc 100644 --- a/js/tsconfig.json +++ b/js/tsconfig.json @@ -2,6 +2,7 @@ "files": [], "references": [ { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.test.json" }, { "path": "./tsconfig.node.json" } ] } diff --git a/js/tsconfig.test.json b/js/tsconfig.test.json new file mode 100644 index 000000000..9f26d66c1 --- /dev/null +++ b/js/tsconfig.test.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "types": ["vitest/globals"], + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src/**/*.test.ts", "src/**/*.test.tsx", "src/lib/test"] +} diff --git a/js/vite.config.ts b/js/vite.config.ts index b5a842f67..baee205cf 100644 --- a/js/vite.config.ts +++ b/js/vite.config.ts @@ -1,3 +1,4 @@ +/// import react from "@vitejs/plugin-react"; import { defineConfig } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; @@ -20,4 +21,15 @@ export default defineConfig({ "@tabler/icons-react": "@tabler/icons-react/dist/esm/icons/index.mjs", }, }, + test: { + globals: true, + environment: "jsdom", + coverage: { + // provider: "v8", + }, + setupFiles: ["src/lib/test/defaults.tsx"], + env: { + VITE_CI: "true", + }, + }, }); diff --git a/src/main/java/org/patinanetwork/codebloom/api/user/UserController.java b/src/main/java/org/patinanetwork/codebloom/api/user/UserController.java index 679c1f921..5e3012409 100644 --- a/src/main/java/org/patinanetwork/codebloom/api/user/UserController.java +++ b/src/main/java/org/patinanetwork/codebloom/api/user/UserController.java @@ -60,6 +60,11 @@ public UserController( this.questionTopicService = questionTopicService; } + public void testingFunction() { + this.userRepository.getAllUsers(); + this.questionRepository.getAllIncompleteQuestions(); + } + @Operation( summary = "Public route that returns the given user's profile", description = """