From a7f273eacc21d82433710dc859769784a15660aa Mon Sep 17 00:00:00 2001 From: Zack Pollard Date: Wed, 10 Sep 2025 14:35:21 +0100 Subject: [PATCH] feat: initial services infrastructure & hello world api (#1) --- .github/workflows/build.yml | 83 + .github/workflows/destroy.yml | 36 + .github/workflows/test.yml | 43 + .gitignore | 41 + .mise/config.toml | 44 + .nvmrc | 1 + .prettierignore | 10 + .prettierrc | 8 + CLAUDE.md | 180 + README.md | 83 + apps/hello/.gitignore | 6 + apps/hello/README.md | 25 + apps/hello/package.json | 13 + apps/hello/src/index.test.ts | 37 + apps/hello/src/index.ts | 72 + apps/hello/vitest.config.ts | 3 + apps/hello/worker-configuration.d.ts | 7 + apps/hello/wrangler.toml | 13 + deployment/.env | 4 + .../workers/hello/.terraform.lock.hcl | 19 + .../cloudflare/workers/hello/config.tf | 11 + .../cloudflare/workers/hello/locals.tf | 5 + .../cloudflare/workers/hello/providers.tf | 3 + .../cloudflare/workers/hello/remote-state.tf | 17 + .../cloudflare/workers/hello/terragrunt.hcl | 30 + .../cloudflare/workers/hello/variables.tf | 6 + .../cloudflare/workers/hello/worker.tf | 63 + deployment/state.hcl | 15 + eslint.config.mjs | 87 + package.json | 39 + pnpm-lock.yaml | 3487 +++++++++++++++++ pnpm-workspace.yaml | 2 + tsconfig.base.json | 16 + tsconfig.json | 17 + vitest.base.config.ts | 11 + 35 files changed, 4537 insertions(+) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/destroy.yml create mode 100644 .github/workflows/test.yml create mode 100644 .gitignore create mode 100644 .mise/config.toml create mode 100644 .nvmrc create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 CLAUDE.md create mode 100644 README.md create mode 100644 apps/hello/.gitignore create mode 100644 apps/hello/README.md create mode 100644 apps/hello/package.json create mode 100644 apps/hello/src/index.test.ts create mode 100644 apps/hello/src/index.ts create mode 100644 apps/hello/vitest.config.ts create mode 100644 apps/hello/worker-configuration.d.ts create mode 100644 apps/hello/wrangler.toml create mode 100644 deployment/.env create mode 100644 deployment/modules/cloudflare/workers/hello/.terraform.lock.hcl create mode 100644 deployment/modules/cloudflare/workers/hello/config.tf create mode 100644 deployment/modules/cloudflare/workers/hello/locals.tf create mode 100644 deployment/modules/cloudflare/workers/hello/providers.tf create mode 100644 deployment/modules/cloudflare/workers/hello/remote-state.tf create mode 100644 deployment/modules/cloudflare/workers/hello/terragrunt.hcl create mode 100644 deployment/modules/cloudflare/workers/hello/variables.tf create mode 100644 deployment/modules/cloudflare/workers/hello/worker.tf create mode 100644 deployment/state.hcl create mode 100644 eslint.config.mjs create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 tsconfig.base.json create mode 100644 tsconfig.json create mode 100644 vitest.base.config.ts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..cfcabda --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,83 @@ +name: Build +on: + push: + branches: [main] + pull_request: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + ENVIRONMENT: ${{ github.ref == 'refs/heads/main' && 'prod' || 'dev' }} + TG_NON_INTERACTIVE: 'true' + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - name: Setup pnpm + uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 + - name: Setup Node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version-file: '.nvmrc' + - name: Run pnpm install + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm build + + - name: Upload build output + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: build-output + path: 'dist' + retention-days: 7 + + deploy: + name: Deploy + runs-on: ubuntu-latest + needs: [build] + env: + TF_VAR_stage: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || '' }} + TF_VAR_dist_dir: ${{github.workspace}}/dist + OP_SERVICE_ACCOUNT_TOKEN: ${{ github.ref == 'refs/heads/main' && secrets.OP_TF_PROD_ENV || secrets.OP_TF_DEV_ENV }} + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Get build artifact + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: 'build-output' + path: '${{ github.workspace }}/dist' + + - name: Install 1Password CLI + uses: 1password/install-cli-action@707af61a6c8b4fa7f9476328c035208fba6b54d7 # v2 + + - name: Setup Mise + uses: immich-app/devtools/actions/use-mise@697a75e2c3186d3c037c2c159855cf2d566542ba # use-mise-action-0.0.1 + + - name: Deploy All + working-directory: ${{ github.workspace }}/deployment + run: mise run tf:apply +# - name: Deploy Output +# id: deploy-output +# working-directory: ${{ github.workspace }}/deployment/modules/cloudflare/static-pages +# run: | +# echo "output=$(op run --no-masking --env-file='../../../.env' -- terragrunt output -json | jq -c .)" >> $GITHUB_OUTPUT +# +# - name: Comment +# uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3 +# if: ${{ github.event_name == 'pull_request' }} +# with: +# number: ${{ github.event.number }} +# body: | +# 📖 Preview of ${{ matrix.app_name }}.immich.app deployed to [${{ fromJson(steps.deploy-output.outputs.output).immich_subdomain.value }}](https://${{ fromJson(steps.deploy-output.outputs.output).immich_subdomain.value }}) +# emojis: 'rocket' +# body-include: '' diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml new file mode 100644 index 0000000..bbd2376 --- /dev/null +++ b/.github/workflows/destroy.yml @@ -0,0 +1,36 @@ +name: Docs destroy +on: + pull_request_target: + types: [closed] + +env: + TF_VAR_dist_dir: ${{ github.workspace }}/dist + TF_VAR_stage: pr-${{ github.event.number }} + OP_SERVICE_ACCOUNT_TOKEN: ${{ matrix.environment == 'prod' && secrets.OP_TF_PROD_ENV || secrets.OP_TF_DEV_ENV }} + +jobs: + deploy: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + environment: ['dev', 'prod'] + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Install 1Password CLI + uses: 1password/install-cli-action@707af61a6c8b4fa7f9476328c035208fba6b54d7 # v2 + + - name: Setup Mise + uses: immich-app/devtools/actions/use-mise@697a75e2c3186d3c037c2c159855cf2d566542ba # use-mise-action-0.0.1 + + - name: Destroy All + working-directory: ${{ github.workspace }}/deployment + run: mise run tf:destroy +# - name: Comment +# uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3 +# with: +# number: ${{ github.event.number }} +# delete: true +# body-include: '' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..50224ee --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,43 @@ +name: Test +on: + workflow_dispatch: + pull_request: + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - name: Setup pnpm + uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 + - name: Setup Node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version-file: '.nvmrc' + + - name: Run pnpm install + run: pnpm install --frozen-lockfile + + - name: Run linter + run: pnpm run lint + if: ${{ !cancelled() }} + + - name: Run formatter + run: pnpm run format + if: ${{ !cancelled() }} + + - name: Run tsc + run: pnpm run check + if: ${{ !cancelled() }} + + - name: Run unit tests + run: pnpm run test + if: ${{ !cancelled() }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1549bdc --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Dependencies +node_modules/ +.pnp +.pnp.js + +# Testing +coverage/ + +# Production +dist/ +build/ + +# Wrangler +.wrangler/ +.dev.vars + +# Logs +logs/ +*.log +npm-debug.log* + +# Editor +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store + +# Terraform +*.tfstate +*.tfstate.* +.terraform/ +.terragrunt-cache/ +*.tfplan +*.tfvars +!*.tfvars.example + +# Misc +.cache/ +tmp/ diff --git a/.mise/config.toml b/.mise/config.toml new file mode 100644 index 0000000..4d78554 --- /dev/null +++ b/.mise/config.toml @@ -0,0 +1,44 @@ +[tools] +opentofu = "1.10.3" +terragrunt = "0.87.0" + +[env] +TF_VAR_dist_dir="{{config_root}}/dist" + +[tasks.tg] +run = "op run '--env-file={{config_root}}/deployment/.env' -- terragrunt" +description = "Wrapper for terragrunt" +dir = "{{cwd}}" + +[tasks."tg:fmt"] +run = "mise run tg hclfmt" +description = "Format terragrunt files" + +[tasks.tf] +run = "mise run tg run --all" +description = "Wrapper for terragrunt run-all" +dir = "{{cwd}}" + +[tasks."tf:fmt"] +run = "tofu fmt -recursive tf/" +description = "Format terraform files" + +[tasks."tf:init"] +run = "mise run tf init -- -reconfigure" +dir = "{{cwd}}" + +[tasks."tf:plan"] +run = "mise run tf plan" +dir = "{{cwd}}" + +[tasks."tf:apply"] +run = "mise run tf apply" +dir = "{{cwd}}" + +[tasks."tf:destroy"] +run = "mise run tf destroy" +dir = "{{cwd}}" + +[settings] +experimental = true +idiomatic_version_file_enable_tools = [] diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..e222811 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22.19.0 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..e87d9e5 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,10 @@ +node_modules/ +dist/ +build/ +.wrangler/ +.terragrunt-cache/ +.terraform/ +*.tfstate +*.tfstate.* +coverage/ +deployment/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..b0daf15 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "printWidth": 120, + "semi": true, + "organizeImportsSkipDestructiveCodeActions": true, + "plugins": ["prettier-plugin-organize-imports"] +} diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..da8d5b8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,180 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is the Immich Workers repository - a monorepo for Cloudflare Workers that provide backend/API services. These workers are deployed independently from the frontend applications. + +## Common Commands + +### Root Level + +```bash +pnpm install # Install all dependencies +pnpm run lint # Lint all workers +pnpm run format # Check formatting +pnpm run test # Run all tests +pnpm run typecheck # Type-check all workers +``` + +### Worker Development + +```bash +cd apps/ +pnpm install # Install worker dependencies +pnpm run dev # Start development server +pnpm run build # Build for production +pnpm run deploy # Deploy directly to Cloudflare +pnpm run test # Run worker tests +``` + +## Architecture + +### Repository Structure + +``` +apps/ +├── hello/ # Example hello world worker +├── datasets/ # Datasets API worker +└── .../ # Other worker applications + +deployment/ +├── modules/ # Terraform modules +│ └── cloudflare/ +│ └── workers/ +│ └── generic/ # Reusable worker module +└── terragrunt/ # Terragrunt configurations + ├── dev/ # Development environment + ├── staging/ # Staging environment + └── prod/ # Production environment + +src/ +└── lib/ # Shared libraries and utilities +``` + +### Worker Structure + +Each worker in `apps//` contains: + +- `src/index.ts` - Main worker entry point +- `wrangler.toml` - Cloudflare Worker configuration +- `package.json` - Dependencies and scripts +- `tsconfig.json` - TypeScript configuration +- `vitest.config.ts` - Test configuration +- `worker-configuration.d.ts` - Environment type definitions + +### Technology Stack + +- **Runtime**: Cloudflare Workers +- **Language**: TypeScript +- **Build Tool**: Wrangler CLI +- **Testing**: Vitest with Miniflare +- **Infrastructure**: Terraform/Terragrunt +- **Package Manager**: pnpm with workspaces + +## Deployment + +### Direct Deployment (Wrangler) + +```bash +cd apps/ +pnpm run deploy # Deploy to default environment +pnpm run deploy:staging # Deploy to staging +pnpm run deploy:production # Deploy to production +``` + +### Infrastructure as Code (Terraform/Terragrunt) + +```bash +# Set up required environment variables +export TF_VAR_tf_state_postgres_conn_str="postgresql://user:pass@host/dbname" +export TF_VAR_env="dev" # Environment (dev/staging/prod) +export TF_VAR_stage="dev" # Stage +export TF_VAR_app_name="hello" # App name +export TF_VAR_cloudflare_account_id="your-account-id" + +# Deploy with Terragrunt +cd deployment/modules/cloudflare/workers/ +terragrunt init +terragrunt plan +terragrunt apply +``` + +The deployment uses the same Terragrunt pattern as other Immich infrastructure: + +- PostgreSQL backend for state storage +- Remote state references for API keys and account info +- Schema naming: `cloudflare_workers_immich_app_${app_name}_${env}${stage}` + +## Environment Configuration + +### Local Development + +Create `.dev.vars` in the worker directory: + +``` +SECRET_KEY=local_secret +API_ENDPOINT=https://api.example.com +``` + +### Production Secrets + +Use Wrangler or Terraform to set production secrets: + +```bash +wrangler secret put SECRET_KEY +``` + +## Creating a New Worker + +1. Create worker directory: `apps//` +2. Copy structure from `apps/hello/` as template +3. Update `wrangler.toml` with worker name +4. Implement worker logic in `src/index.ts` +5. Add Terragrunt config if using IaC deployment + +## Testing + +Workers use Vitest with Miniflare for testing: + +```bash +cd apps/ +pnpm run test # Run tests once +pnpm run test:watch # Run tests in watch mode +``` + +## Common Patterns + +### Request Handling + +```typescript +export default { + async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise { + // Handle request + }, +}; +``` + +### CORS Headers + +```typescript +const corsHeaders = { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type', +}; +``` + +### Error Handling + +```typescript +try { + // Worker logic +} catch (error) { + return new Response(JSON.stringify({ error: 'Internal Server Error' }), { + status: 500, + headers: { 'Content-Type': 'application/json' }, + }); +} +``` diff --git a/README.md b/README.md new file mode 100644 index 0000000..9ae471b --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# Immich Workers + +Monorepo for Immich Cloudflare Workers (backend-only/API services). + +## Structure + +``` +apps/ +├── hello/ # Hello world example worker +├── datasets/ # Datasets API worker +└── .../ # Other worker applications + +deployment/ +├── modules/ # Terraform modules +└── terragrunt/ # Terragrunt configurations + +src/ +└── lib/ # Shared libraries and utilities +``` + +## Development + +### Setup + +```bash +npm install +``` + +### Working with Individual Workers + +```bash +cd apps/ +npm install +npm run dev # Start development server +npm run test # Run tests +npm run build # Build for production +npm run deploy # Deploy to Cloudflare +``` + +### Global Commands + +```bash +npm run lint # Lint all workers +npm run format # Check formatting +npm run test # Run all tests +npm run typecheck # Type-check all workers +``` + +## Deployment + +### Using Wrangler (Direct) + +```bash +cd apps/ +npm run deploy +``` + +### Using Terraform/Terragrunt + +```bash +cd deployment/terragrunt// +terragrunt plan +terragrunt apply +``` + +## Creating a New Worker + +1. Create directory: `apps//` +2. Add `package.json`, `wrangler.toml`, `tsconfig.json` +3. Create source in `src/index.ts` +4. Add terraform module in `deployment/modules/cloudflare/workers//` +5. Add terragrunt config in `deployment/terragrunt/` + +## Environment Variables + +Workers use `.dev.vars` for local development and Cloudflare secrets for production. + +Example `.dev.vars`: + +``` +MY_SECRET=secret_value +API_KEY=test_key +``` diff --git a/apps/hello/.gitignore b/apps/hello/.gitignore new file mode 100644 index 0000000..32f97dd --- /dev/null +++ b/apps/hello/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +dist/ +.wrangler/ +.dev.vars +.env +.env.local \ No newline at end of file diff --git a/apps/hello/README.md b/apps/hello/README.md new file mode 100644 index 0000000..cd3db9e --- /dev/null +++ b/apps/hello/README.md @@ -0,0 +1,25 @@ +# hello.immich.app + +A simple Cloudflare Worker API example for the Immich project. + +## Endpoints + +- `GET /` - Returns a hello message +- `GET /health` - Health check endpoint +- `GET /api/greet?name=` - Personalized greeting + +## Development + +```bash +# Install dependencies +pnpm install + +# Run locally +pnpm run dev +``` + +## Testing + +```bash +pnpm test +``` diff --git a/apps/hello/package.json b/apps/hello/package.json new file mode 100644 index 0000000..bf26407 --- /dev/null +++ b/apps/hello/package.json @@ -0,0 +1,13 @@ +{ + "name": "@immich-services/hello", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "wrangler dev", + "build": "wrangler deploy --dry-run --outdir ../../dist/hello", + "tail": "wrangler tail", + "test": "vitest", + "check": "tsc --noEmit" + } +} diff --git a/apps/hello/src/index.test.ts b/apps/hello/src/index.test.ts new file mode 100644 index 0000000..fde5f46 --- /dev/null +++ b/apps/hello/src/index.test.ts @@ -0,0 +1,37 @@ +import { SELF } from 'cloudflare:test'; +import { describe, expect, it } from 'vitest'; + +describe('Hello Worker', () => { + it('should return hello message on root path', async () => { + const response = await SELF.fetch('https://example.com/'); + const data = (await response.json()) as any; + + expect(response.status).toBe(200); + expect(data).toHaveProperty('message', 'Hello from Immich Worker API!'); + expect(data).toHaveProperty('timestamp'); + }); + + it('should return health status', async () => { + const response = await SELF.fetch('https://example.com/health'); + const data = (await response.json()) as any; + + expect(response.status).toBe(200); + expect(data).toHaveProperty('status', 'healthy'); + }); + + it('should greet with name parameter', async () => { + const response = await SELF.fetch('https://example.com/api/greet?name=Claude'); + const data = (await response.json()) as any; + + expect(response.status).toBe(200); + expect(data).toHaveProperty('greeting', 'Hello, Claude!'); + }); + + it('should return 404 for unknown routes', async () => { + const response = await SELF.fetch('https://example.com/unknown'); + const data = (await response.json()) as any; + + expect(response.status).toBe(404); + expect(data).toHaveProperty('error', 'Not Found'); + }); +}); diff --git a/apps/hello/src/index.ts b/apps/hello/src/index.ts new file mode 100644 index 0000000..8abe9ea --- /dev/null +++ b/apps/hello/src/index.ts @@ -0,0 +1,72 @@ +export default { + // eslint-disable-next-line @typescript-eslint/require-await + async fetch(request: Request): Promise { + const url = new URL(request.url); + + // Handle different routes + switch (url.pathname) { + case '/': { + return new Response( + JSON.stringify({ + message: 'Hello from Immich Worker API!', + timestamp: new Date().toISOString(), + path: url.pathname, + }), + { + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + }, + ); + } + + case '/health': { + return new Response( + JSON.stringify({ + status: 'healthy', + timestamp: new Date().toISOString(), + }), + { + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + }, + ); + } + + case '/api/greet': { + const name = url.searchParams.get('name') || 'World'; + return new Response( + JSON.stringify({ + greeting: `Hello, ${name}!`, + timestamp: new Date().toISOString(), + }), + { + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + }, + ); + } + + default: { + return new Response( + JSON.stringify({ + error: 'Not Found', + path: url.pathname, + }), + { + status: 404, + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + }, + ); + } + } + }, +}; diff --git a/apps/hello/vitest.config.ts b/apps/hello/vitest.config.ts new file mode 100644 index 0000000..9ef43ce --- /dev/null +++ b/apps/hello/vitest.config.ts @@ -0,0 +1,3 @@ +import baseConfig from '../../vitest.base.config.js'; + +export default baseConfig; diff --git a/apps/hello/worker-configuration.d.ts b/apps/hello/worker-configuration.d.ts new file mode 100644 index 0000000..d357727 --- /dev/null +++ b/apps/hello/worker-configuration.d.ts @@ -0,0 +1,7 @@ +interface Env { + // Add environment variables here as needed + // Example: + // MY_KV_NAMESPACE: KVNamespace; + // MY_DURABLE_OBJECT: DurableObjectNamespace; + MY_SECRET: string; +} diff --git a/apps/hello/wrangler.toml b/apps/hello/wrangler.toml new file mode 100644 index 0000000..69780cb --- /dev/null +++ b/apps/hello/wrangler.toml @@ -0,0 +1,13 @@ +name = "hello-immich-app" +main = "src/index.ts" +compatibility_date = "2024-01-01" + +# Uncomment to add KV namespaces, Durable Objects, etc. +# [[kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# [[durable_objects.bindings]] +# name = "MY_DURABLE_OBJECT" +# class_name = "MyDurableObject" +# script_name = "my-durable-object" diff --git a/deployment/.env b/deployment/.env new file mode 100644 index 0000000..eb3593b --- /dev/null +++ b/deployment/.env @@ -0,0 +1,4 @@ +export TF_VAR_cloudflare_account_id="op://tf/cloudflare/account_id" +export TF_VAR_cloudflare_api_token="op://tf/cloudflare/api_token" +export TF_VAR_tf_state_postgres_conn_str="op://tf/tf_state/postgres_conn_str" +export TF_VAR_env=$ENVIRONMENT diff --git a/deployment/modules/cloudflare/workers/hello/.terraform.lock.hcl b/deployment/modules/cloudflare/workers/hello/.terraform.lock.hcl new file mode 100644 index 0000000..ae8cf4f --- /dev/null +++ b/deployment/modules/cloudflare/workers/hello/.terraform.lock.hcl @@ -0,0 +1,19 @@ +# This file is maintained automatically by "tofu init". +# Manual edits may be lost in future updates. + +provider "registry.opentofu.org/cloudflare/cloudflare" { + version = "5.9.0" + constraints = "~> 5.0" + hashes = [ + "h1:yNvFe2InCb4foqjWd+Sz9DIX6mdk30iRycsmm/fZarY=", + "zh:3ae6f70f4e2961e84b89b337d268db0537c6dd0e66d4ccf32cbacc950f7a2807", + "zh:4472d1d1629c3c3a6a23672691ed0852bea9fcd9e39a213d388616f93adaaeb0", + "zh:4680cb586233b4702abb9fc69615bca6ebe9547ddaceaa0d0439bccc7c773905", + "zh:51fd157b544644438ab827e288c8173ecbf31cd92b3b75a8446569db35c00cab", + "zh:66aaeb1cb991b982f81564ea52a18ba962b43e86d9e5c76ac591fa522a4a0db6", + "zh:d271308040efe8324633810d8c58142310da5f88eb223422fd13daa73e944316", + "zh:e56c66588135878081ffa8c2aa5da969d56ff96d4ecb4b0ab6b8b496830cf7c2", + "zh:f809ab383cca0a5f83072981c64208cbd7fa67e986a86ee02dd2c82333221e32", + "zh:fde7a7d2bda2784e78c0bcc39155e0b09c31dd4a4fa65c26e0e8fe858445ecfc", + ] +} diff --git a/deployment/modules/cloudflare/workers/hello/config.tf b/deployment/modules/cloudflare/workers/hello/config.tf new file mode 100644 index 0000000..ac39abc --- /dev/null +++ b/deployment/modules/cloudflare/workers/hello/config.tf @@ -0,0 +1,11 @@ +terraform { + backend "pg" {} + required_version = "~> 1.7" + + required_providers { + cloudflare = { + source = "cloudflare/cloudflare" + version = "~> 5" + } + } +} diff --git a/deployment/modules/cloudflare/workers/hello/locals.tf b/deployment/modules/cloudflare/workers/hello/locals.tf new file mode 100644 index 0000000..752c0ac --- /dev/null +++ b/deployment/modules/cloudflare/workers/hello/locals.tf @@ -0,0 +1,5 @@ +locals { + resource_stage = var.stage != "" ? "-${var.stage}" : "" + resource_env = "-${var.env}" + resource_suffix = "${local.resource_env}${local.resource_stage}" +} \ No newline at end of file diff --git a/deployment/modules/cloudflare/workers/hello/providers.tf b/deployment/modules/cloudflare/workers/hello/providers.tf new file mode 100644 index 0000000..1bd1877 --- /dev/null +++ b/deployment/modules/cloudflare/workers/hello/providers.tf @@ -0,0 +1,3 @@ +provider "cloudflare" { + api_token = data.terraform_remote_state.api_keys_state.outputs.terraform_key_cloudflare_account +} diff --git a/deployment/modules/cloudflare/workers/hello/remote-state.tf b/deployment/modules/cloudflare/workers/hello/remote-state.tf new file mode 100644 index 0000000..cf9d99f --- /dev/null +++ b/deployment/modules/cloudflare/workers/hello/remote-state.tf @@ -0,0 +1,17 @@ +data "terraform_remote_state" "api_keys_state" { + backend = "pg" + + config = { + conn_str = var.tf_state_postgres_conn_str + schema_name = "prod_cloudflare_api_keys" + } +} + +data "terraform_remote_state" "cloudflare_account" { + backend = "pg" + + config = { + conn_str = var.tf_state_postgres_conn_str + schema_name = "prod_cloudflare_account" + } +} diff --git a/deployment/modules/cloudflare/workers/hello/terragrunt.hcl b/deployment/modules/cloudflare/workers/hello/terragrunt.hcl new file mode 100644 index 0000000..8d588ed --- /dev/null +++ b/deployment/modules/cloudflare/workers/hello/terragrunt.hcl @@ -0,0 +1,30 @@ +terraform { + source = "." + + extra_arguments custom_vars { + commands = get_terraform_commands_that_need_vars() + } +} + +include { + path = find_in_parent_folders("state.hcl") +} + +locals { + env = get_env("TF_VAR_env") + stage = get_env("TF_VAR_stage") + app_name = "hello" +} + +inputs = { + app_name = local.app_name +} + +remote_state { + backend = "pg" + + config = { + conn_str = get_env("TF_VAR_tf_state_postgres_conn_str") + schema_name = "services_cloudflare_workers_${local.app_name}_immich_app_${local.env}${local.stage}" + } +} diff --git a/deployment/modules/cloudflare/workers/hello/variables.tf b/deployment/modules/cloudflare/workers/hello/variables.tf new file mode 100644 index 0000000..301f999 --- /dev/null +++ b/deployment/modules/cloudflare/workers/hello/variables.tf @@ -0,0 +1,6 @@ +variable "tf_state_postgres_conn_str" {} +variable "stage" {} +variable "env" {} +variable "app_name" {} +variable "cloudflare_account_id" {} +variable "dist_dir" {} \ No newline at end of file diff --git a/deployment/modules/cloudflare/workers/hello/worker.tf b/deployment/modules/cloudflare/workers/hello/worker.tf new file mode 100644 index 0000000..36be0fd --- /dev/null +++ b/deployment/modules/cloudflare/workers/hello/worker.tf @@ -0,0 +1,63 @@ +resource "cloudflare_worker" "worker" { + account_id = var.cloudflare_account_id + name = "${var.app_name}-api${local.resource_suffix}" + logpush = true +} + +resource "cloudflare_worker_version" "worker" { + account_id = var.cloudflare_account_id + worker_id = cloudflare_worker.worker.id + bindings = [ + { + name = "EXAMPLE_BINDING" + type = "plain_text" + text = "example_value" + } + ] + compatibility_date = "2025-09-09" + compatibility_flags = ["nodejs_compat"] + main_module = "index.js" + modules = [ + { + content_file = "${var.dist_dir}/${var.app_name}/index.js" + content_type = "application/javascript+module" + name = "index.js" + } + ] +} + +resource "cloudflare_workers_deployment" "worker" { + account_id = var.cloudflare_account_id + script_name = cloudflare_worker.worker.name + strategy = "percentage" + versions = [ + { + percentage = 100 + version_id = cloudflare_worker_version.worker.id + } + ] + +} + +data "cloudflare_zone" "immich_app" { + filter = { + name = "immich.cloud" + } +} + +resource "cloudflare_workers_custom_domain" "worker" { + account_id = var.cloudflare_account_id + environment = "production" + hostname = module.domain.fqdn + service = cloudflare_worker.worker.name + zone_id = data.cloudflare_zone.immich_app.zone_id +} + +module "domain" { + source = "git::https://github.com/immich-app/devtools.git//tf/shared/modules/domain?ref=main" + + app_name = var.app_name + stage = var.stage + env = var.env + domain = "immich.cloud" +} diff --git a/deployment/state.hcl b/deployment/state.hcl new file mode 100644 index 0000000..d382890 --- /dev/null +++ b/deployment/state.hcl @@ -0,0 +1,15 @@ +locals { + tf_state_postgres_conn_str = get_env("TF_VAR_tf_state_postgres_conn_str") +} + +remote_state { + backend = "pg" + + config = { + conn_str = local.tf_state_postgres_conn_str + } +} + +inputs = { + tf_state_postgres_conn_str = local.tf_state_postgres_conn_str +} \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..9c0eb16 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,87 @@ +import js from '@eslint/js'; +import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; +import eslintPluginUnicorn from 'eslint-plugin-unicorn'; +import globals from 'globals'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import typescriptEslint from 'typescript-eslint'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +export default typescriptEslint.config([ + eslintPluginUnicorn.configs.recommended, + eslintPluginPrettierRecommended, + js.configs.recommended, + typescriptEslint.configs.recommended, + { + ignores: ['eslint.config.mjs', 'deployment/**', '**/.wrangler/**', 'dist'], + }, + { + languageOptions: { + globals: { + ...globals.node, + }, + + parser: typescriptEslint.parser, + ecmaVersion: 5, + sourceType: 'module', + + parserOptions: { + project: 'tsconfig.json', + tsconfigRootDir: __dirname, + }, + }, + + rules: { + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-floating-promises': 'error', + 'unicorn/prevent-abbreviations': 'off', + 'unicorn/filename-case': 'off', + 'unicorn/no-null': 'off', + 'unicorn/prefer-top-level-await': 'off', + 'unicorn/prefer-event-target': 'off', + 'unicorn/no-thenable': 'off', + 'unicorn/import-style': 'off', + 'unicorn/prefer-structured-clone': 'off', + 'unicorn/no-for-loop': 'off', + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/no-misused-promises': 'error', + 'require-await': 'off', + '@typescript-eslint/require-await': 'error', + curly: 2, + 'prettier/prettier': 0, + 'object-shorthand': ['error', 'always'], + + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['.*'], + message: 'Relative imports are not allowed.', + }, + ], + }, + ], + + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }, + ], + }, + }, + { + files: ['**/*.config.ts', '**/*.config.js', '**/*.config.mjs'], + rules: { + 'no-restricted-imports': 'off', + 'unicorn/prefer-export-from': 'off', + }, + }, +]); diff --git a/package.json b/package.json new file mode 100644 index 0000000..31dbd52 --- /dev/null +++ b/package.json @@ -0,0 +1,39 @@ +{ + "name": "immich-services", + "version": "1.0.0", + "description": "Immich Cloudflare Workers monorepo", + "private": true, + "type": "module", + "scripts": { + "build": "pnpm -r build", + "lint": "eslint . --max-warnings 0", + "lint:fix": "pnpm run lint -- --fix", + "format": "prettier --check .", + "format:fix": "prettier --write .", + "test": "pnpm -r test", + "check": "tsc --noEmit && pnpm -r typecheck" + }, + "devDependencies": { + "@cloudflare/vitest-pool-workers": "^0.8.71", + "@cloudflare/workers-types": "^4.20241127.0", + "@eslint/js": "^9.35.0", + "@types/node": "^22.10.5", + "@typescript-eslint/eslint-plugin": "^8.19.0", + "@typescript-eslint/parser": "^8.19.0", + "eslint": "^9.17.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-prettier": "^5.5.4", + "eslint-plugin-unicorn": "^61.0.2", + "globals": "^16.3.0", + "prettier": "^3.4.2", + "prettier-plugin-organize-imports": "^4.2.0", + "typescript": "^5.7.2", + "typescript-eslint": "^8.43.0", + "vitest": "^3.0.0", + "wrangler": "^4.35.0" + }, + "packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748", + "engines": { + "pnpm": ">=10.0.0" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..b5a45fa --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,3487 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + .: + devDependencies: + '@cloudflare/vitest-pool-workers': + specifier: ^0.8.71 + version: 0.8.71(@cloudflare/workers-types@4.20250909.0)(@vitest/runner@3.2.4)(@vitest/snapshot@3.2.4)(vitest@3.2.4(@types/node@22.18.1)) + '@cloudflare/workers-types': + specifier: ^4.20241127.0 + version: 4.20250909.0 + '@eslint/js': + specifier: ^9.35.0 + version: 9.35.0 + '@types/node': + specifier: ^22.10.5 + version: 22.18.1 + '@typescript-eslint/eslint-plugin': + specifier: ^8.19.0 + version: 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2) + '@typescript-eslint/parser': + specifier: ^8.19.0 + version: 8.43.0(eslint@9.35.0)(typescript@5.9.2) + eslint: + specifier: ^9.17.0 + version: 9.35.0 + eslint-config-prettier: + specifier: ^10.0.1 + version: 10.1.8(eslint@9.35.0) + eslint-plugin-prettier: + specifier: ^5.5.4 + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.35.0))(eslint@9.35.0)(prettier@3.6.2) + eslint-plugin-unicorn: + specifier: ^61.0.2 + version: 61.0.2(eslint@9.35.0) + globals: + specifier: ^16.3.0 + version: 16.3.0 + prettier: + specifier: ^3.4.2 + version: 3.6.2 + prettier-plugin-organize-imports: + specifier: ^4.2.0 + version: 4.2.0(prettier@3.6.2)(typescript@5.9.2) + typescript: + specifier: ^5.7.2 + version: 5.9.2 + typescript-eslint: + specifier: ^8.43.0 + version: 8.43.0(eslint@9.35.0)(typescript@5.9.2) + vitest: + specifier: ^3.0.0 + version: 3.2.4(@types/node@22.18.1) + wrangler: + specifier: ^4.35.0 + version: 4.35.0(@cloudflare/workers-types@4.20250909.0) + + apps/hello: {} + +packages: + '@babel/helper-validator-identifier@7.27.1': + resolution: + { integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== } + engines: { node: '>=6.9.0' } + + '@cloudflare/kv-asset-handler@0.4.0': + resolution: + { integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA== } + engines: { node: '>=18.0.0' } + + '@cloudflare/unenv-preset@2.7.3': + resolution: + { integrity: sha512-tsQQagBKjvpd9baa6nWVIv399ejiqcrUBBW6SZx6Z22+ymm+Odv5+cFimyuCsD/fC1fQTwfRmwXBNpzvHSeGCw== } + peerDependencies: + unenv: 2.0.0-rc.21 + workerd: ^1.20250828.1 + peerDependenciesMeta: + workerd: + optional: true + + '@cloudflare/vitest-pool-workers@0.8.71': + resolution: + { integrity: sha512-keu2HCLQfRNwbmLBCDXJgCFpANTaYnQpE01fBOo4CNwiWHUT7SZGN7w64RKiSWRHyYppStXBuE5Ng7F42+flpg== } + peerDependencies: + '@vitest/runner': 2.0.x - 3.2.x + '@vitest/snapshot': 2.0.x - 3.2.x + vitest: 2.0.x - 3.2.x + + '@cloudflare/workerd-darwin-64@1.20250906.0': + resolution: + { integrity: sha512-E+X/YYH9BmX0ew2j/mAWFif2z05NMNuhCTlNYEGLkqMe99K15UewBqajL9pMcMUKxylnlrEoK3VNxl33DkbnPA== } + engines: { node: '>=16' } + cpu: [x64] + os: [darwin] + + '@cloudflare/workerd-darwin-arm64@1.20250906.0': + resolution: + { integrity: sha512-X5apsZ1SFW4FYTM19ISHf8005FJMPfrcf4U5rO0tdj+TeJgQgXuZ57IG0WeW7SpLVeBo8hM6WC8CovZh41AfnA== } + engines: { node: '>=16' } + cpu: [arm64] + os: [darwin] + + '@cloudflare/workerd-linux-64@1.20250906.0': + resolution: + { integrity: sha512-rlKzWgsLnlQ5Nt9W69YBJKcmTmZbOGu0edUsenXPmc6wzULUxoQpi7ZE9k3TfTonJx4WoQsQlzCUamRYFsX+0Q== } + engines: { node: '>=16' } + cpu: [x64] + os: [linux] + + '@cloudflare/workerd-linux-arm64@1.20250906.0': + resolution: + { integrity: sha512-DdedhiQ+SeLzpg7BpcLrIPEZ33QKioJQ1wvL4X7nuLzEB9rWzS37NNNahQzc1+44rhG4fyiHbXBPOeox4B9XVA== } + engines: { node: '>=16' } + cpu: [arm64] + os: [linux] + + '@cloudflare/workerd-windows-64@1.20250906.0': + resolution: + { integrity: sha512-Q8Qjfs8jGVILnZL6vUpQ90q/8MTCYaGR3d1LGxZMBqte8Vr7xF3KFHPEy7tFs0j0mMjnqCYzlofmPNY+9ZaDRg== } + engines: { node: '>=16' } + cpu: [x64] + os: [win32] + + '@cloudflare/workers-types@4.20250909.0': + resolution: + { integrity: sha512-3WvDDOvFGOAlBUZpWe2N+9BxB1kRt9eHo3AhIKg1fihNdqrGxyh9cJe1MpYs5BI8gXSRxjkDvzPVebRED8iwOQ== } + + '@cspotcode/source-map-support@0.8.1': + resolution: + { integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== } + engines: { node: '>=12' } + + '@emnapi/runtime@1.5.0': + resolution: + { integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ== } + + '@esbuild/aix-ppc64@0.25.4': + resolution: + { integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q== } + engines: { node: '>=18' } + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.25.9': + resolution: + { integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA== } + engines: { node: '>=18' } + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.4': + resolution: + { integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A== } + engines: { node: '>=18' } + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.25.9': + resolution: + { integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg== } + engines: { node: '>=18' } + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.4': + resolution: + { integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ== } + engines: { node: '>=18' } + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.25.9': + resolution: + { integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ== } + engines: { node: '>=18' } + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.4': + resolution: + { integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ== } + engines: { node: '>=18' } + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.25.9': + resolution: + { integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw== } + engines: { node: '>=18' } + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.4': + resolution: + { integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g== } + engines: { node: '>=18' } + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.25.9': + resolution: + { integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg== } + engines: { node: '>=18' } + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.4': + resolution: + { integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A== } + engines: { node: '>=18' } + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.9': + resolution: + { integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ== } + engines: { node: '>=18' } + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.4': + resolution: + { integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ== } + engines: { node: '>=18' } + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.25.9': + resolution: + { integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q== } + engines: { node: '>=18' } + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.4': + resolution: + { integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ== } + engines: { node: '>=18' } + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.9': + resolution: + { integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg== } + engines: { node: '>=18' } + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.4': + resolution: + { integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ== } + engines: { node: '>=18' } + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.25.9': + resolution: + { integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw== } + engines: { node: '>=18' } + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.4': + resolution: + { integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ== } + engines: { node: '>=18' } + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.25.9': + resolution: + { integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw== } + engines: { node: '>=18' } + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.4': + resolution: + { integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ== } + engines: { node: '>=18' } + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.25.9': + resolution: + { integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A== } + engines: { node: '>=18' } + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.4': + resolution: + { integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA== } + engines: { node: '>=18' } + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.25.9': + resolution: + { integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ== } + engines: { node: '>=18' } + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.4': + resolution: + { integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg== } + engines: { node: '>=18' } + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.25.9': + resolution: + { integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA== } + engines: { node: '>=18' } + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.4': + resolution: + { integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag== } + engines: { node: '>=18' } + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.25.9': + resolution: + { integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w== } + engines: { node: '>=18' } + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.4': + resolution: + { integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA== } + engines: { node: '>=18' } + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.9': + resolution: + { integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg== } + engines: { node: '>=18' } + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.4': + resolution: + { integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g== } + engines: { node: '>=18' } + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.25.9': + resolution: + { integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA== } + engines: { node: '>=18' } + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.4': + resolution: + { integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA== } + engines: { node: '>=18' } + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.25.9': + resolution: + { integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg== } + engines: { node: '>=18' } + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.4': + resolution: + { integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ== } + engines: { node: '>=18' } + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.25.9': + resolution: + { integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q== } + engines: { node: '>=18' } + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.4': + resolution: + { integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw== } + engines: { node: '>=18' } + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.9': + resolution: + { integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g== } + engines: { node: '>=18' } + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.4': + resolution: + { integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A== } + engines: { node: '>=18' } + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.25.9': + resolution: + { integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ== } + engines: { node: '>=18' } + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.4': + resolution: + { integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw== } + engines: { node: '>=18' } + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.9': + resolution: + { integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA== } + engines: { node: '>=18' } + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.9': + resolution: + { integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg== } + engines: { node: '>=18' } + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.4': + resolution: + { integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q== } + engines: { node: '>=18' } + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.25.9': + resolution: + { integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw== } + engines: { node: '>=18' } + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.4': + resolution: + { integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ== } + engines: { node: '>=18' } + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.25.9': + resolution: + { integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ== } + engines: { node: '>=18' } + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.4': + resolution: + { integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg== } + engines: { node: '>=18' } + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.25.9': + resolution: + { integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww== } + engines: { node: '>=18' } + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.4': + resolution: + { integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ== } + engines: { node: '>=18' } + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.25.9': + resolution: + { integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ== } + engines: { node: '>=18' } + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.0': + resolution: + { integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g== } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: + { integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== } + engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } + + '@eslint/config-array@0.21.0': + resolution: + { integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + '@eslint/config-helpers@0.3.1': + resolution: + { integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + '@eslint/core@0.15.2': + resolution: + { integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + '@eslint/eslintrc@3.3.1': + resolution: + { integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + '@eslint/js@9.35.0': + resolution: + { integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + '@eslint/object-schema@2.1.6': + resolution: + { integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + '@eslint/plugin-kit@0.3.5': + resolution: + { integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + '@humanfs/core@0.19.1': + resolution: + { integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== } + engines: { node: '>=18.18.0' } + + '@humanfs/node@0.16.7': + resolution: + { integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ== } + engines: { node: '>=18.18.0' } + + '@humanwhocodes/module-importer@1.0.1': + resolution: + { integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== } + engines: { node: '>=12.22' } + + '@humanwhocodes/retry@0.4.3': + resolution: + { integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ== } + engines: { node: '>=18.18' } + + '@img/sharp-darwin-arm64@0.33.5': + resolution: + { integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: + { integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: + { integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg== } + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: + { integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ== } + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: + { integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA== } + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: + { integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g== } + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: + { integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA== } + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: + { integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw== } + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: + { integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA== } + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: + { integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw== } + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: + { integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: + { integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: + { integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: + { integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: + { integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: + { integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: + { integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: + { integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: + { integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [win32] + + '@jridgewell/resolve-uri@3.1.2': + resolution: + { integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== } + engines: { node: '>=6.0.0' } + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: + { integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== } + + '@jridgewell/trace-mapping@0.3.9': + resolution: + { integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== } + + '@nodelib/fs.scandir@2.1.5': + resolution: + { integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== } + engines: { node: '>= 8' } + + '@nodelib/fs.stat@2.0.5': + resolution: + { integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== } + engines: { node: '>= 8' } + + '@nodelib/fs.walk@1.2.8': + resolution: + { integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== } + engines: { node: '>= 8' } + + '@pkgr/core@0.2.9': + resolution: + { integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== } + engines: { node: ^12.20.0 || ^14.18.0 || >=16.0.0 } + + '@poppinss/colors@4.1.5': + resolution: + { integrity: sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw== } + + '@poppinss/dumper@0.6.4': + resolution: + { integrity: sha512-iG0TIdqv8xJ3Lt9O8DrPRxw1MRLjNpoqiSGU03P/wNLP/s0ra0udPJ1J2Tx5M0J3H/cVyEgpbn8xUKRY9j59kQ== } + + '@poppinss/exception@1.2.2': + resolution: + { integrity: sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg== } + + '@rollup/rollup-android-arm-eabi@4.50.1': + resolution: + { integrity: sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag== } + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.50.1': + resolution: + { integrity: sha512-PZlsJVcjHfcH53mOImyt3bc97Ep3FJDXRpk9sMdGX0qgLmY0EIWxCag6EigerGhLVuL8lDVYNnSo8qnTElO4xw== } + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.50.1': + resolution: + { integrity: sha512-xc6i2AuWh++oGi4ylOFPmzJOEeAa2lJeGUGb4MudOtgfyyjr4UPNK+eEWTPLvmPJIY/pgw6ssFIox23SyrkkJw== } + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.50.1': + resolution: + { integrity: sha512-2ofU89lEpDYhdLAbRdeyz/kX3Y2lpYc6ShRnDjY35bZhd2ipuDMDi6ZTQ9NIag94K28nFMofdnKeHR7BT0CATw== } + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.50.1': + resolution: + { integrity: sha512-wOsE6H2u6PxsHY/BeFHA4VGQN3KUJFZp7QJBmDYI983fgxq5Th8FDkVuERb2l9vDMs1D5XhOrhBrnqcEY6l8ZA== } + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.50.1': + resolution: + { integrity: sha512-A/xeqaHTlKbQggxCqispFAcNjycpUEHP52mwMQZUNqDUJFFYtPHCXS1VAG29uMlDzIVr+i00tSFWFLivMcoIBQ== } + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.50.1': + resolution: + { integrity: sha512-54v4okehwl5TaSIkpp97rAHGp7t3ghinRd/vyC1iXqXMfjYUTm7TfYmCzXDoHUPTTf36L8pr0E7YsD3CfB3ZDg== } + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.50.1': + resolution: + { integrity: sha512-p/LaFyajPN/0PUHjv8TNyxLiA7RwmDoVY3flXHPSzqrGcIp/c2FjwPPP5++u87DGHtw+5kSH5bCJz0mvXngYxw== } + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.50.1': + resolution: + { integrity: sha512-2AbMhFFkTo6Ptna1zO7kAXXDLi7H9fGTbVaIq2AAYO7yzcAsuTNWPHhb2aTA6GPiP+JXh85Y8CiS54iZoj4opw== } + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.50.1': + resolution: + { integrity: sha512-Cgef+5aZwuvesQNw9eX7g19FfKX5/pQRIyhoXLCiBOrWopjo7ycfB292TX9MDcDijiuIJlx1IzJz3IoCPfqs9w== } + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.50.1': + resolution: + { integrity: sha512-RPhTwWMzpYYrHrJAS7CmpdtHNKtt2Ueo+BlLBjfZEhYBhK00OsEqM08/7f+eohiF6poe0YRDDd8nAvwtE/Y62Q== } + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.50.1': + resolution: + { integrity: sha512-eSGMVQw9iekut62O7eBdbiccRguuDgiPMsw++BVUg+1K7WjZXHOg/YOT9SWMzPZA+w98G+Fa1VqJgHZOHHnY0Q== } + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.50.1': + resolution: + { integrity: sha512-S208ojx8a4ciIPrLgazF6AgdcNJzQE4+S9rsmOmDJkusvctii+ZvEuIC4v/xFqzbuP8yDjn73oBlNDgF6YGSXQ== } + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.50.1': + resolution: + { integrity: sha512-3Ag8Ls1ggqkGUvSZWYcdgFwriy2lWo+0QlYgEFra/5JGtAd6C5Hw59oojx1DeqcA2Wds2ayRgvJ4qxVTzCHgzg== } + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.50.1': + resolution: + { integrity: sha512-t9YrKfaxCYe7l7ldFERE1BRg/4TATxIg+YieHQ966jwvo7ddHJxPj9cNFWLAzhkVsbBvNA4qTbPVNsZKBO4NSg== } + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.50.1': + resolution: + { integrity: sha512-MCgtFB2+SVNuQmmjHf+wfI4CMxy3Tk8XjA5Z//A0AKD7QXUYFMQcns91K6dEHBvZPCnhJSyDWLApk40Iq/H3tA== } + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.50.1': + resolution: + { integrity: sha512-nEvqG+0jeRmqaUMuwzlfMKwcIVffy/9KGbAGyoa26iu6eSngAYQ512bMXuqqPrlTyfqdlB9FVINs93j534UJrg== } + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.50.1': + resolution: + { integrity: sha512-RDsLm+phmT3MJd9SNxA9MNuEAO/J2fhW8GXk62G/B4G7sLVumNFbRwDL6v5NrESb48k+QMqdGbHgEtfU0LCpbA== } + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.50.1': + resolution: + { integrity: sha512-hpZB/TImk2FlAFAIsoElM3tLzq57uxnGYwplg6WDyAxbYczSi8O2eQ+H2Lx74504rwKtZ3N2g4bCUkiamzS6TQ== } + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.50.1': + resolution: + { integrity: sha512-SXjv8JlbzKM0fTJidX4eVsH+Wmnp0/WcD8gJxIZyR6Gay5Qcsmdbi9zVtnbkGPG8v2vMR1AD06lGWy5FLMcG7A== } + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.50.1': + resolution: + { integrity: sha512-StxAO/8ts62KZVRAm4JZYq9+NqNsV7RvimNK+YM7ry//zebEH6meuugqW/P5OFUCjyQgui+9fUxT6d5NShvMvA== } + cpu: [x64] + os: [win32] + + '@sindresorhus/is@7.0.2': + resolution: + { integrity: sha512-d9xRovfKNz1SKieM0qJdO+PQonjnnIfSNWfHYnBSJ9hkjm0ZPw6HlxscDXYstp3z+7V2GOFHc+J0CYrYTjqCJw== } + engines: { node: '>=18' } + + '@speed-highlight/core@1.2.7': + resolution: + { integrity: sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g== } + + '@types/chai@5.2.2': + resolution: + { integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg== } + + '@types/deep-eql@4.0.2': + resolution: + { integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw== } + + '@types/estree@1.0.8': + resolution: + { integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== } + + '@types/json-schema@7.0.15': + resolution: + { integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== } + + '@types/node@22.18.1': + resolution: + { integrity: sha512-rzSDyhn4cYznVG+PCzGe1lwuMYJrcBS1fc3JqSa2PvtABwWo+dZ1ij5OVok3tqfpEBCBoaR4d7upFJk73HRJDw== } + + '@typescript-eslint/eslint-plugin@8.43.0': + resolution: + { integrity: sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + '@typescript-eslint/parser': ^8.43.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.43.0': + resolution: + { integrity: sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.43.0': + resolution: + { integrity: sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.43.0': + resolution: + { integrity: sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + '@typescript-eslint/tsconfig-utils@8.43.0': + resolution: + { integrity: sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.43.0': + resolution: + { integrity: sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.43.0': + resolution: + { integrity: sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + '@typescript-eslint/typescript-estree@8.43.0': + resolution: + { integrity: sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.43.0': + resolution: + { integrity: sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.43.0': + resolution: + { integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + '@vitest/expect@3.2.4': + resolution: + { integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig== } + + '@vitest/mocker@3.2.4': + resolution: + { integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ== } + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@3.2.4': + resolution: + { integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA== } + + '@vitest/runner@3.2.4': + resolution: + { integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ== } + + '@vitest/snapshot@3.2.4': + resolution: + { integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ== } + + '@vitest/spy@3.2.4': + resolution: + { integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw== } + + '@vitest/utils@3.2.4': + resolution: + { integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA== } + + acorn-jsx@5.3.2: + resolution: + { integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== } + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.2: + resolution: + { integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== } + engines: { node: '>=0.4.0' } + + acorn@8.14.0: + resolution: + { integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== } + engines: { node: '>=0.4.0' } + hasBin: true + + acorn@8.15.0: + resolution: + { integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== } + engines: { node: '>=0.4.0' } + hasBin: true + + ajv@6.12.6: + resolution: + { integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== } + + ansi-styles@4.3.0: + resolution: + { integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== } + engines: { node: '>=8' } + + argparse@2.0.1: + resolution: + { integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== } + + assertion-error@2.0.1: + resolution: + { integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== } + engines: { node: '>=12' } + + balanced-match@1.0.2: + resolution: + { integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== } + + birpc@0.2.14: + resolution: + { integrity: sha512-37FHE8rqsYM5JEKCnXFyHpBCzvgHEExwVVTq+nUmloInU7l8ezD1TpOhKpS8oe1DTYFqEK27rFZVKG43oTqXRA== } + + blake3-wasm@2.1.5: + resolution: + { integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g== } + + brace-expansion@1.1.12: + resolution: + { integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== } + + brace-expansion@2.0.2: + resolution: + { integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== } + + braces@3.0.3: + resolution: + { integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== } + engines: { node: '>=8' } + + browserslist@4.25.4: + resolution: + { integrity: sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg== } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } + hasBin: true + + builtin-modules@5.0.0: + resolution: + { integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg== } + engines: { node: '>=18.20' } + + cac@6.7.14: + resolution: + { integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== } + engines: { node: '>=8' } + + callsites@3.1.0: + resolution: + { integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== } + engines: { node: '>=6' } + + caniuse-lite@1.0.30001741: + resolution: + { integrity: sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw== } + + chai@5.3.3: + resolution: + { integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw== } + engines: { node: '>=18' } + + chalk@4.1.2: + resolution: + { integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== } + engines: { node: '>=10' } + + change-case@5.4.4: + resolution: + { integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w== } + + check-error@2.1.1: + resolution: + { integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== } + engines: { node: '>= 16' } + + ci-info@4.3.0: + resolution: + { integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ== } + engines: { node: '>=8' } + + cjs-module-lexer@1.4.3: + resolution: + { integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== } + + clean-regexp@1.0.0: + resolution: + { integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw== } + engines: { node: '>=4' } + + color-convert@2.0.1: + resolution: + { integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== } + engines: { node: '>=7.0.0' } + + color-name@1.1.4: + resolution: + { integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== } + + color-string@1.9.1: + resolution: + { integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== } + + color@4.2.3: + resolution: + { integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== } + engines: { node: '>=12.5.0' } + + concat-map@0.0.1: + resolution: + { integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== } + + cookie@1.0.2: + resolution: + { integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA== } + engines: { node: '>=18' } + + core-js-compat@3.45.1: + resolution: + { integrity: sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA== } + + cross-spawn@7.0.6: + resolution: + { integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== } + engines: { node: '>= 8' } + + debug@4.4.1: + resolution: + { integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== } + engines: { node: '>=6.0' } + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@5.0.2: + resolution: + { integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== } + engines: { node: '>=6' } + + deep-is@0.1.4: + resolution: + { integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== } + + defu@6.1.4: + resolution: + { integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== } + + detect-libc@2.0.4: + resolution: + { integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA== } + engines: { node: '>=8' } + + devalue@5.3.2: + resolution: + { integrity: sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw== } + + electron-to-chromium@1.5.215: + resolution: + { integrity: sha512-TIvGp57UpeNetj/wV/xpFNpWGb0b/ROw372lHPx5Aafx02gjTBtWnEEcaSX3W2dLM3OSdGGyHX/cHl01JQsLaQ== } + + error-stack-parser-es@1.0.5: + resolution: + { integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA== } + + es-module-lexer@1.7.0: + resolution: + { integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== } + + esbuild@0.25.4: + resolution: + { integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q== } + engines: { node: '>=18' } + hasBin: true + + esbuild@0.25.9: + resolution: + { integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g== } + engines: { node: '>=18' } + hasBin: true + + escalade@3.2.0: + resolution: + { integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== } + engines: { node: '>=6' } + + escape-string-regexp@1.0.5: + resolution: + { integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== } + engines: { node: '>=0.8.0' } + + escape-string-regexp@4.0.0: + resolution: + { integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== } + engines: { node: '>=10' } + + eslint-config-prettier@10.1.8: + resolution: + { integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w== } + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-prettier@5.5.4: + resolution: + { integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg== } + engines: { node: ^14.18.0 || >=16.0.0 } + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-unicorn@61.0.2: + resolution: + { integrity: sha512-zLihukvneYT7f74GNbVJXfWIiNQmkc/a9vYBTE4qPkQZswolWNdu+Wsp9sIXno1JOzdn6OUwLPd19ekXVkahRA== } + engines: { node: ^20.10.0 || >=21.0.0 } + peerDependencies: + eslint: '>=9.29.0' + + eslint-scope@8.4.0: + resolution: + { integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + eslint-visitor-keys@3.4.3: + resolution: + { integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } + + eslint-visitor-keys@4.2.1: + resolution: + { integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + eslint@9.35.0: + resolution: + { integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: + { integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + esquery@1.6.0: + resolution: + { integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== } + engines: { node: '>=0.10' } + + esrecurse@4.3.0: + resolution: + { integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== } + engines: { node: '>=4.0' } + + estraverse@5.3.0: + resolution: + { integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== } + engines: { node: '>=4.0' } + + 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' } + + exit-hook@2.2.1: + resolution: + { integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw== } + engines: { node: '>=6' } + + expect-type@1.2.2: + resolution: + { integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA== } + engines: { node: '>=12.0.0' } + + exsolve@1.0.7: + resolution: + { integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw== } + + fast-deep-equal@3.1.3: + resolution: + { integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== } + + fast-diff@1.3.0: + resolution: + { integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== } + + fast-glob@3.3.3: + resolution: + { integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== } + engines: { node: '>=8.6.0' } + + fast-json-stable-stringify@2.1.0: + resolution: + { integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== } + + fast-levenshtein@2.0.6: + resolution: + { integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== } + + fastq@1.19.1: + resolution: + { integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ== } + + fdir@6.5.0: + resolution: + { integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== } + engines: { node: '>=12.0.0' } + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: + { integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== } + engines: { node: '>=16.0.0' } + + fill-range@7.1.1: + resolution: + { integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== } + engines: { node: '>=8' } + + find-up-simple@1.0.1: + resolution: + { integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ== } + engines: { node: '>=18' } + + find-up@5.0.0: + resolution: + { integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== } + engines: { node: '>=10' } + + flat-cache@4.0.1: + resolution: + { integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== } + engines: { node: '>=16' } + + flatted@3.3.3: + resolution: + { integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== } + + fsevents@2.3.3: + resolution: + { integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] + + glob-parent@5.1.2: + resolution: + { integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== } + engines: { node: '>= 6' } + + glob-parent@6.0.2: + resolution: + { integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== } + engines: { node: '>=10.13.0' } + + glob-to-regexp@0.4.1: + resolution: + { integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== } + + globals@14.0.0: + resolution: + { integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== } + engines: { node: '>=18' } + + globals@16.3.0: + resolution: + { integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ== } + engines: { node: '>=18' } + + graphemer@1.4.0: + resolution: + { integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== } + + has-flag@4.0.0: + resolution: + { integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== } + engines: { node: '>=8' } + + ignore@5.3.2: + resolution: + { integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== } + engines: { node: '>= 4' } + + ignore@7.0.5: + resolution: + { integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== } + engines: { node: '>= 4' } + + import-fresh@3.3.1: + resolution: + { integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== } + engines: { node: '>=6' } + + imurmurhash@0.1.4: + resolution: + { integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== } + engines: { node: '>=0.8.19' } + + indent-string@5.0.0: + resolution: + { integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg== } + engines: { node: '>=12' } + + is-arrayish@0.3.2: + resolution: + { integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== } + + is-builtin-module@5.0.0: + resolution: + { integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA== } + engines: { node: '>=18.20' } + + is-extglob@2.1.1: + resolution: + { integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== } + engines: { node: '>=0.10.0' } + + is-glob@4.0.3: + resolution: + { integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== } + engines: { node: '>=0.10.0' } + + is-number@7.0.0: + resolution: + { integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== } + engines: { node: '>=0.12.0' } + + isexe@2.0.0: + resolution: + { integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== } + + js-tokens@9.0.1: + resolution: + { integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ== } + + js-yaml@4.1.0: + resolution: + { integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== } + hasBin: true + + jsesc@3.0.2: + resolution: + { integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== } + engines: { node: '>=6' } + hasBin: true + + jsesc@3.1.0: + resolution: + { integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== } + engines: { node: '>=6' } + hasBin: true + + json-buffer@3.0.1: + resolution: + { integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== } + + json-schema-traverse@0.4.1: + resolution: + { integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== } + + json-stable-stringify-without-jsonify@1.0.1: + resolution: + { integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== } + + keyv@4.5.4: + resolution: + { integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== } + + kleur@4.1.5: + resolution: + { integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== } + engines: { node: '>=6' } + + levn@0.4.1: + resolution: + { integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== } + engines: { node: '>= 0.8.0' } + + locate-path@6.0.0: + resolution: + { integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== } + engines: { node: '>=10' } + + lodash.merge@4.6.2: + resolution: + { integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== } + + loupe@3.2.1: + resolution: + { integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ== } + + magic-string@0.30.19: + resolution: + { integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw== } + + merge2@1.4.1: + resolution: + { integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== } + engines: { node: '>= 8' } + + micromatch@4.0.8: + resolution: + { integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== } + engines: { node: '>=8.6' } + + mime@3.0.0: + resolution: + { integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== } + engines: { node: '>=10.0.0' } + hasBin: true + + min-indent@1.0.1: + resolution: + { integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== } + engines: { node: '>=4' } + + miniflare@4.20250906.0: + resolution: + { integrity: sha512-T/RWn1sa0ien80s6NjU+Un/tj12gR6wqScZoiLeMJDD4/fK0UXfnbWXJDubnUED8Xjm7RPQ5ESYdE+mhPmMtuQ== } + engines: { node: '>=18.0.0' } + hasBin: true + + minimatch@3.1.2: + resolution: + { integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== } + + minimatch@9.0.5: + resolution: + { integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== } + engines: { node: '>=16 || 14 >=14.17' } + + ms@2.1.3: + resolution: + { integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== } + + nanoid@3.3.11: + resolution: + { integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + + natural-compare@1.4.0: + resolution: + { integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== } + + node-releases@2.0.20: + resolution: + { integrity: sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA== } + + ohash@2.0.11: + resolution: + { integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ== } + + optionator@0.9.4: + resolution: + { integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== } + engines: { node: '>= 0.8.0' } + + p-limit@3.1.0: + resolution: + { integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== } + engines: { node: '>=10' } + + p-locate@5.0.0: + resolution: + { integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== } + engines: { node: '>=10' } + + parent-module@1.0.1: + resolution: + { integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== } + engines: { node: '>=6' } + + path-exists@4.0.0: + resolution: + { integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== } + engines: { node: '>=8' } + + path-key@3.1.1: + resolution: + { integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== } + engines: { node: '>=8' } + + path-to-regexp@6.3.0: + resolution: + { integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== } + + pathe@2.0.3: + resolution: + { integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== } + + pathval@2.0.1: + resolution: + { integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ== } + engines: { node: '>= 14.16' } + + picocolors@1.1.1: + resolution: + { integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== } + + picomatch@2.3.1: + resolution: + { integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== } + engines: { node: '>=8.6' } + + picomatch@4.0.3: + resolution: + { integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== } + engines: { node: '>=12' } + + pluralize@8.0.0: + resolution: + { integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== } + engines: { node: '>=4' } + + postcss@8.5.6: + resolution: + { integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== } + engines: { node: ^10 || ^12 || >=14 } + + prelude-ls@1.2.1: + resolution: + { integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== } + engines: { node: '>= 0.8.0' } + + prettier-linter-helpers@1.0.0: + resolution: + { integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== } + engines: { node: '>=6.0.0' } + + prettier-plugin-organize-imports@4.2.0: + resolution: + { integrity: sha512-Zdy27UhlmyvATZi67BTnLcKTo8fm6Oik59Sz6H64PgZJVs6NJpPD1mT240mmJn62c98/QaL+r3kx9Q3gRpDajg== } + peerDependencies: + prettier: '>=2.0' + typescript: '>=2.9' + vue-tsc: ^2.1.0 || 3 + peerDependenciesMeta: + vue-tsc: + optional: true + + prettier@3.6.2: + resolution: + { integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== } + engines: { node: '>=14' } + hasBin: true + + punycode@2.3.1: + resolution: + { integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== } + engines: { node: '>=6' } + + queue-microtask@1.2.3: + resolution: + { integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== } + + regexp-tree@0.1.27: + resolution: + { integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA== } + hasBin: true + + regjsparser@0.12.0: + resolution: + { integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ== } + hasBin: true + + resolve-from@4.0.0: + resolution: + { integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== } + engines: { node: '>=4' } + + reusify@1.1.0: + resolution: + { integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== } + engines: { iojs: '>=1.0.0', node: '>=0.10.0' } + + rollup@4.50.1: + resolution: + { integrity: sha512-78E9voJHwnXQMiQdiqswVLZwJIzdBKJ1GdI5Zx6XwoFKUIk09/sSrr+05QFzvYb8q6Y9pPV45zzDuYa3907TZA== } + engines: { node: '>=18.0.0', npm: '>=8.0.0' } + hasBin: true + + run-parallel@1.2.0: + resolution: + { integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== } + + semver@7.7.2: + resolution: + { integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== } + engines: { node: '>=10' } + hasBin: true + + sharp@0.33.5: + resolution: + { integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + + shebang-command@2.0.0: + resolution: + { integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== } + engines: { node: '>=8' } + + shebang-regex@3.0.0: + resolution: + { integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== } + engines: { node: '>=8' } + + siginfo@2.0.0: + resolution: + { integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== } + + simple-swizzle@0.2.2: + resolution: + { integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== } + + source-map-js@1.2.1: + resolution: + { integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== } + engines: { node: '>=0.10.0' } + + stackback@0.0.2: + resolution: + { integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== } + + std-env@3.9.0: + resolution: + { integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw== } + + stoppable@1.1.0: + resolution: + { integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== } + engines: { node: '>=4', npm: '>=6' } + + strip-indent@4.0.0: + resolution: + { integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== } + engines: { node: '>=12' } + + strip-json-comments@3.1.1: + resolution: + { integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== } + engines: { node: '>=8' } + + strip-literal@3.0.0: + resolution: + { integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA== } + + supports-color@10.2.2: + resolution: + { integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g== } + engines: { node: '>=18' } + + supports-color@7.2.0: + resolution: + { integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== } + engines: { node: '>=8' } + + synckit@0.11.11: + resolution: + { integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw== } + engines: { node: ^14.18.0 || >=16.0.0 } + + tinybench@2.9.0: + resolution: + { integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== } + + tinyexec@0.3.2: + resolution: + { integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA== } + + tinyglobby@0.2.15: + resolution: + { integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== } + engines: { node: '>=12.0.0' } + + tinypool@1.1.1: + resolution: + { integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg== } + engines: { node: ^18.0.0 || >=20.0.0 } + + tinyrainbow@2.0.0: + resolution: + { integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw== } + engines: { node: '>=14.0.0' } + + tinyspy@4.0.3: + resolution: + { integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A== } + engines: { node: '>=14.0.0' } + + to-regex-range@5.0.1: + resolution: + { integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== } + engines: { node: '>=8.0' } + + ts-api-utils@2.1.0: + resolution: + { integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== } + engines: { node: '>=18.12' } + peerDependencies: + typescript: '>=4.8.4' + + tslib@2.8.1: + resolution: + { integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== } + + type-check@0.4.0: + resolution: + { integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== } + engines: { node: '>= 0.8.0' } + + typescript-eslint@8.43.0: + resolution: + { integrity: sha512-FyRGJKUGvcFekRRcBKFBlAhnp4Ng8rhe8tuvvkR9OiU0gfd4vyvTRQHEckO6VDlH57jbeUQem2IpqPq9kLJH+w== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.2: + resolution: + { integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== } + engines: { node: '>=14.17' } + hasBin: true + + ufo@1.6.1: + resolution: + { integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA== } + + undici-types@6.21.0: + resolution: + { integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== } + + undici@7.15.0: + resolution: + { integrity: sha512-7oZJCPvvMvTd0OlqWsIxTuItTpJBpU1tcbVl24FMn3xt3+VSunwUasmfPJRE57oNO1KsZ4PgA1xTdAX4hq8NyQ== } + engines: { node: '>=20.18.1' } + + unenv@2.0.0-rc.21: + resolution: + { integrity: sha512-Wj7/AMtE9MRnAXa6Su3Lk0LNCfqDYgfwVjwRFVum9U7wsto1imuHqk4kTm7Jni+5A0Hn7dttL6O/zjvUvoo+8A== } + + update-browserslist-db@1.1.3: + resolution: + { integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== } + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: + { integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== } + + vite-node@3.2.4: + resolution: + { integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg== } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } + hasBin: true + + vite@7.1.5: + resolution: + { integrity: sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ== } + engines: { node: ^20.19.0 || >=22.12.0 } + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@3.2.4: + resolution: + { integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A== } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + which@2.0.2: + resolution: + { integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== } + 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' } + + workerd@1.20250906.0: + resolution: + { integrity: sha512-ryVyEaqXPPsr/AxccRmYZZmDAkfQVjhfRqrNTlEeN8aftBk6Ca1u7/VqmfOayjCXrA+O547TauebU+J3IpvFXw== } + engines: { node: '>=16' } + hasBin: true + + wrangler@4.35.0: + resolution: + { integrity: sha512-HbyXtbrh4Fi3mU8ussY85tVdQ74qpVS1vctUgaPc+bPrXBTqfDLkZ6VRtHAVF/eBhz4SFmhJtCQpN1caY2Ak8A== } + engines: { node: '>=18.0.0' } + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20250906.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + + ws@8.18.0: + resolution: + { integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== } + 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 + + yocto-queue@0.1.0: + resolution: + { integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== } + engines: { node: '>=10' } + + youch-core@0.3.3: + resolution: + { integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA== } + + youch@4.1.0-beta.10: + resolution: + { integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ== } + + zod@3.22.3: + resolution: + { integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug== } + +snapshots: + '@babel/helper-validator-identifier@7.27.1': {} + + '@cloudflare/kv-asset-handler@0.4.0': + dependencies: + mime: 3.0.0 + + '@cloudflare/unenv-preset@2.7.3(unenv@2.0.0-rc.21)(workerd@1.20250906.0)': + dependencies: + unenv: 2.0.0-rc.21 + optionalDependencies: + workerd: 1.20250906.0 + + '@cloudflare/vitest-pool-workers@0.8.71(@cloudflare/workers-types@4.20250909.0)(@vitest/runner@3.2.4)(@vitest/snapshot@3.2.4)(vitest@3.2.4(@types/node@22.18.1))': + dependencies: + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + birpc: 0.2.14 + cjs-module-lexer: 1.4.3 + devalue: 5.3.2 + miniflare: 4.20250906.0 + semver: 7.7.2 + vitest: 3.2.4(@types/node@22.18.1) + wrangler: 4.35.0(@cloudflare/workers-types@4.20250909.0) + zod: 3.22.3 + transitivePeerDependencies: + - '@cloudflare/workers-types' + - bufferutil + - utf-8-validate + + '@cloudflare/workerd-darwin-64@1.20250906.0': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20250906.0': + optional: true + + '@cloudflare/workerd-linux-64@1.20250906.0': + optional: true + + '@cloudflare/workerd-linux-arm64@1.20250906.0': + optional: true + + '@cloudflare/workerd-windows-64@1.20250906.0': + optional: true + + '@cloudflare/workers-types@4.20250909.0': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@emnapi/runtime@1.5.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.25.4': + optional: true + + '@esbuild/aix-ppc64@0.25.9': + optional: true + + '@esbuild/android-arm64@0.25.4': + optional: true + + '@esbuild/android-arm64@0.25.9': + optional: true + + '@esbuild/android-arm@0.25.4': + optional: true + + '@esbuild/android-arm@0.25.9': + optional: true + + '@esbuild/android-x64@0.25.4': + optional: true + + '@esbuild/android-x64@0.25.9': + optional: true + + '@esbuild/darwin-arm64@0.25.4': + optional: true + + '@esbuild/darwin-arm64@0.25.9': + optional: true + + '@esbuild/darwin-x64@0.25.4': + optional: true + + '@esbuild/darwin-x64@0.25.9': + optional: true + + '@esbuild/freebsd-arm64@0.25.4': + optional: true + + '@esbuild/freebsd-arm64@0.25.9': + optional: true + + '@esbuild/freebsd-x64@0.25.4': + optional: true + + '@esbuild/freebsd-x64@0.25.9': + optional: true + + '@esbuild/linux-arm64@0.25.4': + optional: true + + '@esbuild/linux-arm64@0.25.9': + optional: true + + '@esbuild/linux-arm@0.25.4': + optional: true + + '@esbuild/linux-arm@0.25.9': + optional: true + + '@esbuild/linux-ia32@0.25.4': + optional: true + + '@esbuild/linux-ia32@0.25.9': + optional: true + + '@esbuild/linux-loong64@0.25.4': + optional: true + + '@esbuild/linux-loong64@0.25.9': + optional: true + + '@esbuild/linux-mips64el@0.25.4': + optional: true + + '@esbuild/linux-mips64el@0.25.9': + optional: true + + '@esbuild/linux-ppc64@0.25.4': + optional: true + + '@esbuild/linux-ppc64@0.25.9': + optional: true + + '@esbuild/linux-riscv64@0.25.4': + optional: true + + '@esbuild/linux-riscv64@0.25.9': + optional: true + + '@esbuild/linux-s390x@0.25.4': + optional: true + + '@esbuild/linux-s390x@0.25.9': + optional: true + + '@esbuild/linux-x64@0.25.4': + optional: true + + '@esbuild/linux-x64@0.25.9': + optional: true + + '@esbuild/netbsd-arm64@0.25.4': + optional: true + + '@esbuild/netbsd-arm64@0.25.9': + optional: true + + '@esbuild/netbsd-x64@0.25.4': + optional: true + + '@esbuild/netbsd-x64@0.25.9': + optional: true + + '@esbuild/openbsd-arm64@0.25.4': + optional: true + + '@esbuild/openbsd-arm64@0.25.9': + optional: true + + '@esbuild/openbsd-x64@0.25.4': + optional: true + + '@esbuild/openbsd-x64@0.25.9': + optional: true + + '@esbuild/openharmony-arm64@0.25.9': + optional: true + + '@esbuild/sunos-x64@0.25.4': + optional: true + + '@esbuild/sunos-x64@0.25.9': + optional: true + + '@esbuild/win32-arm64@0.25.4': + optional: true + + '@esbuild/win32-arm64@0.25.9': + optional: true + + '@esbuild/win32-ia32@0.25.4': + optional: true + + '@esbuild/win32-ia32@0.25.9': + optional: true + + '@esbuild/win32-x64@0.25.4': + optional: true + + '@esbuild/win32-x64@0.25.9': + optional: true + + '@eslint-community/eslint-utils@4.9.0(eslint@9.35.0)': + dependencies: + eslint: 9.35.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.21.0': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.1 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.3.1': {} + + '@eslint/core@0.15.2': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.1 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.35.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.3.5': + dependencies: + '@eslint/core': 0.15.2 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.5.0 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@pkgr/core@0.2.9': {} + + '@poppinss/colors@4.1.5': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.6.4': + dependencies: + '@poppinss/colors': 4.1.5 + '@sindresorhus/is': 7.0.2 + supports-color: 10.2.2 + + '@poppinss/exception@1.2.2': {} + + '@rollup/rollup-android-arm-eabi@4.50.1': + optional: true + + '@rollup/rollup-android-arm64@4.50.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.50.1': + optional: true + + '@rollup/rollup-darwin-x64@4.50.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.50.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.50.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.50.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.50.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.50.1': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.50.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.50.1': + optional: true + + '@rollup/rollup-openharmony-arm64@4.50.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.50.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.50.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.50.1': + optional: true + + '@sindresorhus/is@7.0.2': {} + + '@speed-highlight/core@1.2.7': {} + + '@types/chai@5.2.2': + dependencies: + '@types/deep-eql': 4.0.2 + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@22.18.1': + dependencies: + undici-types: 6.21.0 + + '@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.43.0(eslint@9.35.0)(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/type-utils': 8.43.0(eslint@9.35.0)(typescript@5.9.2) + '@typescript-eslint/utils': 8.43.0(eslint@9.35.0)(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.43.0 + eslint: 9.35.0 + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.43.0 + debug: 4.4.1 + eslint: 9.35.0 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.43.0(typescript@5.9.2)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2) + '@typescript-eslint/types': 8.43.0 + debug: 4.4.1 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.43.0': + dependencies: + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/visitor-keys': 8.43.0 + + '@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.9.2)': + dependencies: + typescript: 5.9.2 + + '@typescript-eslint/type-utils@8.43.0(eslint@9.35.0)(typescript@5.9.2)': + dependencies: + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.43.0(eslint@9.35.0)(typescript@5.9.2) + debug: 4.4.1 + eslint: 9.35.0 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.43.0': {} + + '@typescript-eslint/typescript-estree@8.43.0(typescript@5.9.2)': + dependencies: + '@typescript-eslint/project-service': 8.43.0(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2) + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/visitor-keys': 8.43.0 + debug: 4.4.1 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.43.0(eslint@9.35.0)(typescript@5.9.2)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0) + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + eslint: 9.35.0 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.43.0': + dependencies: + '@typescript-eslint/types': 8.43.0 + eslint-visitor-keys: 4.2.1 + + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.2 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + tinyrainbow: 2.0.0 + + '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@22.18.1))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.19 + optionalDependencies: + vite: 7.1.5(@types/node@22.18.1) + + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + + '@vitest/runner@3.2.4': + dependencies: + '@vitest/utils': 3.2.4 + pathe: 2.0.3 + strip-literal: 3.0.0 + + '@vitest/snapshot@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.19 + pathe: 2.0.3 + + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.3 + + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-walk@8.3.2: {} + + acorn@8.14.0: {} + + acorn@8.15.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + assertion-error@2.0.1: {} + + balanced-match@1.0.2: {} + + birpc@0.2.14: {} + + blake3-wasm@2.1.5: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.25.4: + dependencies: + caniuse-lite: 1.0.30001741 + electron-to-chromium: 1.5.215 + node-releases: 2.0.20 + update-browserslist-db: 1.1.3(browserslist@4.25.4) + + builtin-modules@5.0.0: {} + + cac@6.7.14: {} + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001741: {} + + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + change-case@5.4.4: {} + + check-error@2.1.1: {} + + ci-info@4.3.0: {} + + cjs-module-lexer@1.4.3: {} + + clean-regexp@1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + concat-map@0.0.1: {} + + cookie@1.0.2: {} + + core-js-compat@3.45.1: + dependencies: + browserslist: 4.25.4 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.4.1: + dependencies: + ms: 2.1.3 + + deep-eql@5.0.2: {} + + deep-is@0.1.4: {} + + defu@6.1.4: {} + + detect-libc@2.0.4: {} + + devalue@5.3.2: {} + + electron-to-chromium@1.5.215: {} + + error-stack-parser-es@1.0.5: {} + + es-module-lexer@1.7.0: {} + + esbuild@0.25.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.4 + '@esbuild/android-arm': 0.25.4 + '@esbuild/android-arm64': 0.25.4 + '@esbuild/android-x64': 0.25.4 + '@esbuild/darwin-arm64': 0.25.4 + '@esbuild/darwin-x64': 0.25.4 + '@esbuild/freebsd-arm64': 0.25.4 + '@esbuild/freebsd-x64': 0.25.4 + '@esbuild/linux-arm': 0.25.4 + '@esbuild/linux-arm64': 0.25.4 + '@esbuild/linux-ia32': 0.25.4 + '@esbuild/linux-loong64': 0.25.4 + '@esbuild/linux-mips64el': 0.25.4 + '@esbuild/linux-ppc64': 0.25.4 + '@esbuild/linux-riscv64': 0.25.4 + '@esbuild/linux-s390x': 0.25.4 + '@esbuild/linux-x64': 0.25.4 + '@esbuild/netbsd-arm64': 0.25.4 + '@esbuild/netbsd-x64': 0.25.4 + '@esbuild/openbsd-arm64': 0.25.4 + '@esbuild/openbsd-x64': 0.25.4 + '@esbuild/sunos-x64': 0.25.4 + '@esbuild/win32-arm64': 0.25.4 + '@esbuild/win32-ia32': 0.25.4 + '@esbuild/win32-x64': 0.25.4 + + esbuild@0.25.9: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.9 + '@esbuild/android-arm': 0.25.9 + '@esbuild/android-arm64': 0.25.9 + '@esbuild/android-x64': 0.25.9 + '@esbuild/darwin-arm64': 0.25.9 + '@esbuild/darwin-x64': 0.25.9 + '@esbuild/freebsd-arm64': 0.25.9 + '@esbuild/freebsd-x64': 0.25.9 + '@esbuild/linux-arm': 0.25.9 + '@esbuild/linux-arm64': 0.25.9 + '@esbuild/linux-ia32': 0.25.9 + '@esbuild/linux-loong64': 0.25.9 + '@esbuild/linux-mips64el': 0.25.9 + '@esbuild/linux-ppc64': 0.25.9 + '@esbuild/linux-riscv64': 0.25.9 + '@esbuild/linux-s390x': 0.25.9 + '@esbuild/linux-x64': 0.25.9 + '@esbuild/netbsd-arm64': 0.25.9 + '@esbuild/netbsd-x64': 0.25.9 + '@esbuild/openbsd-arm64': 0.25.9 + '@esbuild/openbsd-x64': 0.25.9 + '@esbuild/openharmony-arm64': 0.25.9 + '@esbuild/sunos-x64': 0.25.9 + '@esbuild/win32-arm64': 0.25.9 + '@esbuild/win32-ia32': 0.25.9 + '@esbuild/win32-x64': 0.25.9 + + escalade@3.2.0: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@10.1.8(eslint@9.35.0): + dependencies: + eslint: 9.35.0 + + eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.35.0))(eslint@9.35.0)(prettier@3.6.2): + dependencies: + eslint: 9.35.0 + prettier: 3.6.2 + prettier-linter-helpers: 1.0.0 + synckit: 0.11.11 + optionalDependencies: + eslint-config-prettier: 10.1.8(eslint@9.35.0) + + eslint-plugin-unicorn@61.0.2(eslint@9.35.0): + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0) + '@eslint/plugin-kit': 0.3.5 + change-case: 5.4.4 + ci-info: 4.3.0 + clean-regexp: 1.0.0 + core-js-compat: 3.45.1 + eslint: 9.35.0 + esquery: 1.6.0 + find-up-simple: 1.0.1 + globals: 16.3.0 + indent-string: 5.0.0 + is-builtin-module: 5.0.0 + jsesc: 3.1.0 + pluralize: 8.0.0 + regexp-tree: 0.1.27 + regjsparser: 0.12.0 + semver: 7.7.2 + strip-indent: 4.0.0 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@9.35.0: + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.21.0 + '@eslint/config-helpers': 0.3.1 + '@eslint/core': 0.15.2 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.35.0 + '@eslint/plugin-kit': 0.3.5 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.1 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + exit-hook@2.2.1: {} + + expect-type@1.2.2: {} + + exsolve@1.0.7: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up-simple@1.0.1: {} + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + fsevents@2.3.3: + optional: true + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + + globals@14.0.0: {} + + globals@16.3.0: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + indent-string@5.0.0: {} + + is-arrayish@0.3.2: {} + + is-builtin-module@5.0.0: + dependencies: + builtin-modules: 5.0.0 + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + isexe@2.0.0: {} + + js-tokens@9.0.1: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.0.2: {} + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@4.1.5: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + loupe@3.2.1: {} + + magic-string@0.30.19: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime@3.0.0: {} + + min-indent@1.0.1: {} + + miniflare@4.20250906.0: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.14.0 + acorn-walk: 8.3.2 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + sharp: 0.33.5 + stoppable: 1.1.0 + undici: 7.15.0 + workerd: 1.20250906.0 + ws: 8.18.0 + youch: 4.1.0-beta.10 + zod: 3.22.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + node-releases@2.0.20: {} + + ohash@2.0.11: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-to-regexp@6.3.0: {} + + pathe@2.0.3: {} + + pathval@2.0.1: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pluralize@8.0.0: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier-plugin-organize-imports@4.2.0(prettier@3.6.2)(typescript@5.9.2): + dependencies: + prettier: 3.6.2 + typescript: 5.9.2 + + prettier@3.6.2: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + regexp-tree@0.1.27: {} + + regjsparser@0.12.0: + dependencies: + jsesc: 3.0.2 + + resolve-from@4.0.0: {} + + reusify@1.1.0: {} + + rollup@4.50.1: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.50.1 + '@rollup/rollup-android-arm64': 4.50.1 + '@rollup/rollup-darwin-arm64': 4.50.1 + '@rollup/rollup-darwin-x64': 4.50.1 + '@rollup/rollup-freebsd-arm64': 4.50.1 + '@rollup/rollup-freebsd-x64': 4.50.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.50.1 + '@rollup/rollup-linux-arm-musleabihf': 4.50.1 + '@rollup/rollup-linux-arm64-gnu': 4.50.1 + '@rollup/rollup-linux-arm64-musl': 4.50.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.50.1 + '@rollup/rollup-linux-ppc64-gnu': 4.50.1 + '@rollup/rollup-linux-riscv64-gnu': 4.50.1 + '@rollup/rollup-linux-riscv64-musl': 4.50.1 + '@rollup/rollup-linux-s390x-gnu': 4.50.1 + '@rollup/rollup-linux-x64-gnu': 4.50.1 + '@rollup/rollup-linux-x64-musl': 4.50.1 + '@rollup/rollup-openharmony-arm64': 4.50.1 + '@rollup/rollup-win32-arm64-msvc': 4.50.1 + '@rollup/rollup-win32-ia32-msvc': 4.50.1 + '@rollup/rollup-win32-x64-msvc': 4.50.1 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + semver@7.7.2: {} + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.0.4 + semver: 7.7.2 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@3.9.0: {} + + stoppable@1.1.0: {} + + strip-indent@4.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@3.1.1: {} + + strip-literal@3.0.0: + dependencies: + js-tokens: 9.0.1 + + supports-color@10.2.2: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + synckit@0.11.11: + dependencies: + '@pkgr/core': 0.2.9 + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinypool@1.1.1: {} + + tinyrainbow@2.0.0: {} + + tinyspy@4.0.3: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-api-utils@2.1.0(typescript@5.9.2): + dependencies: + typescript: 5.9.2 + + tslib@2.8.1: + optional: true + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.43.0(eslint@9.35.0)(typescript@5.9.2): + dependencies: + '@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2) + '@typescript-eslint/parser': 8.43.0(eslint@9.35.0)(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.43.0(eslint@9.35.0)(typescript@5.9.2) + eslint: 9.35.0 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + typescript@5.9.2: {} + + ufo@1.6.1: {} + + undici-types@6.21.0: {} + + undici@7.15.0: {} + + unenv@2.0.0-rc.21: + dependencies: + defu: 6.1.4 + exsolve: 1.0.7 + ohash: 2.0.11 + pathe: 2.0.3 + ufo: 1.6.1 + + update-browserslist-db@1.1.3(browserslist@4.25.4): + dependencies: + browserslist: 4.25.4 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vite-node@3.2.4(@types/node@22.18.1): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.1.5(@types/node@22.18.1) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite@7.1.5(@types/node@22.18.1): + dependencies: + esbuild: 0.25.9 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.50.1 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.18.1 + fsevents: 2.3.3 + + vitest@3.2.4(@types/node@22.18.1): + dependencies: + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@22.18.1)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + debug: 4.4.1 + expect-type: 1.2.2 + magic-string: 0.30.19 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 7.1.5(@types/node@22.18.1) + vite-node: 3.2.4(@types/node@22.18.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.18.1 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + which@2.0.2: + 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: {} + + workerd@1.20250906.0: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20250906.0 + '@cloudflare/workerd-darwin-arm64': 1.20250906.0 + '@cloudflare/workerd-linux-64': 1.20250906.0 + '@cloudflare/workerd-linux-arm64': 1.20250906.0 + '@cloudflare/workerd-windows-64': 1.20250906.0 + + wrangler@4.35.0(@cloudflare/workers-types@4.20250909.0): + dependencies: + '@cloudflare/kv-asset-handler': 0.4.0 + '@cloudflare/unenv-preset': 2.7.3(unenv@2.0.0-rc.21)(workerd@1.20250906.0) + blake3-wasm: 2.1.5 + esbuild: 0.25.4 + miniflare: 4.20250906.0 + path-to-regexp: 6.3.0 + unenv: 2.0.0-rc.21 + workerd: 1.20250906.0 + optionalDependencies: + '@cloudflare/workers-types': 4.20250909.0 + fsevents: 2.3.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ws@8.18.0: {} + + yocto-queue@0.1.0: {} + + youch-core@0.3.3: + dependencies: + '@poppinss/exception': 1.2.2 + error-stack-parser-es: 1.0.5 + + youch@4.1.0-beta.10: + dependencies: + '@poppinss/colors': 4.1.5 + '@poppinss/dumper': 0.6.4 + '@speed-highlight/core': 1.2.7 + cookie: 1.0.2 + youch-core: 0.3.3 + + zod@3.22.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..8ab3e17 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - 'apps/*' diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..1746e70 --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2021", + "module": "Node16", + "lib": ["ES2021"], + "moduleResolution": "Node16", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "allowJs": true, + "checkJs": true, + "noEmit": true + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..f49ed5b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "types": ["@cloudflare/workers-types", "@cloudflare/vitest-pool-workers", "@types/node"], + "composite": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "src/**/*.ts", + "apps/*/src/**/*.ts", + "apps/*/worker-configuration.d.ts", + "*.config.ts", + "apps/*/*.config.ts" + ], + "exclude": ["node_modules", "**/dist", "**/.wrangler"] +} diff --git a/vitest.base.config.ts b/vitest.base.config.ts new file mode 100644 index 0000000..931e511 --- /dev/null +++ b/vitest.base.config.ts @@ -0,0 +1,11 @@ +import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config'; + +export default defineWorkersConfig({ + test: { + poolOptions: { + workers: { + wrangler: { configPath: './wrangler.toml' }, + }, + }, + }, +});