diff --git a/examples/solid/todo/CHANGELOG.md b/examples/solid/todo/CHANGELOG.md new file mode 100644 index 00000000..4f804dba --- /dev/null +++ b/examples/solid/todo/CHANGELOG.md @@ -0,0 +1,2 @@ +# examples/solid/todo + diff --git a/examples/solid/todo/README.md b/examples/solid/todo/README.md new file mode 100644 index 00000000..adbeb92e --- /dev/null +++ b/examples/solid/todo/README.md @@ -0,0 +1,17 @@ +# Todo example app + +## How to run + +- Go to the root of the repository and run: + + - `pnpm install` + - `pnpm build` + +- Install packages + `pnpm install` + +- Start dev server & Docker containers + `pnpm dev` + +- Run db migrations + `pnpm db:push` diff --git a/examples/solid/todo/docker-compose.yml b/examples/solid/todo/docker-compose.yml new file mode 100644 index 00000000..5d6ece8c --- /dev/null +++ b/examples/solid/todo/docker-compose.yml @@ -0,0 +1,38 @@ +version: "3.8" +services: + postgres: + image: postgres:17-alpine + environment: + POSTGRES_DB: todo_app + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - "54322:5432" + volumes: + - ./postgres.conf:/etc/postgresql/postgresql.conf:ro + tmpfs: + - /var/lib/postgresql/data + - /tmp + command: + - postgres + - -c + - config_file=/etc/postgresql/postgresql.conf + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 5s + retries: 5 + + electric: + image: electricsql/electric:canary + environment: + DATABASE_URL: postgresql://postgres:postgres@postgres:5432/todo_app?sslmode=disable + ELECTRIC_INSECURE: true + ports: + - 3003:3000 + depends_on: + postgres: + condition: service_healthy + +volumes: + postgres_data: diff --git a/examples/solid/todo/drizzle.config.ts b/examples/solid/todo/drizzle.config.ts new file mode 100644 index 00000000..55063343 --- /dev/null +++ b/examples/solid/todo/drizzle.config.ts @@ -0,0 +1,15 @@ +import type { Config } from "drizzle-kit" + +export default { + schema: `./src/db/schema.ts`, + out: `./drizzle`, + dialect: `postgresql`, + casing: `snake_case`, + dbCredentials: { + host: process.env.DB_HOST || `localhost`, + port: parseInt(process.env.DB_PORT || `54322`), + user: process.env.DB_USER || `postgres`, + password: process.env.DB_PASSWORD || `postgres`, + database: process.env.DB_NAME || `todo_app`, + }, +} satisfies Config diff --git a/examples/solid/todo/drizzle/0000_whole_sprite.sql b/examples/solid/todo/drizzle/0000_whole_sprite.sql new file mode 100644 index 00000000..8223fef7 --- /dev/null +++ b/examples/solid/todo/drizzle/0000_whole_sprite.sql @@ -0,0 +1,7 @@ +CREATE TABLE "todos" ( + "id" serial PRIMARY KEY NOT NULL, + "text" text NOT NULL, + "completed" boolean DEFAULT false NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); diff --git a/examples/solid/todo/drizzle/0001_sturdy_titania.sql b/examples/solid/todo/drizzle/0001_sturdy_titania.sql new file mode 100644 index 00000000..fefdf679 --- /dev/null +++ b/examples/solid/todo/drizzle/0001_sturdy_titania.sql @@ -0,0 +1,8 @@ +CREATE TABLE "config" ( + "id" serial PRIMARY KEY NOT NULL, + "key" text NOT NULL, + "value" text NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "config_key_unique" UNIQUE("key") +); diff --git a/examples/solid/todo/drizzle/0002_update_timestamps_trigger.sql b/examples/solid/todo/drizzle/0002_update_timestamps_trigger.sql new file mode 100644 index 00000000..3e39c477 --- /dev/null +++ b/examples/solid/todo/drizzle/0002_update_timestamps_trigger.sql @@ -0,0 +1,29 @@ +-- Custom SQL migration file, put your code below! -- + +-- Create a function to update the updated_at timestamp +CREATE OR REPLACE FUNCTION update_updated_at_column() +RETURNS TRIGGER AS $$ +BEGIN + NEW.updated_at = NOW(); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +-- Create trigger for todos table +DROP TRIGGER IF EXISTS update_todos_updated_at ON "todos"; +CREATE TRIGGER update_todos_updated_at +BEFORE UPDATE ON "todos" +FOR EACH ROW +EXECUTE FUNCTION update_updated_at_column(); + +-- Create trigger for config table +DROP TRIGGER IF EXISTS update_config_updated_at ON "config"; +CREATE TRIGGER update_config_updated_at +BEFORE UPDATE ON "config" +FOR EACH ROW +EXECUTE FUNCTION update_updated_at_column(); + +-- Insert default config for background color +INSERT INTO "config" ("key", "value") +VALUES ('backgroundColor', '#f5f5f5') +ON CONFLICT ("key") DO NOTHING; \ No newline at end of file diff --git a/examples/solid/todo/drizzle/meta/0000_snapshot.json b/examples/solid/todo/drizzle/meta/0000_snapshot.json new file mode 100644 index 00000000..407155f7 --- /dev/null +++ b/examples/solid/todo/drizzle/meta/0000_snapshot.json @@ -0,0 +1,65 @@ +{ + "id": "1649b703-2b2d-413c-8185-15390a9d97e7", + "prevId": "00000000-0000-0000-0000-000000000000", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.todos": { + "name": "todos", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "completed": { + "name": "completed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/examples/solid/todo/drizzle/meta/0001_snapshot.json b/examples/solid/todo/drizzle/meta/0001_snapshot.json new file mode 100644 index 00000000..5774acf0 --- /dev/null +++ b/examples/solid/todo/drizzle/meta/0001_snapshot.json @@ -0,0 +1,116 @@ +{ + "id": "1b3a815a-1865-451b-b646-983e995ee97e", + "prevId": "1649b703-2b2d-413c-8185-15390a9d97e7", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.config": { + "name": "config", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "config_key_unique": { + "name": "config_key_unique", + "nullsNotDistinct": false, + "columns": ["key"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.todos": { + "name": "todos", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "completed": { + "name": "completed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/examples/solid/todo/drizzle/meta/0002_snapshot.json b/examples/solid/todo/drizzle/meta/0002_snapshot.json new file mode 100644 index 00000000..dde3eae1 --- /dev/null +++ b/examples/solid/todo/drizzle/meta/0002_snapshot.json @@ -0,0 +1,116 @@ +{ + "id": "017c3a1c-9d70-4fed-ad07-9a2e1ab49bb4", + "prevId": "1b3a815a-1865-451b-b646-983e995ee97e", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.config": { + "name": "config", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "config_key_unique": { + "name": "config_key_unique", + "columns": ["key"], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.todos": { + "name": "todos", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "completed": { + "name": "completed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "views": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/examples/solid/todo/drizzle/meta/_journal.json b/examples/solid/todo/drizzle/meta/_journal.json new file mode 100644 index 00000000..bf477dc8 --- /dev/null +++ b/examples/solid/todo/drizzle/meta/_journal.json @@ -0,0 +1,27 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1740502196428, + "tag": "0000_whole_sprite", + "breakpoints": true + }, + { + "idx": 1, + "version": "7", + "when": 1740601351239, + "tag": "0001_sturdy_titania", + "breakpoints": true + }, + { + "idx": 2, + "version": "7", + "when": 1740606615508, + "tag": "0002_update_timestamps_trigger", + "breakpoints": true + } + ] +} diff --git a/examples/solid/todo/index.html b/examples/solid/todo/index.html new file mode 100644 index 00000000..1d0525a7 --- /dev/null +++ b/examples/solid/todo/index.html @@ -0,0 +1,14 @@ + + + + + + + + TODO App + + +
+ + + diff --git a/examples/solid/todo/package.json b/examples/solid/todo/package.json new file mode 100644 index 00000000..39d56119 --- /dev/null +++ b/examples/solid/todo/package.json @@ -0,0 +1,44 @@ +{ + "name": "examples/solid/todo", + "private": true, + "version": "0.0.4", + "dependencies": { + "@tanstack/db-collections": "workspace:*", + "@tanstack/query-core": "^5.75.7", + "@tanstack/solid-db": "workspace:*", + "cors": "^2.8.5", + "drizzle-orm": "^0.40.1", + "drizzle-zod": "^0.7.0", + "express": "^4.19.2", + "postgres": "^3.4.5", + "solid-js": "^1.9.4", + "tailwindcss": "^4.0.17", + "zod": "^3.24.2" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.0.0-alpha.8", + "@types/cors": "^2.8.17", + "@types/express": "^4.17.21", + "@types/node": "^22.13.10", + "@types/pg": "^8.11.11", + "vite-plugin-solid": "^2.11.6", + "concurrently": "^9.1.2", + "dotenv": "^16.3.1", + "drizzle-kit": "^0.30.5", + "pg": "^8.14.1", + "tsx": "^4.6.2", + "typescript": "^5.8.2", + "vite": "^6.2.2" + }, + "scripts": { + "api:dev": "tsx watch src/api/server.ts", + "build": "tsc -b && vite build", + "db:ensure-config": "tsx scripts/ensure-default-config.ts", + "db:generate": "drizzle-kit generate", + "db:push": "tsx scripts/migrate.ts", + "db:studio": "drizzle-kit studio", + "dev": "docker compose up -d && concurrently \"pnpm api:dev\" \"vite\"", + "preview": "vite preview" + }, + "type": "module" +} \ No newline at end of file diff --git a/examples/solid/todo/pnpm-lock.yaml b/examples/solid/todo/pnpm-lock.yaml new file mode 100644 index 00000000..7b09a6b0 --- /dev/null +++ b/examples/solid/todo/pnpm-lock.yaml @@ -0,0 +1,5671 @@ +lockfileVersion: "9.0" + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + .: + dependencies: + "@types/use-sync-external-store": + specifier: ^0.0.6 + version: 0.0.6 + cors: + specifier: ^2.8.5 + version: 2.8.5 + drizzle-orm: + specifier: ^0.39.3 + version: 0.39.3(@types/pg@8.11.11)(kysely@0.27.5)(pg@8.13.3) + drizzle-zod: + specifier: ^0.7.0 + version: 0.7.0(drizzle-orm@0.39.3(@types/pg@8.11.11)(kysely@0.27.5)(pg@8.13.3))(zod@3.24.2) + express: + specifier: ^4.19.2 + version: 4.21.2 + kysely: + specifier: ^0.27.3 + version: 0.27.5 + mitt: + specifier: ^3.0.1 + version: 3.0.1 + pg: + specifier: ^8.13.3 + version: 8.13.3 + react: + specifier: ^19.0.0 + version: 19.0.0 + react-dom: + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) + zod: + specifier: ^3.24.2 + version: 3.24.2 + devDependencies: + "@eslint/js": + specifier: ^9.19.0 + version: 9.21.0 + "@tailwindcss/vite": + specifier: ^4.0.8 + version: 4.0.8(vite@6.1.1(@types/node@22.13.5)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.3)) + "@types/cors": + specifier: ^2.8.17 + version: 2.8.17 + "@types/express": + specifier: ^4.17.21 + version: 4.17.21 + "@types/pg": + specifier: ^8.11.11 + version: 8.11.11 + "@types/react": + specifier: ^19.0.8 + version: 19.0.10 + "@types/react-dom": + specifier: ^19.0.3 + version: 19.0.4(@types/react@19.0.10) + "@vitejs/plugin-react": + specifier: ^4.3.4 + version: 4.3.4(vite@6.1.1(@types/node@22.13.5)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.3)) + concurrently: + specifier: ^9.1.2 + version: 9.1.2 + dotenv: + specifier: ^16.4.7 + version: 16.4.7 + drizzle-kit: + specifier: ^0.30.4 + version: 0.30.4 + eslint: + specifier: ^9.19.0 + version: 9.21.0(jiti@2.4.2) + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.1.0(eslint@9.21.0(jiti@2.4.2)) + eslint-plugin-react-refresh: + specifier: ^0.4.18 + version: 0.4.19(eslint@9.21.0(jiti@2.4.2)) + globals: + specifier: ^15.14.0 + version: 15.15.0 + tailwindcss: + specifier: ^4.0.8 + version: 4.0.8 + tsx: + specifier: ^4.19.3 + version: 4.19.3 + typescript: + specifier: ~5.7.2 + version: 5.7.3 + typescript-eslint: + specifier: ^8.22.0 + version: 8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) + vite: + specifier: ^6.1.0 + version: 6.1.1(@types/node@22.13.5)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.3) + +packages: + "@ampproject/remapping@2.3.0": + resolution: + { + integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, + } + engines: { node: ">=6.0.0" } + + "@babel/code-frame@7.26.2": + resolution: + { + integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/compat-data@7.26.8": + resolution: + { + integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/core@7.26.9": + resolution: + { + integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==, + } + engines: { node: ">=6.9.0" } + + "@babel/generator@7.26.9": + resolution: + { + integrity: sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-compilation-targets@7.26.5": + resolution: + { + integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-module-imports@7.25.9": + resolution: + { + integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-module-transforms@7.26.0": + resolution: + { + integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0 + + "@babel/helper-plugin-utils@7.26.5": + resolution: + { + integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-string-parser@7.25.9": + resolution: + { + integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-identifier@7.25.9": + resolution: + { + integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-option@7.25.9": + resolution: + { + integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helpers@7.26.9": + resolution: + { + integrity: sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==, + } + engines: { node: ">=6.9.0" } + + "@babel/parser@7.26.9": + resolution: + { + integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==, + } + engines: { node: ">=6.0.0" } + hasBin: true + + "@babel/plugin-transform-react-jsx-self@7.25.9": + resolution: + { + integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-transform-react-jsx-source@7.25.9": + resolution: + { + integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/template@7.26.9": + resolution: + { + integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==, + } + engines: { node: ">=6.9.0" } + + "@babel/traverse@7.26.9": + resolution: + { + integrity: sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==, + } + engines: { node: ">=6.9.0" } + + "@babel/types@7.26.9": + resolution: + { + integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==, + } + engines: { node: ">=6.9.0" } + + "@drizzle-team/brocli@0.10.2": + resolution: + { + integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==, + } + + "@esbuild-kit/core-utils@3.3.2": + resolution: + { + integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==, + } + deprecated: "Merged into tsx: https://tsx.is" + + "@esbuild-kit/esm-loader@2.6.5": + resolution: + { + integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==, + } + deprecated: "Merged into tsx: https://tsx.is" + + "@esbuild/aix-ppc64@0.19.12": + resolution: + { + integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==, + } + engines: { node: ">=12" } + cpu: [ppc64] + os: [aix] + + "@esbuild/aix-ppc64@0.24.2": + resolution: + { + integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [aix] + + "@esbuild/aix-ppc64@0.25.0": + resolution: + { + integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [aix] + + "@esbuild/android-arm64@0.18.20": + resolution: + { + integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [android] + + "@esbuild/android-arm64@0.19.12": + resolution: + { + integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [android] + + "@esbuild/android-arm64@0.24.2": + resolution: + { + integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [android] + + "@esbuild/android-arm64@0.25.0": + resolution: + { + integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [android] + + "@esbuild/android-arm@0.18.20": + resolution: + { + integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==, + } + engines: { node: ">=12" } + cpu: [arm] + os: [android] + + "@esbuild/android-arm@0.19.12": + resolution: + { + integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==, + } + engines: { node: ">=12" } + cpu: [arm] + os: [android] + + "@esbuild/android-arm@0.24.2": + resolution: + { + integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [android] + + "@esbuild/android-arm@0.25.0": + resolution: + { + integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [android] + + "@esbuild/android-x64@0.18.20": + resolution: + { + integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [android] + + "@esbuild/android-x64@0.19.12": + resolution: + { + integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [android] + + "@esbuild/android-x64@0.24.2": + resolution: + { + integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [android] + + "@esbuild/android-x64@0.25.0": + resolution: + { + integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [android] + + "@esbuild/darwin-arm64@0.18.20": + resolution: + { + integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [darwin] + + "@esbuild/darwin-arm64@0.19.12": + resolution: + { + integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [darwin] + + "@esbuild/darwin-arm64@0.24.2": + resolution: + { + integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [darwin] + + "@esbuild/darwin-arm64@0.25.0": + resolution: + { + integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [darwin] + + "@esbuild/darwin-x64@0.18.20": + resolution: + { + integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [darwin] + + "@esbuild/darwin-x64@0.19.12": + resolution: + { + integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [darwin] + + "@esbuild/darwin-x64@0.24.2": + resolution: + { + integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [darwin] + + "@esbuild/darwin-x64@0.25.0": + resolution: + { + integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [darwin] + + "@esbuild/freebsd-arm64@0.18.20": + resolution: + { + integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [freebsd] + + "@esbuild/freebsd-arm64@0.19.12": + resolution: + { + integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [freebsd] + + "@esbuild/freebsd-arm64@0.24.2": + resolution: + { + integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [freebsd] + + "@esbuild/freebsd-arm64@0.25.0": + resolution: + { + integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [freebsd] + + "@esbuild/freebsd-x64@0.18.20": + resolution: + { + integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [freebsd] + + "@esbuild/freebsd-x64@0.19.12": + resolution: + { + integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [freebsd] + + "@esbuild/freebsd-x64@0.24.2": + resolution: + { + integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [freebsd] + + "@esbuild/freebsd-x64@0.25.0": + resolution: + { + integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [freebsd] + + "@esbuild/linux-arm64@0.18.20": + resolution: + { + integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [linux] + + "@esbuild/linux-arm64@0.19.12": + resolution: + { + integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [linux] + + "@esbuild/linux-arm64@0.24.2": + resolution: + { + integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [linux] + + "@esbuild/linux-arm64@0.25.0": + resolution: + { + integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [linux] + + "@esbuild/linux-arm@0.18.20": + resolution: + { + integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==, + } + engines: { node: ">=12" } + cpu: [arm] + os: [linux] + + "@esbuild/linux-arm@0.19.12": + resolution: + { + integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==, + } + engines: { node: ">=12" } + cpu: [arm] + os: [linux] + + "@esbuild/linux-arm@0.24.2": + resolution: + { + integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [linux] + + "@esbuild/linux-arm@0.25.0": + resolution: + { + integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [linux] + + "@esbuild/linux-ia32@0.18.20": + resolution: + { + integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==, + } + engines: { node: ">=12" } + cpu: [ia32] + os: [linux] + + "@esbuild/linux-ia32@0.19.12": + resolution: + { + integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==, + } + engines: { node: ">=12" } + cpu: [ia32] + os: [linux] + + "@esbuild/linux-ia32@0.24.2": + resolution: + { + integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [linux] + + "@esbuild/linux-ia32@0.25.0": + resolution: + { + integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [linux] + + "@esbuild/linux-loong64@0.18.20": + resolution: + { + integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==, + } + engines: { node: ">=12" } + cpu: [loong64] + os: [linux] + + "@esbuild/linux-loong64@0.19.12": + resolution: + { + integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==, + } + engines: { node: ">=12" } + cpu: [loong64] + os: [linux] + + "@esbuild/linux-loong64@0.24.2": + resolution: + { + integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==, + } + engines: { node: ">=18" } + cpu: [loong64] + os: [linux] + + "@esbuild/linux-loong64@0.25.0": + resolution: + { + integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==, + } + engines: { node: ">=18" } + cpu: [loong64] + os: [linux] + + "@esbuild/linux-mips64el@0.18.20": + resolution: + { + integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==, + } + engines: { node: ">=12" } + cpu: [mips64el] + os: [linux] + + "@esbuild/linux-mips64el@0.19.12": + resolution: + { + integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==, + } + engines: { node: ">=12" } + cpu: [mips64el] + os: [linux] + + "@esbuild/linux-mips64el@0.24.2": + resolution: + { + integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==, + } + engines: { node: ">=18" } + cpu: [mips64el] + os: [linux] + + "@esbuild/linux-mips64el@0.25.0": + resolution: + { + integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==, + } + engines: { node: ">=18" } + cpu: [mips64el] + os: [linux] + + "@esbuild/linux-ppc64@0.18.20": + resolution: + { + integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==, + } + engines: { node: ">=12" } + cpu: [ppc64] + os: [linux] + + "@esbuild/linux-ppc64@0.19.12": + resolution: + { + integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==, + } + engines: { node: ">=12" } + cpu: [ppc64] + os: [linux] + + "@esbuild/linux-ppc64@0.24.2": + resolution: + { + integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [linux] + + "@esbuild/linux-ppc64@0.25.0": + resolution: + { + integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [linux] + + "@esbuild/linux-riscv64@0.18.20": + resolution: + { + integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==, + } + engines: { node: ">=12" } + cpu: [riscv64] + os: [linux] + + "@esbuild/linux-riscv64@0.19.12": + resolution: + { + integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==, + } + engines: { node: ">=12" } + cpu: [riscv64] + os: [linux] + + "@esbuild/linux-riscv64@0.24.2": + resolution: + { + integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==, + } + engines: { node: ">=18" } + cpu: [riscv64] + os: [linux] + + "@esbuild/linux-riscv64@0.25.0": + resolution: + { + integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==, + } + engines: { node: ">=18" } + cpu: [riscv64] + os: [linux] + + "@esbuild/linux-s390x@0.18.20": + resolution: + { + integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==, + } + engines: { node: ">=12" } + cpu: [s390x] + os: [linux] + + "@esbuild/linux-s390x@0.19.12": + resolution: + { + integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==, + } + engines: { node: ">=12" } + cpu: [s390x] + os: [linux] + + "@esbuild/linux-s390x@0.24.2": + resolution: + { + integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==, + } + engines: { node: ">=18" } + cpu: [s390x] + os: [linux] + + "@esbuild/linux-s390x@0.25.0": + resolution: + { + integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==, + } + engines: { node: ">=18" } + cpu: [s390x] + os: [linux] + + "@esbuild/linux-x64@0.18.20": + resolution: + { + integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [linux] + + "@esbuild/linux-x64@0.19.12": + resolution: + { + integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [linux] + + "@esbuild/linux-x64@0.24.2": + resolution: + { + integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [linux] + + "@esbuild/linux-x64@0.25.0": + resolution: + { + integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [linux] + + "@esbuild/netbsd-arm64@0.24.2": + resolution: + { + integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [netbsd] + + "@esbuild/netbsd-arm64@0.25.0": + resolution: + { + integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [netbsd] + + "@esbuild/netbsd-x64@0.18.20": + resolution: + { + integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [netbsd] + + "@esbuild/netbsd-x64@0.19.12": + resolution: + { + integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [netbsd] + + "@esbuild/netbsd-x64@0.24.2": + resolution: + { + integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [netbsd] + + "@esbuild/netbsd-x64@0.25.0": + resolution: + { + integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [netbsd] + + "@esbuild/openbsd-arm64@0.24.2": + resolution: + { + integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openbsd] + + "@esbuild/openbsd-arm64@0.25.0": + resolution: + { + integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openbsd] + + "@esbuild/openbsd-x64@0.18.20": + resolution: + { + integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [openbsd] + + "@esbuild/openbsd-x64@0.19.12": + resolution: + { + integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [openbsd] + + "@esbuild/openbsd-x64@0.24.2": + resolution: + { + integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [openbsd] + + "@esbuild/openbsd-x64@0.25.0": + resolution: + { + integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [openbsd] + + "@esbuild/sunos-x64@0.18.20": + resolution: + { + integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [sunos] + + "@esbuild/sunos-x64@0.19.12": + resolution: + { + integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [sunos] + + "@esbuild/sunos-x64@0.24.2": + resolution: + { + integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [sunos] + + "@esbuild/sunos-x64@0.25.0": + resolution: + { + integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [sunos] + + "@esbuild/win32-arm64@0.18.20": + resolution: + { + integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [win32] + + "@esbuild/win32-arm64@0.19.12": + resolution: + { + integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [win32] + + "@esbuild/win32-arm64@0.24.2": + resolution: + { + integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [win32] + + "@esbuild/win32-arm64@0.25.0": + resolution: + { + integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [win32] + + "@esbuild/win32-ia32@0.18.20": + resolution: + { + integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==, + } + engines: { node: ">=12" } + cpu: [ia32] + os: [win32] + + "@esbuild/win32-ia32@0.19.12": + resolution: + { + integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==, + } + engines: { node: ">=12" } + cpu: [ia32] + os: [win32] + + "@esbuild/win32-ia32@0.24.2": + resolution: + { + integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [win32] + + "@esbuild/win32-ia32@0.25.0": + resolution: + { + integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [win32] + + "@esbuild/win32-x64@0.18.20": + resolution: + { + integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [win32] + + "@esbuild/win32-x64@0.19.12": + resolution: + { + integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [win32] + + "@esbuild/win32-x64@0.24.2": + resolution: + { + integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [win32] + + "@esbuild/win32-x64@0.25.0": + resolution: + { + integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [win32] + + "@eslint-community/eslint-utils@4.4.1": + resolution: + { + integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==, + } + 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.19.2": + resolution: + { + integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/core@0.12.0": + resolution: + { + integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/eslintrc@3.3.0": + resolution: + { + integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/js@9.21.0": + resolution: + { + integrity: sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==, + } + 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.2.7": + resolution: + { + integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==, + } + 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.6": + resolution: + { + integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==, + } + engines: { node: ">=18.18.0" } + + "@humanwhocodes/module-importer@1.0.1": + resolution: + { + integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, + } + engines: { node: ">=12.22" } + + "@humanwhocodes/retry@0.3.1": + resolution: + { + integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==, + } + engines: { node: ">=18.18" } + + "@humanwhocodes/retry@0.4.2": + resolution: + { + integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==, + } + engines: { node: ">=18.18" } + + "@jridgewell/gen-mapping@0.3.8": + resolution: + { + integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/resolve-uri@3.1.2": + resolution: + { + integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/set-array@1.2.1": + resolution: + { + integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/sourcemap-codec@1.5.0": + resolution: + { + integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, + } + + "@jridgewell/trace-mapping@0.3.25": + resolution: + { + integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, + } + + "@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" } + + "@rollup/rollup-android-arm-eabi@4.34.8": + resolution: + { + integrity: sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==, + } + cpu: [arm] + os: [android] + + "@rollup/rollup-android-arm64@4.34.8": + resolution: + { + integrity: sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==, + } + cpu: [arm64] + os: [android] + + "@rollup/rollup-darwin-arm64@4.34.8": + resolution: + { + integrity: sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==, + } + cpu: [arm64] + os: [darwin] + + "@rollup/rollup-darwin-x64@4.34.8": + resolution: + { + integrity: sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==, + } + cpu: [x64] + os: [darwin] + + "@rollup/rollup-freebsd-arm64@4.34.8": + resolution: + { + integrity: sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==, + } + cpu: [arm64] + os: [freebsd] + + "@rollup/rollup-freebsd-x64@4.34.8": + resolution: + { + integrity: sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==, + } + cpu: [x64] + os: [freebsd] + + "@rollup/rollup-linux-arm-gnueabihf@4.34.8": + resolution: + { + integrity: sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==, + } + cpu: [arm] + os: [linux] + + "@rollup/rollup-linux-arm-musleabihf@4.34.8": + resolution: + { + integrity: sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==, + } + cpu: [arm] + os: [linux] + + "@rollup/rollup-linux-arm64-gnu@4.34.8": + resolution: + { + integrity: sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==, + } + cpu: [arm64] + os: [linux] + + "@rollup/rollup-linux-arm64-musl@4.34.8": + resolution: + { + integrity: sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==, + } + cpu: [arm64] + os: [linux] + + "@rollup/rollup-linux-loongarch64-gnu@4.34.8": + resolution: + { + integrity: sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==, + } + cpu: [loong64] + os: [linux] + + "@rollup/rollup-linux-powerpc64le-gnu@4.34.8": + resolution: + { + integrity: sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==, + } + cpu: [ppc64] + os: [linux] + + "@rollup/rollup-linux-riscv64-gnu@4.34.8": + resolution: + { + integrity: sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==, + } + cpu: [riscv64] + os: [linux] + + "@rollup/rollup-linux-s390x-gnu@4.34.8": + resolution: + { + integrity: sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==, + } + cpu: [s390x] + os: [linux] + + "@rollup/rollup-linux-x64-gnu@4.34.8": + resolution: + { + integrity: sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==, + } + cpu: [x64] + os: [linux] + + "@rollup/rollup-linux-x64-musl@4.34.8": + resolution: + { + integrity: sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==, + } + cpu: [x64] + os: [linux] + + "@rollup/rollup-win32-arm64-msvc@4.34.8": + resolution: + { + integrity: sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==, + } + cpu: [arm64] + os: [win32] + + "@rollup/rollup-win32-ia32-msvc@4.34.8": + resolution: + { + integrity: sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==, + } + cpu: [ia32] + os: [win32] + + "@rollup/rollup-win32-x64-msvc@4.34.8": + resolution: + { + integrity: sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==, + } + cpu: [x64] + os: [win32] + + "@tailwindcss/node@4.0.8": + resolution: + { + integrity: sha512-FKArQpbrbwv08TNT0k7ejYXpF+R8knZFAatNc0acOxbgeqLzwb86r+P3LGOjIeI3Idqe9CVkZrh4GlsJLJKkkw==, + } + + "@tailwindcss/oxide-android-arm64@4.0.8": + resolution: + { + integrity: sha512-We7K79+Sm4mwJHk26Yzu/GAj7C7myemm7PeXvpgMxyxO70SSFSL3uCcqFbz9JA5M5UPkrl7N9fkBe/Y0iazqpA==, + } + engines: { node: ">= 10" } + cpu: [arm64] + os: [android] + + "@tailwindcss/oxide-darwin-arm64@4.0.8": + resolution: + { + integrity: sha512-Lv9Isi2EwkCTG1sRHNDi0uRNN1UGFdEThUAGFrydRmQZnraGLMjN8gahzg2FFnOizDl7LB2TykLUuiw833DSNg==, + } + engines: { node: ">= 10" } + cpu: [arm64] + os: [darwin] + + "@tailwindcss/oxide-darwin-x64@4.0.8": + resolution: + { + integrity: sha512-fWfywfYIlSWtKoqWTjukTHLWV3ARaBRjXCC2Eo0l6KVpaqGY4c2y8snUjp1xpxUtpqwMvCvFWFaleMoz1Vhzlw==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [darwin] + + "@tailwindcss/oxide-freebsd-x64@4.0.8": + resolution: + { + integrity: sha512-SO+dyvjJV9G94bnmq2288Ke0BIdvrbSbvtPLaQdqjqHR83v5L2fWADyFO+1oecHo9Owsk8MxcXh1agGVPIKIqw==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [freebsd] + + "@tailwindcss/oxide-linux-arm-gnueabihf@4.0.8": + resolution: + { + integrity: sha512-ZSHggWiEblQNV69V0qUK5vuAtHP+I+S2eGrKGJ5lPgwgJeAd6GjLsVBN+Mqn2SPVfYM3BOpS9jX/zVg9RWQVDQ==, + } + engines: { node: ">= 10" } + cpu: [arm] + os: [linux] + + "@tailwindcss/oxide-linux-arm64-gnu@4.0.8": + resolution: + { + integrity: sha512-xWpr6M0OZLDNsr7+bQz+3X7zcnDJZJ1N9gtBWCtfhkEtDjjxYEp+Lr5L5nc/yXlL4MyCHnn0uonGVXy3fhxaVA==, + } + engines: { node: ">= 10" } + cpu: [arm64] + os: [linux] + + "@tailwindcss/oxide-linux-arm64-musl@4.0.8": + resolution: + { + integrity: sha512-5tz2IL7LN58ssGEq7h/staD7pu/izF/KeMWdlJ86WDe2Ah46LF3ET6ZGKTr5eZMrnEA0M9cVFuSPprKRHNgjeg==, + } + engines: { node: ">= 10" } + cpu: [arm64] + os: [linux] + + "@tailwindcss/oxide-linux-x64-gnu@4.0.8": + resolution: + { + integrity: sha512-KSzMkhyrxAQyY2o194NKVKU9j/c+NFSoMvnHWFaNHKi3P1lb+Vq1UC19tLHrmxSkKapcMMu69D7+G1+FVGNDXQ==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [linux] + + "@tailwindcss/oxide-linux-x64-musl@4.0.8": + resolution: + { + integrity: sha512-yFYKG5UtHTRimjtqxUWXBgI4Tc6NJe3USjRIVdlTczpLRxq/SFwgzGl5JbatCxgSRDPBFwRrNPxq+ukfQFGdrw==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [linux] + + "@tailwindcss/oxide-win32-arm64-msvc@4.0.8": + resolution: + { + integrity: sha512-tndGujmCSba85cRCnQzXgpA2jx5gXimyspsUYae5jlPyLRG0RjXbDshFKOheVXU4TLflo7FSG8EHCBJ0EHTKdQ==, + } + engines: { node: ">= 10" } + cpu: [arm64] + os: [win32] + + "@tailwindcss/oxide-win32-x64-msvc@4.0.8": + resolution: + { + integrity: sha512-T77jroAc0p4EHVVgTUiNeFn6Nj3jtD3IeNId2X+0k+N1XxfNipy81BEkYErpKLiOkNhpNFjPee8/ZVas29b2OQ==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [win32] + + "@tailwindcss/oxide@4.0.8": + resolution: + { + integrity: sha512-KfMcuAu/Iw+DcV1e8twrFyr2yN8/ZDC/odIGta4wuuJOGkrkHZbvJvRNIbQNhGh7erZTYV6Ie0IeD6WC9Y8Hcw==, + } + engines: { node: ">= 10" } + + "@tailwindcss/vite@4.0.8": + resolution: + { + integrity: sha512-+SAq44yLzYlzyrb7QTcFCdU8Xa7FOA0jp+Xby7fPMUie+MY9HhJysM7Vp+vL8qIp8ceQJfLD+FjgJuJ4lL6nyg==, + } + peerDependencies: + vite: ^5.2.0 || ^6 + + "@types/babel__core@7.20.5": + resolution: + { + integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, + } + + "@types/babel__generator@7.6.8": + resolution: + { + integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==, + } + + "@types/babel__template@7.4.4": + resolution: + { + integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, + } + + "@types/babel__traverse@7.20.6": + resolution: + { + integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==, + } + + "@types/body-parser@1.19.5": + resolution: + { + integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==, + } + + "@types/connect@3.4.38": + resolution: + { + integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==, + } + + "@types/cors@2.8.17": + resolution: + { + integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==, + } + + "@types/estree@1.0.6": + resolution: + { + integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==, + } + + "@types/express-serve-static-core@4.19.6": + resolution: + { + integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==, + } + + "@types/express@4.17.21": + resolution: + { + integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==, + } + + "@types/http-errors@2.0.4": + resolution: + { + integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==, + } + + "@types/json-schema@7.0.15": + resolution: + { + integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==, + } + + "@types/mime@1.3.5": + resolution: + { + integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==, + } + + "@types/node@22.13.5": + resolution: + { + integrity: sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==, + } + + "@types/pg@8.11.11": + resolution: + { + integrity: sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==, + } + + "@types/qs@6.9.18": + resolution: + { + integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==, + } + + "@types/range-parser@1.2.7": + resolution: + { + integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==, + } + + "@types/react-dom@19.0.4": + resolution: + { + integrity: sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==, + } + peerDependencies: + "@types/react": ^19.0.0 + + "@types/react@19.0.10": + resolution: + { + integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==, + } + + "@types/send@0.17.4": + resolution: + { + integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==, + } + + "@types/serve-static@1.15.7": + resolution: + { + integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==, + } + + "@types/use-sync-external-store@0.0.6": + resolution: + { + integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==, + } + + "@typescript-eslint/eslint-plugin@8.25.0": + resolution: + { + integrity: sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + + "@typescript-eslint/parser@8.25.0": + resolution: + { + integrity: sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + + "@typescript-eslint/scope-manager@8.25.0": + resolution: + { + integrity: sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@typescript-eslint/type-utils@8.25.0": + resolution: + { + integrity: sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + + "@typescript-eslint/types@8.25.0": + resolution: + { + integrity: sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@typescript-eslint/typescript-estree@8.25.0": + resolution: + { + integrity: sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + typescript: ">=4.8.4 <5.8.0" + + "@typescript-eslint/utils@8.25.0": + resolution: + { + integrity: sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + + "@typescript-eslint/visitor-keys@8.25.0": + resolution: + { + integrity: sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@vitejs/plugin-react@4.3.4": + resolution: + { + integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==, + } + engines: { node: ^14.18.0 || >=16.0.0 } + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + + accepts@1.3.8: + resolution: + { + integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==, + } + engines: { node: ">= 0.6" } + + acorn-jsx@5.3.2: + resolution: + { + integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, + } + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.14.0: + resolution: + { + integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==, + } + engines: { node: ">=0.4.0" } + hasBin: true + + ajv@6.12.6: + resolution: + { + integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==, + } + + ansi-regex@5.0.1: + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: ">=8" } + + 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==, + } + + array-flatten@1.1.1: + resolution: + { + integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==, + } + + balanced-match@1.0.2: + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } + + body-parser@1.20.3: + resolution: + { + integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==, + } + engines: { node: ">= 0.8", npm: 1.2.8000 || >= 1.4.16 } + + brace-expansion@1.1.11: + resolution: + { + integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, + } + + brace-expansion@2.0.1: + resolution: + { + integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, + } + + braces@3.0.3: + resolution: + { + integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, + } + engines: { node: ">=8" } + + browserslist@4.24.4: + resolution: + { + integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==, + } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } + hasBin: true + + buffer-from@1.1.2: + resolution: + { + integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, + } + + bytes@3.1.2: + resolution: + { + integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==, + } + engines: { node: ">= 0.8" } + + call-bind-apply-helpers@1.0.2: + resolution: + { + integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==, + } + engines: { node: ">= 0.4" } + + call-bound@1.0.3: + resolution: + { + integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==, + } + engines: { node: ">= 0.4" } + + callsites@3.1.0: + resolution: + { + integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, + } + engines: { node: ">=6" } + + caniuse-lite@1.0.30001700: + resolution: + { + integrity: sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==, + } + + chalk@4.1.2: + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: ">=10" } + + cliui@8.0.1: + resolution: + { + integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, + } + engines: { node: ">=12" } + + 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==, + } + + concat-map@0.0.1: + resolution: + { + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, + } + + concurrently@9.1.2: + resolution: + { + integrity: sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==, + } + engines: { node: ">=18" } + hasBin: true + + content-disposition@0.5.4: + resolution: + { + integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==, + } + engines: { node: ">= 0.6" } + + content-type@1.0.5: + resolution: + { + integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==, + } + engines: { node: ">= 0.6" } + + convert-source-map@2.0.0: + resolution: + { + integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, + } + + cookie-signature@1.0.6: + resolution: + { + integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==, + } + + cookie@0.7.1: + resolution: + { + integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==, + } + engines: { node: ">= 0.6" } + + cors@2.8.5: + resolution: + { + integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==, + } + engines: { node: ">= 0.10" } + + cross-spawn@7.0.6: + resolution: + { + integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, + } + engines: { node: ">= 8" } + + csstype@3.1.3: + resolution: + { + integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==, + } + + debug@2.6.9: + resolution: + { + integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==, + } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.0: + resolution: + { + integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==, + } + engines: { node: ">=6.0" } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: + { + integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, + } + + depd@2.0.0: + resolution: + { + integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==, + } + engines: { node: ">= 0.8" } + + destroy@1.2.0: + resolution: + { + integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==, + } + engines: { node: ">= 0.8", npm: 1.2.8000 || >= 1.4.16 } + + detect-libc@1.0.3: + resolution: + { + integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==, + } + engines: { node: ">=0.10" } + hasBin: true + + dotenv@16.4.7: + resolution: + { + integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==, + } + engines: { node: ">=12" } + + drizzle-kit@0.30.4: + resolution: + { + integrity: sha512-B2oJN5UkvwwNHscPWXDG5KqAixu7AUzZ3qbe++KU9SsQ+cZWR4DXEPYcvWplyFAno0dhRJECNEhNxiDmFaPGyQ==, + } + hasBin: true + + drizzle-orm@0.39.3: + resolution: + { + integrity: sha512-EZ8ZpYvDIvKU9C56JYLOmUskazhad+uXZCTCRN4OnRMsL+xAJ05dv1eCpAG5xzhsm1hqiuC5kAZUCS924u2DTw==, + } + peerDependencies: + "@aws-sdk/client-rds-data": ">=3" + "@cloudflare/workers-types": ">=4" + "@electric-sql/pglite": ">=0.2.0" + "@libsql/client": ">=0.10.0" + "@libsql/client-wasm": ">=0.10.0" + "@neondatabase/serverless": ">=0.10.0" + "@op-engineering/op-sqlite": ">=2" + "@opentelemetry/api": ^1.4.1 + "@planetscale/database": ">=1" + "@prisma/client": "*" + "@tidbcloud/serverless": "*" + "@types/better-sqlite3": "*" + "@types/pg": "*" + "@types/sql.js": "*" + "@vercel/postgres": ">=0.8.0" + "@xata.io/client": "*" + better-sqlite3: ">=7" + bun-types: "*" + expo-sqlite: ">=14.0.0" + knex: "*" + kysely: "*" + mysql2: ">=2" + pg: ">=8" + postgres: ">=3" + prisma: "*" + sql.js: ">=1" + sqlite3: ">=5" + peerDependenciesMeta: + "@aws-sdk/client-rds-data": + optional: true + "@cloudflare/workers-types": + optional: true + "@electric-sql/pglite": + optional: true + "@libsql/client": + optional: true + "@libsql/client-wasm": + optional: true + "@neondatabase/serverless": + optional: true + "@op-engineering/op-sqlite": + optional: true + "@opentelemetry/api": + optional: true + "@planetscale/database": + optional: true + "@prisma/client": + optional: true + "@tidbcloud/serverless": + optional: true + "@types/better-sqlite3": + optional: true + "@types/pg": + optional: true + "@types/sql.js": + optional: true + "@vercel/postgres": + optional: true + "@xata.io/client": + optional: true + better-sqlite3: + optional: true + bun-types: + optional: true + expo-sqlite: + optional: true + knex: + optional: true + kysely: + optional: true + mysql2: + optional: true + pg: + optional: true + postgres: + optional: true + prisma: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + + drizzle-zod@0.7.0: + resolution: + { + integrity: sha512-xgCRYYVEzRkeXTS33GSMgoowe3vKsMNBjSI+cwG1oLQVEhAWWbqtb/AAMlm7tkmV4fG/uJjEmWzdzlEmTgWOoQ==, + } + peerDependencies: + drizzle-orm: ">=0.36.0" + zod: ">=3.0.0" + + dunder-proto@1.0.1: + resolution: + { + integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==, + } + engines: { node: ">= 0.4" } + + ee-first@1.1.1: + resolution: + { + integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, + } + + electron-to-chromium@1.5.104: + resolution: + { + integrity: sha512-Us9M2L4cO/zMBqVkJtnj353nQhMju9slHm62NprKTmdF3HH8wYOtNvDFq/JB2+ZRoGLzdvYDiATlMHs98XBM1g==, + } + + emoji-regex@8.0.0: + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } + + encodeurl@1.0.2: + resolution: + { + integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==, + } + engines: { node: ">= 0.8" } + + encodeurl@2.0.0: + resolution: + { + integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==, + } + engines: { node: ">= 0.8" } + + enhanced-resolve@5.18.1: + resolution: + { + integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==, + } + engines: { node: ">=10.13.0" } + + es-define-property@1.0.1: + resolution: + { + integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==, + } + engines: { node: ">= 0.4" } + + es-errors@1.3.0: + resolution: + { + integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, + } + engines: { node: ">= 0.4" } + + es-object-atoms@1.1.1: + resolution: + { + integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==, + } + engines: { node: ">= 0.4" } + + esbuild-register@3.6.0: + resolution: + { + integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==, + } + peerDependencies: + esbuild: ">=0.12 <1" + + esbuild@0.18.20: + resolution: + { + integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==, + } + engines: { node: ">=12" } + hasBin: true + + esbuild@0.19.12: + resolution: + { + integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==, + } + engines: { node: ">=12" } + hasBin: true + + esbuild@0.24.2: + resolution: + { + integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==, + } + engines: { node: ">=18" } + hasBin: true + + esbuild@0.25.0: + resolution: + { + integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==, + } + engines: { node: ">=18" } + hasBin: true + + escalade@3.2.0: + resolution: + { + integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, + } + engines: { node: ">=6" } + + escape-html@1.0.3: + resolution: + { + integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, + } + + escape-string-regexp@4.0.0: + resolution: + { + integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, + } + engines: { node: ">=10" } + + eslint-plugin-react-hooks@5.1.0: + resolution: + { + integrity: sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==, + } + engines: { node: ">=10" } + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.4.19: + resolution: + { + integrity: sha512-eyy8pcr/YxSYjBoqIFSrlbn9i/xvxUFa8CjzAYo9cFjgGXqq1hyjihcpZvxRLalpaWmueWR81xn7vuKmAFijDQ==, + } + peerDependencies: + eslint: ">=8.40" + + eslint-scope@8.2.0: + resolution: + { + integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==, + } + 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.0: + resolution: + { + integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + eslint@9.21.0: + resolution: + { + integrity: sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + hasBin: true + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: + { + integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==, + } + 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" } + + esutils@2.0.3: + resolution: + { + integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, + } + engines: { node: ">=0.10.0" } + + etag@1.8.1: + resolution: + { + integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==, + } + engines: { node: ">= 0.6" } + + express@4.21.2: + resolution: + { + integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==, + } + engines: { node: ">= 0.10.0" } + + fast-deep-equal@3.1.3: + resolution: + { + integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, + } + + 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.0: + resolution: + { + integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==, + } + + 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" } + + finalhandler@1.3.1: + resolution: + { + integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==, + } + engines: { node: ">= 0.8" } + + 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==, + } + + forwarded@0.2.0: + resolution: + { + integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==, + } + engines: { node: ">= 0.6" } + + fresh@0.5.2: + resolution: + { + integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==, + } + engines: { node: ">= 0.6" } + + fsevents@2.3.3: + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] + + function-bind@1.1.2: + resolution: + { + integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, + } + + gensync@1.0.0-beta.2: + resolution: + { + integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, + } + engines: { node: ">=6.9.0" } + + get-caller-file@2.0.5: + resolution: + { + integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, + } + engines: { node: 6.* || 8.* || >= 10.* } + + get-intrinsic@1.3.0: + resolution: + { + integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==, + } + engines: { node: ">= 0.4" } + + get-proto@1.0.1: + resolution: + { + integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==, + } + engines: { node: ">= 0.4" } + + get-tsconfig@4.10.0: + resolution: + { + integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==, + } + + 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" } + + globals@11.12.0: + resolution: + { + integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, + } + engines: { node: ">=4" } + + globals@14.0.0: + resolution: + { + integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==, + } + engines: { node: ">=18" } + + globals@15.15.0: + resolution: + { + integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==, + } + engines: { node: ">=18" } + + gopd@1.2.0: + resolution: + { + integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==, + } + engines: { node: ">= 0.4" } + + graceful-fs@4.2.11: + resolution: + { + integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, + } + + graphemer@1.4.0: + resolution: + { + integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, + } + + has-flag@4.0.0: + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: ">=8" } + + has-symbols@1.1.0: + resolution: + { + integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==, + } + engines: { node: ">= 0.4" } + + hasown@2.0.2: + resolution: + { + integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, + } + engines: { node: ">= 0.4" } + + http-errors@2.0.0: + resolution: + { + integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==, + } + engines: { node: ">= 0.8" } + + iconv-lite@0.4.24: + resolution: + { + integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==, + } + engines: { node: ">=0.10.0" } + + ignore@5.3.2: + resolution: + { + integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, + } + 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" } + + inherits@2.0.4: + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } + + ipaddr.js@1.9.1: + resolution: + { + integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==, + } + engines: { node: ">= 0.10" } + + is-extglob@2.1.1: + resolution: + { + integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, + } + engines: { node: ">=0.10.0" } + + is-fullwidth-code-point@3.0.0: + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: ">=8" } + + 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==, + } + + jiti@2.4.2: + resolution: + { + integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==, + } + hasBin: true + + js-tokens@4.0.0: + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } + + js-yaml@4.1.0: + resolution: + { + integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, + } + 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==, + } + + json5@2.2.3: + resolution: + { + integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, + } + engines: { node: ">=6" } + hasBin: true + + keyv@4.5.4: + resolution: + { + integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, + } + + kysely@0.27.5: + resolution: + { + integrity: sha512-s7hZHcQeSNKpzCkHRm8yA+0JPLjncSWnjb+2TIElwS2JAqYr+Kv3Ess+9KFfJS0C1xcQ1i9NkNHpWwCYpHMWsA==, + } + engines: { node: ">=14.0.0" } + + levn@0.4.1: + resolution: + { + integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, + } + engines: { node: ">= 0.8.0" } + + lightningcss-darwin-arm64@1.29.1: + resolution: + { + integrity: sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==, + } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.29.1: + resolution: + { + integrity: sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==, + } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.29.1: + resolution: + { + integrity: sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==, + } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.29.1: + resolution: + { + integrity: sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==, + } + engines: { node: ">= 12.0.0" } + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.29.1: + resolution: + { + integrity: sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==, + } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.29.1: + resolution: + { + integrity: sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==, + } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.29.1: + resolution: + { + integrity: sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==, + } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.29.1: + resolution: + { + integrity: sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==, + } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.29.1: + resolution: + { + integrity: sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==, + } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.29.1: + resolution: + { + integrity: sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==, + } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [win32] + + lightningcss@1.29.1: + resolution: + { + integrity: sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==, + } + engines: { node: ">= 12.0.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==, + } + + lodash@4.17.21: + resolution: + { + integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==, + } + + lru-cache@5.1.1: + resolution: + { + integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, + } + + math-intrinsics@1.1.0: + resolution: + { + integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==, + } + engines: { node: ">= 0.4" } + + media-typer@0.3.0: + resolution: + { + integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==, + } + engines: { node: ">= 0.6" } + + merge-descriptors@1.0.3: + resolution: + { + integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==, + } + + merge2@1.4.1: + resolution: + { + integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, + } + engines: { node: ">= 8" } + + methods@1.1.2: + resolution: + { + integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==, + } + engines: { node: ">= 0.6" } + + micromatch@4.0.8: + resolution: + { + integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, + } + engines: { node: ">=8.6" } + + mime-db@1.52.0: + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: ">= 0.6" } + + mime-types@2.1.35: + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: ">= 0.6" } + + mime@1.6.0: + resolution: + { + integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, + } + engines: { node: ">=4" } + 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" } + + mitt@3.0.1: + resolution: + { + integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==, + } + + ms@2.0.0: + resolution: + { + integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==, + } + + ms@2.1.3: + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } + + nanoid@3.3.8: + resolution: + { + integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + + natural-compare@1.4.0: + resolution: + { + integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, + } + + negotiator@0.6.3: + resolution: + { + integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==, + } + engines: { node: ">= 0.6" } + + node-releases@2.0.19: + resolution: + { + integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==, + } + + object-assign@4.1.1: + resolution: + { + integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==, + } + engines: { node: ">=0.10.0" } + + object-inspect@1.13.4: + resolution: + { + integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==, + } + engines: { node: ">= 0.4" } + + obuf@1.1.2: + resolution: + { + integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==, + } + + on-finished@2.4.1: + resolution: + { + integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==, + } + engines: { node: ">= 0.8" } + + 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" } + + parseurl@1.3.3: + resolution: + { + integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==, + } + engines: { node: ">= 0.8" } + + 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@0.1.12: + resolution: + { + integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==, + } + + pg-cloudflare@1.1.1: + resolution: + { + integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==, + } + + pg-connection-string@2.7.0: + resolution: + { + integrity: sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==, + } + + pg-int8@1.0.1: + resolution: + { + integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==, + } + engines: { node: ">=4.0.0" } + + pg-numeric@1.0.2: + resolution: + { + integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==, + } + engines: { node: ">=4" } + + pg-pool@3.7.1: + resolution: + { + integrity: sha512-xIOsFoh7Vdhojas6q3596mXFsR8nwBQBXX5JiV7p9buEVAGqYL4yFzclON5P9vFrpu1u7Zwl2oriyDa89n0wbw==, + } + peerDependencies: + pg: ">=8.0" + + pg-protocol@1.7.1: + resolution: + { + integrity: sha512-gjTHWGYWsEgy9MsY0Gp6ZJxV24IjDqdpTW7Eh0x+WfJLFsm/TJx1MzL6T0D88mBvkpxotCQ6TwW6N+Kko7lhgQ==, + } + + pg-types@2.2.0: + resolution: + { + integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==, + } + engines: { node: ">=4" } + + pg-types@4.0.2: + resolution: + { + integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==, + } + engines: { node: ">=10" } + + pg@8.13.3: + resolution: + { + integrity: sha512-P6tPt9jXbL9HVu/SSRERNYaYG++MjnscnegFh9pPHihfoBSujsrka0hyuymMzeJKFWrcG8wvCKy8rCe8e5nDUQ==, + } + engines: { node: ">= 8.0.0" } + peerDependencies: + pg-native: ">=3.0.1" + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: + { + integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==, + } + + picocolors@1.1.1: + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } + + picomatch@2.3.1: + resolution: + { + integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, + } + engines: { node: ">=8.6" } + + postcss@8.5.3: + resolution: + { + integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==, + } + engines: { node: ^10 || ^12 || >=14 } + + postgres-array@2.0.0: + resolution: + { + integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==, + } + engines: { node: ">=4" } + + postgres-array@3.0.2: + resolution: + { + integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==, + } + engines: { node: ">=12" } + + postgres-bytea@1.0.0: + resolution: + { + integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==, + } + engines: { node: ">=0.10.0" } + + postgres-bytea@3.0.0: + resolution: + { + integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==, + } + engines: { node: ">= 6" } + + postgres-date@1.0.7: + resolution: + { + integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==, + } + engines: { node: ">=0.10.0" } + + postgres-date@2.1.0: + resolution: + { + integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==, + } + engines: { node: ">=12" } + + postgres-interval@1.2.0: + resolution: + { + integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==, + } + engines: { node: ">=0.10.0" } + + postgres-interval@3.0.0: + resolution: + { + integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==, + } + engines: { node: ">=12" } + + postgres-range@1.1.4: + resolution: + { + integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==, + } + + prelude-ls@1.2.1: + resolution: + { + integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, + } + engines: { node: ">= 0.8.0" } + + proxy-addr@2.0.7: + resolution: + { + integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==, + } + engines: { node: ">= 0.10" } + + punycode@2.3.1: + resolution: + { + integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, + } + engines: { node: ">=6" } + + qs@6.13.0: + resolution: + { + integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==, + } + engines: { node: ">=0.6" } + + queue-microtask@1.2.3: + resolution: + { + integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, + } + + range-parser@1.2.1: + resolution: + { + integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==, + } + engines: { node: ">= 0.6" } + + raw-body@2.5.2: + resolution: + { + integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==, + } + engines: { node: ">= 0.8" } + + react-dom@19.0.0: + resolution: + { + integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==, + } + peerDependencies: + react: ^19.0.0 + + react-refresh@0.14.2: + resolution: + { + integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==, + } + engines: { node: ">=0.10.0" } + + react@19.0.0: + resolution: + { + integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==, + } + engines: { node: ">=0.10.0" } + + require-directory@2.1.1: + resolution: + { + integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, + } + engines: { node: ">=0.10.0" } + + resolve-from@4.0.0: + resolution: + { + integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, + } + engines: { node: ">=4" } + + resolve-pkg-maps@1.0.0: + resolution: + { + integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==, + } + + reusify@1.0.4: + resolution: + { + integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==, + } + engines: { iojs: ">=1.0.0", node: ">=0.10.0" } + + rollup@4.34.8: + resolution: + { + integrity: sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==, + } + engines: { node: ">=18.0.0", npm: ">=8.0.0" } + hasBin: true + + run-parallel@1.2.0: + resolution: + { + integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, + } + + rxjs@7.8.2: + resolution: + { + integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==, + } + + safe-buffer@5.2.1: + resolution: + { + integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, + } + + safer-buffer@2.1.2: + resolution: + { + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, + } + + scheduler@0.25.0: + resolution: + { + integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==, + } + + semver@6.3.1: + resolution: + { + integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, + } + hasBin: true + + semver@7.7.1: + resolution: + { + integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==, + } + engines: { node: ">=10" } + hasBin: true + + send@0.19.0: + resolution: + { + integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==, + } + engines: { node: ">= 0.8.0" } + + serve-static@1.16.2: + resolution: + { + integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==, + } + engines: { node: ">= 0.8.0" } + + setprototypeof@1.2.0: + resolution: + { + integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==, + } + + 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" } + + shell-quote@1.8.2: + resolution: + { + integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==, + } + engines: { node: ">= 0.4" } + + side-channel-list@1.0.0: + resolution: + { + integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==, + } + engines: { node: ">= 0.4" } + + side-channel-map@1.0.1: + resolution: + { + integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==, + } + engines: { node: ">= 0.4" } + + side-channel-weakmap@1.0.2: + resolution: + { + integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==, + } + engines: { node: ">= 0.4" } + + side-channel@1.1.0: + resolution: + { + integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==, + } + engines: { node: ">= 0.4" } + + source-map-js@1.2.1: + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, + } + engines: { node: ">=0.10.0" } + + source-map-support@0.5.21: + resolution: + { + integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, + } + + source-map@0.6.1: + resolution: + { + integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, + } + engines: { node: ">=0.10.0" } + + split2@4.2.0: + resolution: + { + integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==, + } + engines: { node: ">= 10.x" } + + statuses@2.0.1: + resolution: + { + integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==, + } + engines: { node: ">= 0.8" } + + string-width@4.2.3: + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: ">=8" } + + strip-ansi@6.0.1: + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: ">=8" } + + strip-json-comments@3.1.1: + resolution: + { + integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, + } + engines: { node: ">=8" } + + supports-color@7.2.0: + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: ">=8" } + + supports-color@8.1.1: + resolution: + { + integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, + } + engines: { node: ">=10" } + + tailwindcss@4.0.8: + resolution: + { + integrity: sha512-Me7N5CKR+D2A1xdWA5t5+kjjT7bwnxZOE6/yDI/ixJdJokszsn2n++mdU5yJwrsTpqFX2B9ZNMBJDwcqk9C9lw==, + } + + tapable@2.2.1: + resolution: + { + integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==, + } + engines: { node: ">=6" } + + to-regex-range@5.0.1: + resolution: + { + integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, + } + engines: { node: ">=8.0" } + + toidentifier@1.0.1: + resolution: + { + integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==, + } + engines: { node: ">=0.6" } + + tree-kill@1.2.2: + resolution: + { + integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==, + } + hasBin: true + + ts-api-utils@2.0.1: + resolution: + { + integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==, + } + engines: { node: ">=18.12" } + peerDependencies: + typescript: ">=4.8.4" + + tslib@2.8.1: + resolution: + { + integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, + } + + tsx@4.19.3: + resolution: + { + integrity: sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==, + } + engines: { node: ">=18.0.0" } + hasBin: true + + type-check@0.4.0: + resolution: + { + integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, + } + engines: { node: ">= 0.8.0" } + + type-is@1.6.18: + resolution: + { + integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==, + } + engines: { node: ">= 0.6" } + + typescript-eslint@8.25.0: + resolution: + { + integrity: sha512-TxRdQQLH4g7JkoFlYG3caW5v1S6kEkz8rqt80iQJZUYPq1zD1Ra7HfQBJJ88ABRaMvHAXnwRvRB4V+6sQ9xN5Q==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + + typescript@5.7.3: + resolution: + { + integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==, + } + engines: { node: ">=14.17" } + hasBin: true + + undici-types@6.20.0: + resolution: + { + integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==, + } + + unpipe@1.0.0: + resolution: + { + integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, + } + engines: { node: ">= 0.8" } + + update-browserslist-db@1.1.2: + resolution: + { + integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==, + } + hasBin: true + peerDependencies: + browserslist: ">= 4.21.0" + + uri-js@4.4.1: + resolution: + { + integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, + } + + utils-merge@1.0.1: + resolution: + { + integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==, + } + engines: { node: ">= 0.4.0" } + + vary@1.1.2: + resolution: + { + integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, + } + engines: { node: ">= 0.8" } + + vite@6.1.1: + resolution: + { + integrity: sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==, + } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } + hasBin: true + peerDependencies: + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: ">=1.21.0" + less: "*" + lightningcss: ^1.21.0 + sass: "*" + sass-embedded: "*" + stylus: "*" + sugarss: "*" + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + 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 + + which@2.0.2: + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: ">= 8" } + hasBin: true + + word-wrap@1.2.5: + resolution: + { + integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==, + } + engines: { node: ">=0.10.0" } + + wrap-ansi@7.0.0: + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: ">=10" } + + xtend@4.0.2: + resolution: + { + integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==, + } + engines: { node: ">=0.4" } + + y18n@5.0.8: + resolution: + { + integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, + } + engines: { node: ">=10" } + + yallist@3.1.1: + resolution: + { + integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, + } + + yargs-parser@21.1.1: + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: ">=12" } + + yargs@17.7.2: + resolution: + { + integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, + } + engines: { node: ">=12" } + + yocto-queue@0.1.0: + resolution: + { + integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, + } + engines: { node: ">=10" } + + zod@3.24.2: + resolution: + { + integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==, + } + +snapshots: + "@ampproject/remapping@2.3.0": + dependencies: + "@jridgewell/gen-mapping": 0.3.8 + "@jridgewell/trace-mapping": 0.3.25 + + "@babel/code-frame@7.26.2": + dependencies: + "@babel/helper-validator-identifier": 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + "@babel/compat-data@7.26.8": {} + + "@babel/core@7.26.9": + dependencies: + "@ampproject/remapping": 2.3.0 + "@babel/code-frame": 7.26.2 + "@babel/generator": 7.26.9 + "@babel/helper-compilation-targets": 7.26.5 + "@babel/helper-module-transforms": 7.26.0(@babel/core@7.26.9) + "@babel/helpers": 7.26.9 + "@babel/parser": 7.26.9 + "@babel/template": 7.26.9 + "@babel/traverse": 7.26.9 + "@babel/types": 7.26.9 + convert-source-map: 2.0.0 + debug: 4.4.0 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + "@babel/generator@7.26.9": + dependencies: + "@babel/parser": 7.26.9 + "@babel/types": 7.26.9 + "@jridgewell/gen-mapping": 0.3.8 + "@jridgewell/trace-mapping": 0.3.25 + jsesc: 3.1.0 + + "@babel/helper-compilation-targets@7.26.5": + dependencies: + "@babel/compat-data": 7.26.8 + "@babel/helper-validator-option": 7.25.9 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + + "@babel/helper-module-imports@7.25.9": + dependencies: + "@babel/traverse": 7.26.9 + "@babel/types": 7.26.9 + transitivePeerDependencies: + - supports-color + + "@babel/helper-module-transforms@7.26.0(@babel/core@7.26.9)": + dependencies: + "@babel/core": 7.26.9 + "@babel/helper-module-imports": 7.25.9 + "@babel/helper-validator-identifier": 7.25.9 + "@babel/traverse": 7.26.9 + transitivePeerDependencies: + - supports-color + + "@babel/helper-plugin-utils@7.26.5": {} + + "@babel/helper-string-parser@7.25.9": {} + + "@babel/helper-validator-identifier@7.25.9": {} + + "@babel/helper-validator-option@7.25.9": {} + + "@babel/helpers@7.26.9": + dependencies: + "@babel/template": 7.26.9 + "@babel/types": 7.26.9 + + "@babel/parser@7.26.9": + dependencies: + "@babel/types": 7.26.9 + + "@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.9)": + dependencies: + "@babel/core": 7.26.9 + "@babel/helper-plugin-utils": 7.26.5 + + "@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.9)": + dependencies: + "@babel/core": 7.26.9 + "@babel/helper-plugin-utils": 7.26.5 + + "@babel/template@7.26.9": + dependencies: + "@babel/code-frame": 7.26.2 + "@babel/parser": 7.26.9 + "@babel/types": 7.26.9 + + "@babel/traverse@7.26.9": + dependencies: + "@babel/code-frame": 7.26.2 + "@babel/generator": 7.26.9 + "@babel/parser": 7.26.9 + "@babel/template": 7.26.9 + "@babel/types": 7.26.9 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + "@babel/types@7.26.9": + dependencies: + "@babel/helper-string-parser": 7.25.9 + "@babel/helper-validator-identifier": 7.25.9 + + "@drizzle-team/brocli@0.10.2": {} + + "@esbuild-kit/core-utils@3.3.2": + dependencies: + esbuild: 0.18.20 + source-map-support: 0.5.21 + + "@esbuild-kit/esm-loader@2.6.5": + dependencies: + "@esbuild-kit/core-utils": 3.3.2 + get-tsconfig: 4.10.0 + + "@esbuild/aix-ppc64@0.19.12": + optional: true + + "@esbuild/aix-ppc64@0.24.2": + optional: true + + "@esbuild/aix-ppc64@0.25.0": + optional: true + + "@esbuild/android-arm64@0.18.20": + optional: true + + "@esbuild/android-arm64@0.19.12": + optional: true + + "@esbuild/android-arm64@0.24.2": + optional: true + + "@esbuild/android-arm64@0.25.0": + optional: true + + "@esbuild/android-arm@0.18.20": + optional: true + + "@esbuild/android-arm@0.19.12": + optional: true + + "@esbuild/android-arm@0.24.2": + optional: true + + "@esbuild/android-arm@0.25.0": + optional: true + + "@esbuild/android-x64@0.18.20": + optional: true + + "@esbuild/android-x64@0.19.12": + optional: true + + "@esbuild/android-x64@0.24.2": + optional: true + + "@esbuild/android-x64@0.25.0": + optional: true + + "@esbuild/darwin-arm64@0.18.20": + optional: true + + "@esbuild/darwin-arm64@0.19.12": + optional: true + + "@esbuild/darwin-arm64@0.24.2": + optional: true + + "@esbuild/darwin-arm64@0.25.0": + optional: true + + "@esbuild/darwin-x64@0.18.20": + optional: true + + "@esbuild/darwin-x64@0.19.12": + optional: true + + "@esbuild/darwin-x64@0.24.2": + optional: true + + "@esbuild/darwin-x64@0.25.0": + optional: true + + "@esbuild/freebsd-arm64@0.18.20": + optional: true + + "@esbuild/freebsd-arm64@0.19.12": + optional: true + + "@esbuild/freebsd-arm64@0.24.2": + optional: true + + "@esbuild/freebsd-arm64@0.25.0": + optional: true + + "@esbuild/freebsd-x64@0.18.20": + optional: true + + "@esbuild/freebsd-x64@0.19.12": + optional: true + + "@esbuild/freebsd-x64@0.24.2": + optional: true + + "@esbuild/freebsd-x64@0.25.0": + optional: true + + "@esbuild/linux-arm64@0.18.20": + optional: true + + "@esbuild/linux-arm64@0.19.12": + optional: true + + "@esbuild/linux-arm64@0.24.2": + optional: true + + "@esbuild/linux-arm64@0.25.0": + optional: true + + "@esbuild/linux-arm@0.18.20": + optional: true + + "@esbuild/linux-arm@0.19.12": + optional: true + + "@esbuild/linux-arm@0.24.2": + optional: true + + "@esbuild/linux-arm@0.25.0": + optional: true + + "@esbuild/linux-ia32@0.18.20": + optional: true + + "@esbuild/linux-ia32@0.19.12": + optional: true + + "@esbuild/linux-ia32@0.24.2": + optional: true + + "@esbuild/linux-ia32@0.25.0": + optional: true + + "@esbuild/linux-loong64@0.18.20": + optional: true + + "@esbuild/linux-loong64@0.19.12": + optional: true + + "@esbuild/linux-loong64@0.24.2": + optional: true + + "@esbuild/linux-loong64@0.25.0": + optional: true + + "@esbuild/linux-mips64el@0.18.20": + optional: true + + "@esbuild/linux-mips64el@0.19.12": + optional: true + + "@esbuild/linux-mips64el@0.24.2": + optional: true + + "@esbuild/linux-mips64el@0.25.0": + optional: true + + "@esbuild/linux-ppc64@0.18.20": + optional: true + + "@esbuild/linux-ppc64@0.19.12": + optional: true + + "@esbuild/linux-ppc64@0.24.2": + optional: true + + "@esbuild/linux-ppc64@0.25.0": + optional: true + + "@esbuild/linux-riscv64@0.18.20": + optional: true + + "@esbuild/linux-riscv64@0.19.12": + optional: true + + "@esbuild/linux-riscv64@0.24.2": + optional: true + + "@esbuild/linux-riscv64@0.25.0": + optional: true + + "@esbuild/linux-s390x@0.18.20": + optional: true + + "@esbuild/linux-s390x@0.19.12": + optional: true + + "@esbuild/linux-s390x@0.24.2": + optional: true + + "@esbuild/linux-s390x@0.25.0": + optional: true + + "@esbuild/linux-x64@0.18.20": + optional: true + + "@esbuild/linux-x64@0.19.12": + optional: true + + "@esbuild/linux-x64@0.24.2": + optional: true + + "@esbuild/linux-x64@0.25.0": + optional: true + + "@esbuild/netbsd-arm64@0.24.2": + optional: true + + "@esbuild/netbsd-arm64@0.25.0": + optional: true + + "@esbuild/netbsd-x64@0.18.20": + optional: true + + "@esbuild/netbsd-x64@0.19.12": + optional: true + + "@esbuild/netbsd-x64@0.24.2": + optional: true + + "@esbuild/netbsd-x64@0.25.0": + optional: true + + "@esbuild/openbsd-arm64@0.24.2": + optional: true + + "@esbuild/openbsd-arm64@0.25.0": + optional: true + + "@esbuild/openbsd-x64@0.18.20": + optional: true + + "@esbuild/openbsd-x64@0.19.12": + optional: true + + "@esbuild/openbsd-x64@0.24.2": + optional: true + + "@esbuild/openbsd-x64@0.25.0": + optional: true + + "@esbuild/sunos-x64@0.18.20": + optional: true + + "@esbuild/sunos-x64@0.19.12": + optional: true + + "@esbuild/sunos-x64@0.24.2": + optional: true + + "@esbuild/sunos-x64@0.25.0": + optional: true + + "@esbuild/win32-arm64@0.18.20": + optional: true + + "@esbuild/win32-arm64@0.19.12": + optional: true + + "@esbuild/win32-arm64@0.24.2": + optional: true + + "@esbuild/win32-arm64@0.25.0": + optional: true + + "@esbuild/win32-ia32@0.18.20": + optional: true + + "@esbuild/win32-ia32@0.19.12": + optional: true + + "@esbuild/win32-ia32@0.24.2": + optional: true + + "@esbuild/win32-ia32@0.25.0": + optional: true + + "@esbuild/win32-x64@0.18.20": + optional: true + + "@esbuild/win32-x64@0.19.12": + optional: true + + "@esbuild/win32-x64@0.24.2": + optional: true + + "@esbuild/win32-x64@0.25.0": + optional: true + + "@eslint-community/eslint-utils@4.4.1(eslint@9.21.0(jiti@2.4.2))": + dependencies: + eslint: 9.21.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + + "@eslint-community/regexpp@4.12.1": {} + + "@eslint/config-array@0.19.2": + dependencies: + "@eslint/object-schema": 2.1.6 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + "@eslint/core@0.12.0": + dependencies: + "@types/json-schema": 7.0.15 + + "@eslint/eslintrc@3.3.0": + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.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.21.0": {} + + "@eslint/object-schema@2.1.6": {} + + "@eslint/plugin-kit@0.2.7": + dependencies: + "@eslint/core": 0.12.0 + levn: 0.4.1 + + "@humanfs/core@0.19.1": {} + + "@humanfs/node@0.16.6": + dependencies: + "@humanfs/core": 0.19.1 + "@humanwhocodes/retry": 0.3.1 + + "@humanwhocodes/module-importer@1.0.1": {} + + "@humanwhocodes/retry@0.3.1": {} + + "@humanwhocodes/retry@0.4.2": {} + + "@jridgewell/gen-mapping@0.3.8": + dependencies: + "@jridgewell/set-array": 1.2.1 + "@jridgewell/sourcemap-codec": 1.5.0 + "@jridgewell/trace-mapping": 0.3.25 + + "@jridgewell/resolve-uri@3.1.2": {} + + "@jridgewell/set-array@1.2.1": {} + + "@jridgewell/sourcemap-codec@1.5.0": {} + + "@jridgewell/trace-mapping@0.3.25": + dependencies: + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.0 + + "@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.0 + + "@rollup/rollup-android-arm-eabi@4.34.8": + optional: true + + "@rollup/rollup-android-arm64@4.34.8": + optional: true + + "@rollup/rollup-darwin-arm64@4.34.8": + optional: true + + "@rollup/rollup-darwin-x64@4.34.8": + optional: true + + "@rollup/rollup-freebsd-arm64@4.34.8": + optional: true + + "@rollup/rollup-freebsd-x64@4.34.8": + optional: true + + "@rollup/rollup-linux-arm-gnueabihf@4.34.8": + optional: true + + "@rollup/rollup-linux-arm-musleabihf@4.34.8": + optional: true + + "@rollup/rollup-linux-arm64-gnu@4.34.8": + optional: true + + "@rollup/rollup-linux-arm64-musl@4.34.8": + optional: true + + "@rollup/rollup-linux-loongarch64-gnu@4.34.8": + optional: true + + "@rollup/rollup-linux-powerpc64le-gnu@4.34.8": + optional: true + + "@rollup/rollup-linux-riscv64-gnu@4.34.8": + optional: true + + "@rollup/rollup-linux-s390x-gnu@4.34.8": + optional: true + + "@rollup/rollup-linux-x64-gnu@4.34.8": + optional: true + + "@rollup/rollup-linux-x64-musl@4.34.8": + optional: true + + "@rollup/rollup-win32-arm64-msvc@4.34.8": + optional: true + + "@rollup/rollup-win32-ia32-msvc@4.34.8": + optional: true + + "@rollup/rollup-win32-x64-msvc@4.34.8": + optional: true + + "@tailwindcss/node@4.0.8": + dependencies: + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + tailwindcss: 4.0.8 + + "@tailwindcss/oxide-android-arm64@4.0.8": + optional: true + + "@tailwindcss/oxide-darwin-arm64@4.0.8": + optional: true + + "@tailwindcss/oxide-darwin-x64@4.0.8": + optional: true + + "@tailwindcss/oxide-freebsd-x64@4.0.8": + optional: true + + "@tailwindcss/oxide-linux-arm-gnueabihf@4.0.8": + optional: true + + "@tailwindcss/oxide-linux-arm64-gnu@4.0.8": + optional: true + + "@tailwindcss/oxide-linux-arm64-musl@4.0.8": + optional: true + + "@tailwindcss/oxide-linux-x64-gnu@4.0.8": + optional: true + + "@tailwindcss/oxide-linux-x64-musl@4.0.8": + optional: true + + "@tailwindcss/oxide-win32-arm64-msvc@4.0.8": + optional: true + + "@tailwindcss/oxide-win32-x64-msvc@4.0.8": + optional: true + + "@tailwindcss/oxide@4.0.8": + optionalDependencies: + "@tailwindcss/oxide-android-arm64": 4.0.8 + "@tailwindcss/oxide-darwin-arm64": 4.0.8 + "@tailwindcss/oxide-darwin-x64": 4.0.8 + "@tailwindcss/oxide-freebsd-x64": 4.0.8 + "@tailwindcss/oxide-linux-arm-gnueabihf": 4.0.8 + "@tailwindcss/oxide-linux-arm64-gnu": 4.0.8 + "@tailwindcss/oxide-linux-arm64-musl": 4.0.8 + "@tailwindcss/oxide-linux-x64-gnu": 4.0.8 + "@tailwindcss/oxide-linux-x64-musl": 4.0.8 + "@tailwindcss/oxide-win32-arm64-msvc": 4.0.8 + "@tailwindcss/oxide-win32-x64-msvc": 4.0.8 + + "@tailwindcss/vite@4.0.8(vite@6.1.1(@types/node@22.13.5)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.3))": + dependencies: + "@tailwindcss/node": 4.0.8 + "@tailwindcss/oxide": 4.0.8 + lightningcss: 1.29.1 + tailwindcss: 4.0.8 + vite: 6.1.1(@types/node@22.13.5)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.3) + + "@types/babel__core@7.20.5": + dependencies: + "@babel/parser": 7.26.9 + "@babel/types": 7.26.9 + "@types/babel__generator": 7.6.8 + "@types/babel__template": 7.4.4 + "@types/babel__traverse": 7.20.6 + + "@types/babel__generator@7.6.8": + dependencies: + "@babel/types": 7.26.9 + + "@types/babel__template@7.4.4": + dependencies: + "@babel/parser": 7.26.9 + "@babel/types": 7.26.9 + + "@types/babel__traverse@7.20.6": + dependencies: + "@babel/types": 7.26.9 + + "@types/body-parser@1.19.5": + dependencies: + "@types/connect": 3.4.38 + "@types/node": 22.13.5 + + "@types/connect@3.4.38": + dependencies: + "@types/node": 22.13.5 + + "@types/cors@2.8.17": + dependencies: + "@types/node": 22.13.5 + + "@types/estree@1.0.6": {} + + "@types/express-serve-static-core@4.19.6": + dependencies: + "@types/node": 22.13.5 + "@types/qs": 6.9.18 + "@types/range-parser": 1.2.7 + "@types/send": 0.17.4 + + "@types/express@4.17.21": + dependencies: + "@types/body-parser": 1.19.5 + "@types/express-serve-static-core": 4.19.6 + "@types/qs": 6.9.18 + "@types/serve-static": 1.15.7 + + "@types/http-errors@2.0.4": {} + + "@types/json-schema@7.0.15": {} + + "@types/mime@1.3.5": {} + + "@types/node@22.13.5": + dependencies: + undici-types: 6.20.0 + + "@types/pg@8.11.11": + dependencies: + "@types/node": 22.13.5 + pg-protocol: 1.7.1 + pg-types: 4.0.2 + + "@types/qs@6.9.18": {} + + "@types/range-parser@1.2.7": {} + + "@types/react-dom@19.0.4(@types/react@19.0.10)": + dependencies: + "@types/react": 19.0.10 + + "@types/react@19.0.10": + dependencies: + csstype: 3.1.3 + + "@types/send@0.17.4": + dependencies: + "@types/mime": 1.3.5 + "@types/node": 22.13.5 + + "@types/serve-static@1.15.7": + dependencies: + "@types/http-errors": 2.0.4 + "@types/node": 22.13.5 + "@types/send": 0.17.4 + + "@types/use-sync-external-store@0.0.6": {} + + "@typescript-eslint/eslint-plugin@8.25.0(@typescript-eslint/parser@8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3)": + dependencies: + "@eslint-community/regexpp": 4.12.1 + "@typescript-eslint/parser": 8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) + "@typescript-eslint/scope-manager": 8.25.0 + "@typescript-eslint/type-utils": 8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) + "@typescript-eslint/utils": 8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) + "@typescript-eslint/visitor-keys": 8.25.0 + eslint: 9.21.0(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 2.0.1(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/parser@8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3)": + dependencies: + "@typescript-eslint/scope-manager": 8.25.0 + "@typescript-eslint/types": 8.25.0 + "@typescript-eslint/typescript-estree": 8.25.0(typescript@5.7.3) + "@typescript-eslint/visitor-keys": 8.25.0 + debug: 4.4.0 + eslint: 9.21.0(jiti@2.4.2) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/scope-manager@8.25.0": + dependencies: + "@typescript-eslint/types": 8.25.0 + "@typescript-eslint/visitor-keys": 8.25.0 + + "@typescript-eslint/type-utils@8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3)": + dependencies: + "@typescript-eslint/typescript-estree": 8.25.0(typescript@5.7.3) + "@typescript-eslint/utils": 8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) + debug: 4.4.0 + eslint: 9.21.0(jiti@2.4.2) + ts-api-utils: 2.0.1(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/types@8.25.0": {} + + "@typescript-eslint/typescript-estree@8.25.0(typescript@5.7.3)": + dependencies: + "@typescript-eslint/types": 8.25.0 + "@typescript-eslint/visitor-keys": 8.25.0 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.0.1(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/utils@8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3)": + dependencies: + "@eslint-community/eslint-utils": 4.4.1(eslint@9.21.0(jiti@2.4.2)) + "@typescript-eslint/scope-manager": 8.25.0 + "@typescript-eslint/types": 8.25.0 + "@typescript-eslint/typescript-estree": 8.25.0(typescript@5.7.3) + eslint: 9.21.0(jiti@2.4.2) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/visitor-keys@8.25.0": + dependencies: + "@typescript-eslint/types": 8.25.0 + eslint-visitor-keys: 4.2.0 + + "@vitejs/plugin-react@4.3.4(vite@6.1.1(@types/node@22.13.5)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.3))": + dependencies: + "@babel/core": 7.26.9 + "@babel/plugin-transform-react-jsx-self": 7.25.9(@babel/core@7.26.9) + "@babel/plugin-transform-react-jsx-source": 7.25.9(@babel/core@7.26.9) + "@types/babel__core": 7.20.5 + react-refresh: 0.14.2 + vite: 6.1.1(@types/node@22.13.5)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.3) + transitivePeerDependencies: + - supports-color + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-jsx@5.3.2(acorn@8.14.0): + dependencies: + acorn: 8.14.0 + + acorn@8.14.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-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + array-flatten@1.1.1: {} + + balanced-match@1.0.2: {} + + body-parser@1.20.3: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.4: + dependencies: + caniuse-lite: 1.0.30001700 + electron-to-chromium: 1.5.104 + node-releases: 2.0.19 + update-browserslist-db: 1.1.2(browserslist@4.24.4) + + buffer-from@1.1.2: {} + + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.3: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001700: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + concurrently@9.1.2: + dependencies: + chalk: 4.1.2 + lodash: 4.17.21 + rxjs: 7.8.2 + shell-quote: 1.8.2 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.6: {} + + cookie@0.7.1: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.1.3: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + depd@2.0.0: {} + + destroy@1.2.0: {} + + detect-libc@1.0.3: {} + + dotenv@16.4.7: {} + + drizzle-kit@0.30.4: + dependencies: + "@drizzle-team/brocli": 0.10.2 + "@esbuild-kit/esm-loader": 2.6.5 + esbuild: 0.19.12 + esbuild-register: 3.6.0(esbuild@0.19.12) + transitivePeerDependencies: + - supports-color + + drizzle-orm@0.39.3(@types/pg@8.11.11)(kysely@0.27.5)(pg@8.13.3): + optionalDependencies: + "@types/pg": 8.11.11 + kysely: 0.27.5 + pg: 8.13.3 + + drizzle-zod@0.7.0(drizzle-orm@0.39.3(@types/pg@8.11.11)(kysely@0.27.5)(pg@8.13.3))(zod@3.24.2): + dependencies: + drizzle-orm: 0.39.3(@types/pg@8.11.11)(kysely@0.27.5)(pg@8.13.3) + zod: 3.24.2 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.104: {} + + emoji-regex@8.0.0: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + esbuild-register@3.6.0(esbuild@0.19.12): + dependencies: + debug: 4.4.0 + esbuild: 0.19.12 + transitivePeerDependencies: + - supports-color + + esbuild@0.18.20: + optionalDependencies: + "@esbuild/android-arm": 0.18.20 + "@esbuild/android-arm64": 0.18.20 + "@esbuild/android-x64": 0.18.20 + "@esbuild/darwin-arm64": 0.18.20 + "@esbuild/darwin-x64": 0.18.20 + "@esbuild/freebsd-arm64": 0.18.20 + "@esbuild/freebsd-x64": 0.18.20 + "@esbuild/linux-arm": 0.18.20 + "@esbuild/linux-arm64": 0.18.20 + "@esbuild/linux-ia32": 0.18.20 + "@esbuild/linux-loong64": 0.18.20 + "@esbuild/linux-mips64el": 0.18.20 + "@esbuild/linux-ppc64": 0.18.20 + "@esbuild/linux-riscv64": 0.18.20 + "@esbuild/linux-s390x": 0.18.20 + "@esbuild/linux-x64": 0.18.20 + "@esbuild/netbsd-x64": 0.18.20 + "@esbuild/openbsd-x64": 0.18.20 + "@esbuild/sunos-x64": 0.18.20 + "@esbuild/win32-arm64": 0.18.20 + "@esbuild/win32-ia32": 0.18.20 + "@esbuild/win32-x64": 0.18.20 + + esbuild@0.19.12: + optionalDependencies: + "@esbuild/aix-ppc64": 0.19.12 + "@esbuild/android-arm": 0.19.12 + "@esbuild/android-arm64": 0.19.12 + "@esbuild/android-x64": 0.19.12 + "@esbuild/darwin-arm64": 0.19.12 + "@esbuild/darwin-x64": 0.19.12 + "@esbuild/freebsd-arm64": 0.19.12 + "@esbuild/freebsd-x64": 0.19.12 + "@esbuild/linux-arm": 0.19.12 + "@esbuild/linux-arm64": 0.19.12 + "@esbuild/linux-ia32": 0.19.12 + "@esbuild/linux-loong64": 0.19.12 + "@esbuild/linux-mips64el": 0.19.12 + "@esbuild/linux-ppc64": 0.19.12 + "@esbuild/linux-riscv64": 0.19.12 + "@esbuild/linux-s390x": 0.19.12 + "@esbuild/linux-x64": 0.19.12 + "@esbuild/netbsd-x64": 0.19.12 + "@esbuild/openbsd-x64": 0.19.12 + "@esbuild/sunos-x64": 0.19.12 + "@esbuild/win32-arm64": 0.19.12 + "@esbuild/win32-ia32": 0.19.12 + "@esbuild/win32-x64": 0.19.12 + + esbuild@0.24.2: + optionalDependencies: + "@esbuild/aix-ppc64": 0.24.2 + "@esbuild/android-arm": 0.24.2 + "@esbuild/android-arm64": 0.24.2 + "@esbuild/android-x64": 0.24.2 + "@esbuild/darwin-arm64": 0.24.2 + "@esbuild/darwin-x64": 0.24.2 + "@esbuild/freebsd-arm64": 0.24.2 + "@esbuild/freebsd-x64": 0.24.2 + "@esbuild/linux-arm": 0.24.2 + "@esbuild/linux-arm64": 0.24.2 + "@esbuild/linux-ia32": 0.24.2 + "@esbuild/linux-loong64": 0.24.2 + "@esbuild/linux-mips64el": 0.24.2 + "@esbuild/linux-ppc64": 0.24.2 + "@esbuild/linux-riscv64": 0.24.2 + "@esbuild/linux-s390x": 0.24.2 + "@esbuild/linux-x64": 0.24.2 + "@esbuild/netbsd-arm64": 0.24.2 + "@esbuild/netbsd-x64": 0.24.2 + "@esbuild/openbsd-arm64": 0.24.2 + "@esbuild/openbsd-x64": 0.24.2 + "@esbuild/sunos-x64": 0.24.2 + "@esbuild/win32-arm64": 0.24.2 + "@esbuild/win32-ia32": 0.24.2 + "@esbuild/win32-x64": 0.24.2 + + esbuild@0.25.0: + optionalDependencies: + "@esbuild/aix-ppc64": 0.25.0 + "@esbuild/android-arm": 0.25.0 + "@esbuild/android-arm64": 0.25.0 + "@esbuild/android-x64": 0.25.0 + "@esbuild/darwin-arm64": 0.25.0 + "@esbuild/darwin-x64": 0.25.0 + "@esbuild/freebsd-arm64": 0.25.0 + "@esbuild/freebsd-x64": 0.25.0 + "@esbuild/linux-arm": 0.25.0 + "@esbuild/linux-arm64": 0.25.0 + "@esbuild/linux-ia32": 0.25.0 + "@esbuild/linux-loong64": 0.25.0 + "@esbuild/linux-mips64el": 0.25.0 + "@esbuild/linux-ppc64": 0.25.0 + "@esbuild/linux-riscv64": 0.25.0 + "@esbuild/linux-s390x": 0.25.0 + "@esbuild/linux-x64": 0.25.0 + "@esbuild/netbsd-arm64": 0.25.0 + "@esbuild/netbsd-x64": 0.25.0 + "@esbuild/openbsd-arm64": 0.25.0 + "@esbuild/openbsd-x64": 0.25.0 + "@esbuild/sunos-x64": 0.25.0 + "@esbuild/win32-arm64": 0.25.0 + "@esbuild/win32-ia32": 0.25.0 + "@esbuild/win32-x64": 0.25.0 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@4.0.0: {} + + eslint-plugin-react-hooks@5.1.0(eslint@9.21.0(jiti@2.4.2)): + dependencies: + eslint: 9.21.0(jiti@2.4.2) + + eslint-plugin-react-refresh@0.4.19(eslint@9.21.0(jiti@2.4.2)): + dependencies: + eslint: 9.21.0(jiti@2.4.2) + + eslint-scope@8.2.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@9.21.0(jiti@2.4.2): + dependencies: + "@eslint-community/eslint-utils": 4.4.1(eslint@9.21.0(jiti@2.4.2)) + "@eslint-community/regexpp": 4.12.1 + "@eslint/config-array": 0.19.2 + "@eslint/core": 0.12.0 + "@eslint/eslintrc": 3.3.0 + "@eslint/js": 9.21.0 + "@eslint/plugin-kit": 0.2.7 + "@humanfs/node": 0.16.6 + "@humanwhocodes/module-importer": 1.0.1 + "@humanwhocodes/retry": 0.4.2 + "@types/estree": 1.0.6 + "@types/json-schema": 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.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 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + express@4.21.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.12 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + 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.0: + dependencies: + reusify: 1.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.1: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + 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: {} + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-tsconfig@4.10.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@11.12.0: {} + + globals@14.0.0: {} + + globals@15.15.0: {} + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inherits@2.0.4: {} + + ipaddr.js@1.9.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + isexe@2.0.0: {} + + jiti@2.4.2: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kysely@0.27.5: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-darwin-arm64@1.29.1: + optional: true + + lightningcss-darwin-x64@1.29.1: + optional: true + + lightningcss-freebsd-x64@1.29.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.29.1: + optional: true + + lightningcss-linux-arm64-gnu@1.29.1: + optional: true + + lightningcss-linux-arm64-musl@1.29.1: + optional: true + + lightningcss-linux-x64-gnu@1.29.1: + optional: true + + lightningcss-linux-x64-musl@1.29.1: + optional: true + + lightningcss-win32-arm64-msvc@1.29.1: + optional: true + + lightningcss-win32-x64-msvc@1.29.1: + optional: true + + lightningcss@1.29.1: + dependencies: + detect-libc: 1.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.29.1 + lightningcss-darwin-x64: 1.29.1 + lightningcss-freebsd-x64: 1.29.1 + lightningcss-linux-arm-gnueabihf: 1.29.1 + lightningcss-linux-arm64-gnu: 1.29.1 + lightningcss-linux-arm64-musl: 1.29.1 + lightningcss-linux-x64-gnu: 1.29.1 + lightningcss-linux-x64-musl: 1.29.1 + lightningcss-win32-arm64-msvc: 1.29.1 + lightningcss-win32-x64-msvc: 1.29.1 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + math-intrinsics@1.1.0: {} + + media-typer@0.3.0: {} + + merge-descriptors@1.0.3: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + mitt@3.0.1: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + nanoid@3.3.8: {} + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + node-releases@2.0.19: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + obuf@1.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + 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 + + parseurl@1.3.3: {} + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-to-regexp@0.1.12: {} + + pg-cloudflare@1.1.1: + optional: true + + pg-connection-string@2.7.0: {} + + pg-int8@1.0.1: {} + + pg-numeric@1.0.2: {} + + pg-pool@3.7.1(pg@8.13.3): + dependencies: + pg: 8.13.3 + + pg-protocol@1.7.1: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.0 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg-types@4.0.2: + dependencies: + pg-int8: 1.0.1 + pg-numeric: 1.0.2 + postgres-array: 3.0.2 + postgres-bytea: 3.0.0 + postgres-date: 2.1.0 + postgres-interval: 3.0.0 + postgres-range: 1.1.4 + + pg@8.13.3: + dependencies: + pg-connection-string: 2.7.0 + pg-pool: 3.7.1(pg@8.13.3) + pg-protocol: 1.7.1 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.1.1 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + postcss@8.5.3: + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postgres-array@2.0.0: {} + + postgres-array@3.0.2: {} + + postgres-bytea@1.0.0: {} + + postgres-bytea@3.0.0: + dependencies: + obuf: 1.1.2 + + postgres-date@1.0.7: {} + + postgres-date@2.1.0: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + + postgres-interval@3.0.0: {} + + postgres-range@1.1.4: {} + + prelude-ls@1.2.1: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + punycode@2.3.1: {} + + qs@6.13.0: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + react-dom@19.0.0(react@19.0.0): + dependencies: + react: 19.0.0 + scheduler: 0.25.0 + + react-refresh@0.14.2: {} + + react@19.0.0: {} + + require-directory@2.1.1: {} + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + reusify@1.0.4: {} + + rollup@4.34.8: + dependencies: + "@types/estree": 1.0.6 + optionalDependencies: + "@rollup/rollup-android-arm-eabi": 4.34.8 + "@rollup/rollup-android-arm64": 4.34.8 + "@rollup/rollup-darwin-arm64": 4.34.8 + "@rollup/rollup-darwin-x64": 4.34.8 + "@rollup/rollup-freebsd-arm64": 4.34.8 + "@rollup/rollup-freebsd-x64": 4.34.8 + "@rollup/rollup-linux-arm-gnueabihf": 4.34.8 + "@rollup/rollup-linux-arm-musleabihf": 4.34.8 + "@rollup/rollup-linux-arm64-gnu": 4.34.8 + "@rollup/rollup-linux-arm64-musl": 4.34.8 + "@rollup/rollup-linux-loongarch64-gnu": 4.34.8 + "@rollup/rollup-linux-powerpc64le-gnu": 4.34.8 + "@rollup/rollup-linux-riscv64-gnu": 4.34.8 + "@rollup/rollup-linux-s390x-gnu": 4.34.8 + "@rollup/rollup-linux-x64-gnu": 4.34.8 + "@rollup/rollup-linux-x64-musl": 4.34.8 + "@rollup/rollup-win32-arm64-msvc": 4.34.8 + "@rollup/rollup-win32-ia32-msvc": 4.34.8 + "@rollup/rollup-win32-x64-msvc": 4.34.8 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + scheduler@0.25.0: {} + + semver@6.3.1: {} + + semver@7.7.1: {} + + send@0.19.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.2: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.2: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + split2@4.2.0: {} + + statuses@2.0.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + tailwindcss@4.0.8: {} + + tapable@2.2.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + tree-kill@1.2.2: {} + + ts-api-utils@2.0.1(typescript@5.7.3): + dependencies: + typescript: 5.7.3 + + tslib@2.8.1: {} + + tsx@4.19.3: + dependencies: + esbuild: 0.25.0 + get-tsconfig: 4.10.0 + optionalDependencies: + fsevents: 2.3.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typescript-eslint@8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3): + dependencies: + "@typescript-eslint/eslint-plugin": 8.25.0(@typescript-eslint/parser@8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) + "@typescript-eslint/parser": 8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) + "@typescript-eslint/utils": 8.25.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) + eslint: 9.21.0(jiti@2.4.2) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + typescript@5.7.3: {} + + undici-types@6.20.0: {} + + unpipe@1.0.0: {} + + update-browserslist-db@1.1.2(browserslist@4.24.4): + dependencies: + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + utils-merge@1.0.1: {} + + vary@1.1.2: {} + + vite@6.1.1(@types/node@22.13.5)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.3): + dependencies: + esbuild: 0.24.2 + postcss: 8.5.3 + rollup: 4.34.8 + optionalDependencies: + "@types/node": 22.13.5 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.29.1 + tsx: 4.19.3 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} + + zod@3.24.2: {} diff --git a/examples/solid/todo/postgres.conf b/examples/solid/todo/postgres.conf new file mode 100644 index 00000000..cafbb9b3 --- /dev/null +++ b/examples/solid/todo/postgres.conf @@ -0,0 +1,17 @@ +listen_addresses = '*' +max_connections = 100 +shared_buffers = 128MB +dynamic_shared_memory_type = posix +max_wal_size = 1GB +min_wal_size = 80MB +log_timezone = 'UTC' +datestyle = 'iso, mdy' +timezone = 'UTC' +lc_messages = 'en_US.utf8' +lc_monetary = 'en_US.utf8' +lc_numeric = 'en_US.utf8' +lc_time = 'en_US.utf8' +default_text_search_config = 'pg_catalog.english' +wal_level = logical +max_replication_slots = 10 +max_wal_senders = 10 diff --git a/examples/solid/todo/public/vite.svg b/examples/solid/todo/public/vite.svg new file mode 100644 index 00000000..e7b8dfb1 --- /dev/null +++ b/examples/solid/todo/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/solid/todo/scripts/migrate.ts b/examples/solid/todo/scripts/migrate.ts new file mode 100644 index 00000000..ee0089f3 --- /dev/null +++ b/examples/solid/todo/scripts/migrate.ts @@ -0,0 +1,29 @@ +import { drizzle } from "drizzle-orm/node-postgres" +import { migrate } from "drizzle-orm/node-postgres/migrator" +import pkg from "pg" +import * as dotenv from "dotenv" + +dotenv.config() + +const { Pool } = pkg +const pool = new Pool({ + host: process.env.DB_HOST || `localhost`, + port: parseInt(process.env.DB_PORT || `54322`), + user: process.env.DB_USER || `postgres`, + password: process.env.DB_PASSWORD || `postgres`, + database: process.env.DB_NAME || `todo_app`, +}) + +const db = drizzle(pool) + +async function main() { + console.log(`Running migrations...`) + await migrate(db, { migrationsFolder: `./drizzle` }) + console.log(`Migrations completed!`) + await pool.end() +} + +main().catch((err) => { + console.error(`Migration failed!`, err) + process.exit(1) +}) diff --git a/examples/solid/todo/src/App.tsx b/examples/solid/todo/src/App.tsx new file mode 100644 index 00000000..38d04cf5 --- /dev/null +++ b/examples/solid/todo/src/App.tsx @@ -0,0 +1,654 @@ +import { useLiveQuery, useOptimisticMutation } from "@tanstack/solid-db" +import { + createElectricCollection, + createQueryCollection, +} from "@tanstack/db-collections" +import { QueryClient } from "@tanstack/query-core" +import { updateConfigSchema, updateTodoSchema } from "./db/validation" +import type { + ElectricCollection, + QueryCollection, +} from "@tanstack/db-collections" +import type { Collection, PendingMutation } from "@tanstack/solid-db" +import type { UpdateConfig, UpdateTodo } from "./db/validation" +import type { JSX } from "solid-js/jsx-runtime" +import { createSignal, For, Show } from "solid-js" + +// API helper for todos and config +const API_BASE_URL = `http://localhost:3001/api` + +const api = { + // Todo API methods + todos: { + getAll: async (): Promise> => { + const response = await fetch(`${API_BASE_URL}/todos`) + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`) + return response.json() + }, + getById: async (id: number): Promise => { + const response = await fetch(`${API_BASE_URL}/todos/${id}`) + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`) + return response.json() + }, + create: async ( + todo: Partial + ): Promise<{ todo: UpdateTodo; txid: number }> => { + const response = await fetch(`${API_BASE_URL}/todos`, { + method: `POST`, + headers: { "Content-Type": `application/json` }, + body: JSON.stringify(todo), + }) + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`) + return response.json() + }, + update: async ( + id: unknown, + changes: Partial + ): Promise<{ todo: UpdateTodo; txid: number }> => { + const response = await fetch(`${API_BASE_URL}/todos/${id}`, { + method: `PUT`, + headers: { "Content-Type": `application/json` }, + body: JSON.stringify(changes), + }) + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`) + return response.json() + }, + delete: async ( + id: unknown + ): Promise<{ success: boolean; txid: number }> => { + const response = await fetch(`${API_BASE_URL}/todos/${id}`, { + method: `DELETE`, + }) + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`) + return response.json() + }, + }, + + // Config API methods + config: { + getAll: async (): Promise> => { + const response = await fetch(`${API_BASE_URL}/config`) + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`) + return response.json() + }, + getById: async (id: number): Promise => { + const response = await fetch(`${API_BASE_URL}/config/${id}`) + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`) + return response.json() + }, + create: async ( + config: Partial + ): Promise<{ config: UpdateConfig; txid: number }> => { + const response = await fetch(`${API_BASE_URL}/config`, { + method: `POST`, + headers: { "Content-Type": `application/json` }, + body: JSON.stringify(config), + }) + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`) + return response.json() + }, + update: async ( + id: number, + changes: Partial + ): Promise<{ config: UpdateConfig; txid: number }> => { + const response = await fetch(`${API_BASE_URL}/config/${id}`, { + method: `PUT`, + headers: { "Content-Type": `application/json` }, + body: JSON.stringify(changes), + }) + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`) + return response.json() + }, + delete: async (id: number): Promise<{ success: boolean; txid: number }> => { + const response = await fetch(`${API_BASE_URL}/config/${id}`, { + method: `DELETE`, + }) + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`) + return response.json() + }, + }, +} + +// Collection type enum +const CollectionType = { + Electric: `electric`, + Query: `query`, +} as const + +type CollectionType = (typeof CollectionType)[keyof typeof CollectionType] + +// Create a query client for query collections +const queryClient = new QueryClient() + +const collectionsCache = new Map() +// Function to create the appropriate todo collection based on type +const createTodoCollection = (type: CollectionType) => { + if (collectionsCache.has(`todo`)) { + return collectionsCache.get(`todo`) + } else { + let newCollection: Collection + if (type === CollectionType.Electric) { + newCollection = createElectricCollection({ + id: `todos`, + streamOptions: { + url: `http://localhost:3003/v1/shape`, + params: { + table: `todos`, + }, + parser: { + // Parse timestamp columns into JavaScript Date objects + timestamptz: (date: string) => new Date(date), + }, + }, + primaryKey: [`id`], + schema: updateTodoSchema, + }) + } else { + // Query collection using our API helper + newCollection = createQueryCollection({ + id: `todos`, + queryKey: [`todos`], + refetchInterval: 3000, + queryFn: async () => { + const todos = await api.todos.getAll() + // Turn date strings into Dates if needed + return todos.map((todo) => ({ + ...todo, + created_at: todo.created_at ? new Date(todo.created_at) : undefined, + updated_at: todo.updated_at ? new Date(todo.updated_at) : undefined, + })) + }, + getId: (item) => String(item.id), + schema: updateTodoSchema, + queryClient, + }) + } + collectionsCache.set(`todo`, newCollection) + return newCollection + } +} + +// Function to create the appropriate config collection based on type +const createConfigCollection = (type: CollectionType) => { + if (collectionsCache.has(`config`)) { + return collectionsCache.get(`config`) + } else { + let newCollection: Collection + if (type === CollectionType.Electric) { + newCollection = createElectricCollection({ + id: `config`, + streamOptions: { + url: `http://localhost:3003/v1/shape`, + params: { + table: `config`, + }, + parser: { + // Parse timestamp columns into JavaScript Date objects + timestamptz: (date: string) => { + return new Date(date) + }, + }, + }, + primaryKey: [`id`], + schema: updateConfigSchema, + }) + } else { + // Query collection using our API helper + newCollection = createQueryCollection({ + id: `config`, + queryKey: [`config`], + refetchInterval: 3000, + queryFn: async () => { + const configs = await api.config.getAll() + // Turn date strings into Dates if needed + return configs.map((config) => ({ + ...config, + created_at: config.created_at + ? new Date(config.created_at) + : undefined, + updated_at: config.updated_at + ? new Date(config.updated_at) + : undefined, + })) + }, + getId: (item) => String(item.id), + schema: updateConfigSchema, + queryClient, + }) + } + collectionsCache.set(`config`, newCollection) + return newCollection + } +} + +// A bit of indirection to handle awaiting each collection type syncing in new changes. +async function collectionSync( + type: CollectionType, + mutation: PendingMutation, + txid: number +) { + if (type === CollectionType.Query) { + await (mutation.collection as QueryCollection).invalidate() + } else { + await (mutation.collection as ElectricCollection).awaitTxId( + txid + ) + } +} + +export default function App() { + // Read collection type from URL param directly + const getInitialCollectionType = (): CollectionType => { + const params = new URLSearchParams(window.location.search) + return params.get(`type`) === `electric` + ? CollectionType.Electric + : CollectionType.Query + } + + const collectionType = getInitialCollectionType() + const [newTodo, setNewTodo] = createSignal(``) + + // Create collections + const todoCollection = createTodoCollection(collectionType) + const configCollection = createConfigCollection(collectionType) + + // Always call useLiveQuery hooks + const { data: todos } = useLiveQuery((q) => + q + .from({ todoCollection: todoCollection as Collection }) + .keyBy(`@id`) + .orderBy(`@created_at`) + .select(`@id`, `@created_at`, `@text`, `@completed`) + ) + + const { data: configData } = useLiveQuery((q) => + q + .from({ configCollection: configCollection as Collection }) + .keyBy(`@id`) + .select(`@id`, `@key`, `@value`) + ) + + // Define mutations + const addTodo = useOptimisticMutation({ + mutationFn: async ({ transaction }) => { + const mutation = transaction.mutations[0] as PendingMutation + + const { modified } = mutation + const response = await api.todos.create(modified) + await collectionSync(collectionType, mutation, response.txid) + }, + }) + + const updateTodo = useOptimisticMutation({ + mutationFn: async ({ transaction }) => { + const mutation = transaction.mutations[0] as PendingMutation + const { original, changes } = mutation + const response = await api.todos.update(original.id, changes) + await collectionSync(collectionType, mutation, response.txid) + }, + }) + + const deleteTodo = useOptimisticMutation({ + mutationFn: async ({ transaction }) => { + const mutation = transaction.mutations[0] as PendingMutation + const { original } = mutation + const response = await api.todos.delete(original.id) + await collectionSync(collectionType, mutation, response.txid) + }, + }) + + const createConfig = useOptimisticMutation({ + mutationFn: async ({ transaction }) => { + const mutation = transaction.mutations[0] as PendingMutation + const { modified } = mutation + const response = await api.config.create(modified) + await collectionSync(collectionType, mutation, response.txid) + }, + }) + + const updateConfig = useOptimisticMutation({ + mutationFn: async ({ transaction }) => { + const mutation = transaction.mutations[0] as PendingMutation + const { original, changes } = mutation + const response = await api.config.update(original.id as number, changes) + await collectionSync(collectionType, mutation, response.txid) + }, + }) + + // Handle collection type change directly + const handleCollectionTypeChange = (type: CollectionType) => { + if (type !== collectionType) { + // Update URL and reload page + const url = new URL(window.location.href) + url.searchParams.set(`type`, type) + window.location.href = url.toString() + } + } + + // Define a more robust type-safe helper function to get config values + const getConfigValue = (key: string): string => { + for (const config of configData()) { + if (config.key === key) { + return config.value! + } + } + return `` + } + + // Define a helper function to update config values + const setConfigValue = (key: string, value: string): void => { + for (const config of configData()) { + if (config.key === key) { + updateConfig.mutate(() => + configCollection.update( + Array.from(configCollection.state.values())[0]! as UpdateConfig, + (draft) => { + draft.value = value + } + ) + ) + + return + } + } + + // If the config doesn't exist yet, create it + createConfig.mutate(() => + configCollection.insert({ + key, + value, + }) + ) + } + + const backgroundColor = getConfigValue(`backgroundColor`) + + // Function to generate a complementary color + const getComplementaryColor = (hexColor: string): string => { + // Default to a nice blue if no color is provided + if (!hexColor) return `#3498db` + + // Remove the hash if it exists + const color = hexColor.replace(`#`, ``) + + // Convert hex to RGB + const r = parseInt(color.substr(0, 2), 16) + const g = parseInt(color.substr(2, 2), 16) + const b = parseInt(color.substr(4, 2), 16) + + // Calculate complementary color (inverting the RGB values) + const compR = 255 - r + const compG = 255 - g + const compB = 255 - b + + // Convert back to hex + const compHex = + `#` + + ((1 << 24) + (compR << 16) + (compG << 8) + compB).toString(16).slice(1) + + // Calculate brightness of the background + const brightness = r * 0.299 + g * 0.587 + b * 0.114 + + // If the complementary color doesn't have enough contrast, adjust it + const compBrightness = compR * 0.299 + compG * 0.587 + compB * 0.114 + const brightnessDiff = Math.abs(brightness - compBrightness) + + if (brightnessDiff < 128) { + // Not enough contrast, use a more vibrant alternative + if (brightness > 128) { + // Dark color for light background + return `#8e44ad` // Purple + } else { + // Light color for dark background + return `#f1c40f` // Yellow + } + } + + return compHex + } + + const titleColor = getComplementaryColor(backgroundColor) + + const handleColorChange: JSX.EventHandler = ( + e + ) => { + const newColor = e.currentTarget.value + setConfigValue(`backgroundColor`, newColor) + } + + const handleSubmit: JSX.EventHandlerUnion< + HTMLFormElement, + SubmitEvent, + JSX.EventHandler + > = (e) => { + e.preventDefault() + if (!newTodo().trim()) return + + addTodo.mutate(() => + todoCollection.insert({ + text: newTodo(), + completed: false, + id: Math.round(Math.random() * 1000000), + }) + ) + setNewTodo(``) + } + + const toggleTodo = (todo: UpdateTodo) => { + updateTodo.mutate(() => + todoCollection.update( + Array.from(todoCollection.state.values()).find( + (t) => t.id === todo.id + )!, + (draft) => { + draft.completed = !draft.completed + } + ) + ) + } + + const activeTodos = () => todos().filter((todo) => !todo.completed) + const completedTodos = () => todos().filter((todo) => todo.completed) + + return ( + <> +
+
+

+ todos +

+ + {/* Collection Type Selector */} +
+
+
+ + Collection Type + +
+
+ + +
+
+
+ +
+
+ + +
+
+ +
+
+ 0}> + + + setNewTodo(e.target.value)} + placeholder="What needs to be done?" + class="w-full py-4 pl-[60px] pr-4 text-2xl font-light border-none shadow-[inset_0_-2px_1px_rgba(0,0,0,0.03)] box-border" + style={{ + background: `rgba(0, 0, 0, 0.003)`, + }} + /> +
+ + 0}> +
    + + {(todo) => ( +
  • +
    + toggleTodo(todo)} + class="absolute left-[12px] top-0 bottom-0 my-auto h-[40px] w-[40px] cursor-pointer" + /> + + +
    +
  • + )} +
    +
+ +
+ + {activeTodos().length} + {` `} + {activeTodos().length === 1 ? `item` : `items`} left + + 0}> + { + + } + +
+
+
+
+
+ {/* */} + + ) +} diff --git a/examples/solid/todo/src/DevTools.tsx b/examples/solid/todo/src/DevTools.tsx new file mode 100644 index 00000000..2eeb4d18 --- /dev/null +++ b/examples/solid/todo/src/DevTools.tsx @@ -0,0 +1,239 @@ +import { useCollections } from "@tanstack/solid-db" +import { DiffView } from "./DiffView" +import type { Transaction } from "@tanstack/solid-db" +import { createMemo, createSignal, For } from "solid-js" + +export function DevTools() { + const collections = useCollections() + const [selectedCollection, setSelectedCollection] = createSignal< + string | null + >(null) + const [activeTab, setActiveTab] = createSignal<`state` | `transactions`>( + `state` + ) + const [expandedTransactions, setExpandedTransactions] = createSignal< + Set + >(new Set()) + + // Get the selected collection's data + const selectedData = () => + selectedCollection() ? collections().get(selectedCollection) : null + + const collectionsArray = createMemo(() => Array.from(collections())) + const selectedDataArray = createMemo(() => Array.from(selectedData().state)) + const selectedTransactions = createMemo(() => + [...selectedData().transactions.values()].reverse() + ) + + const toggleTransaction = (id: string) => { + setExpandedTransactions((prev) => { + const next = new Set(prev) + if (next.has(id)) { + next.delete(id) + } else { + next.add(id) + } + return next + }) + } + + return ( +
+ {/* Collections List */} +
+
+

Collections

+
+
+ + {([id, { state }]) => ( + + )} + +
+
+ + {/* Collection Details */} +
+ {selectedCollection ? ( + <> +
+
+

+ Collection: {selectedCollection()} +

+
+ + +
+
+
+
+ {activeTab() === `state` && selectedData() ? ( + + + + + + + + + + {([key, value]) => ( + + + + + )} + + +
+ Key + + Value +
+ {key} + + {JSON.stringify(value, null, 2)} +
+ ) : activeTab() === `transactions` && selectedData() ? ( + + + + + + + + + + + + + {(transaction: Transaction) => ( + <> + toggleTransaction(transaction.id)} + > + + + + + + + {expandedTransactions().has(transaction.id) && ( + + + + )} + + )} + + +
+ Time + + ID + + State + + Mutations +
+ + {expandedTransactions().has(transaction.id) + ? `▼` + : `▶`} + + + {new Date( + transaction.createdAt + ).toLocaleTimeString()} + + {transaction.id.slice(0, 8)}... + + + {transaction.state} + + + {transaction.mutations.length} mutation + {transaction.mutations.length !== 1 ? `s` : ``} +
+
+ + {(mutation) => ( +
+
+ + {mutation.type} + + + key: {mutation.key} + +
+ +
+ )} +
+
+
+ ) : null} +
+ + ) : ( +
+ Select a collection to view details +
+ )} +
+
+ ) +} diff --git a/examples/solid/todo/src/DiffView.tsx b/examples/solid/todo/src/DiffView.tsx new file mode 100644 index 00000000..16cb8db3 --- /dev/null +++ b/examples/solid/todo/src/DiffView.tsx @@ -0,0 +1,35 @@ +import { diffLines } from "diff" +import { For } from "solid-js" + +interface DiffViewProps { + oldValue: unknown + newValue: unknown +} + +export function DiffView({ oldValue, newValue }: DiffViewProps) { + const diff = diffLines( + JSON.stringify(oldValue, null, 2), + JSON.stringify(newValue, null, 2) + ) + + return ( +
+      
+        {(part) => (
+          
+ {part.added ? `+ ` : part.removed ? `- ` : ` `} + {part.value} +
+ )} +
+
+ ) +} diff --git a/examples/solid/todo/src/api/server.ts b/examples/solid/todo/src/api/server.ts new file mode 100644 index 00000000..0e94c3d7 --- /dev/null +++ b/examples/solid/todo/src/api/server.ts @@ -0,0 +1,303 @@ +import express from "express" +import cors from "cors" +import { sql } from "../db/postgres" +import { + validateInsertConfig, + validateInsertTodo, + validateUpdateConfig, + validateUpdateTodo, +} from "../db/validation" + +// Create Express app +const app = express() +const PORT = process.env.PORT || 3001 + +// Middleware +app.use(cors()) +app.use(express.json()) + +// Health check endpoint +app.get(`/api/health`, (req, res) => { + res.status(200).json({ status: `ok` }) +}) + +// Generate a transaction ID +async function generateTxId(tx: any): Promise { + const [{ txid }] = await tx`SELECT txid_current() as txid` + return Number(txid) +} + +// ===== TODOS API ===== + +// GET all todos +app.get(`/api/todos`, async (req, res) => { + try { + const todos = await sql`SELECT * FROM todos` + res.status(200).json(todos) + } catch (error) { + console.error(`Error fetching todos:`, error) + res.status(500).json({ + error: `Failed to fetch todos`, + details: error instanceof Error ? error.message : String(error), + }) + } +}) + +// GET a single todo by ID +app.get(`/api/todos/:id`, async (req, res) => { + try { + const { id } = req.params + const [todo] = await sql`SELECT * FROM todos WHERE id = ${id}` + + if (!todo) { + return res.status(404).json({ error: `Todo not found` }) + } + + res.status(200).json(todo) + } catch (error) { + console.error(`Error fetching todo:`, error) + res.status(500).json({ + error: `Failed to fetch todo`, + details: error instanceof Error ? error.message : String(error), + }) + } +}) + +// POST create a new todo +app.post(`/api/todos`, async (req, res) => { + try { + const todoData = validateInsertTodo(req.body) + + let txid: number + const newTodo = await sql.begin(async (tx) => { + txid = await generateTxId(tx) + + const [result] = await tx` + INSERT INTO todos ${tx(todoData)} + RETURNING * + ` + return result + }) + + res.status(201).json({ todo: newTodo, txid }) + } catch (error) { + console.error(`Error creating todo:`, error) + res.status(500).json({ + error: `Failed to create todo`, + details: error instanceof Error ? error.message : String(error), + }) + } +}) + +// PUT update a todo +app.put(`/api/todos/:id`, async (req, res) => { + try { + const { id } = req.params + const todoData = validateUpdateTodo(req.body) + + let txid: number + const updatedTodo = await sql.begin(async (tx) => { + txid = await generateTxId(tx) + + const [result] = await tx` + UPDATE todos + SET ${tx(todoData)} + WHERE id = ${id} + RETURNING * + ` + + if (!result) { + throw new Error(`Todo not found`) + } + + return result + }) + + res.status(200).json({ todo: updatedTodo, txid }) + } catch (error) { + if (error instanceof Error && error.message === `Todo not found`) { + return res.status(404).json({ error: `Todo not found` }) + } + + console.error(`Error updating todo:`, error) + res.status(500).json({ + error: `Failed to update todo`, + details: error instanceof Error ? error.message : String(error), + }) + } +}) + +// DELETE a todo +app.delete(`/api/todos/:id`, async (req, res) => { + try { + const { id } = req.params + + let txid: number + await sql.begin(async (tx) => { + txid = await generateTxId(tx) + + const [result] = await tx` + DELETE FROM todos + WHERE id = ${id} + RETURNING id + ` + + if (!result) { + throw new Error(`Todo not found`) + } + }) + + res.status(200).json({ success: true, txid }) + } catch (error) { + if (error instanceof Error && error.message === `Todo not found`) { + return res.status(404).json({ error: `Todo not found` }) + } + + console.error(`Error deleting todo:`, error) + res.status(500).json({ + error: `Failed to delete todo`, + details: error instanceof Error ? error.message : String(error), + }) + } +}) + +// ===== CONFIG API ===== + +// GET all config entries +app.get(`/api/config`, async (req, res) => { + try { + const config = await sql`SELECT * FROM config` + res.status(200).json(config) + } catch (error) { + console.error(`Error fetching config:`, error) + res.status(500).json({ + error: `Failed to fetch config`, + details: error instanceof Error ? error.message : String(error), + }) + } +}) + +// GET a single config by ID +app.get(`/api/config/:id`, async (req, res) => { + try { + const { id } = req.params + const [config] = await sql`SELECT * FROM config WHERE id = ${id}` + + if (!config) { + return res.status(404).json({ error: `Config not found` }) + } + + res.status(200).json(config) + } catch (error) { + console.error(`Error fetching config:`, error) + res.status(500).json({ + error: `Failed to fetch config`, + details: error instanceof Error ? error.message : String(error), + }) + } +}) + +// POST create a new config +app.post(`/api/config`, async (req, res) => { + try { + const configData = validateInsertConfig(req.body) + + let txid: number + const newConfig = await sql.begin(async (tx) => { + txid = await generateTxId(tx) + + const [result] = await tx` + INSERT INTO config ${tx(configData)} + RETURNING * + ` + return result + }) + + res.status(201).json({ config: newConfig, txid }) + } catch (error) { + console.error(`Error creating config:`, error) + res.status(500).json({ + error: `Failed to create config`, + details: error instanceof Error ? error.message : String(error), + }) + } +}) + +// PUT update a config +app.put(`/api/config/:id`, async (req, res) => { + try { + const { id } = req.params + const configData = validateUpdateConfig(req.body) + + let txid: number + const updatedConfig = await sql.begin(async (tx) => { + txid = await generateTxId(tx) + + const [result] = await tx` + UPDATE config + SET ${tx(configData)} + WHERE id = ${id} + RETURNING * + ` + + if (!result) { + throw new Error(`Config not found`) + } + + return result + }) + + res.status(200).json({ config: updatedConfig, txid }) + } catch (error) { + if (error instanceof Error && error.message === `Config not found`) { + return res.status(404).json({ error: `Config not found` }) + } + + console.error(`Error updating config:`, error) + res.status(500).json({ + error: `Failed to update config`, + details: error instanceof Error ? error.message : String(error), + }) + } +}) + +// DELETE a config +app.delete(`/api/config/:id`, async (req, res) => { + try { + const { id } = req.params + + let txid: number + await sql.begin(async (tx) => { + txid = await generateTxId(tx) + + const [result] = await tx` + DELETE FROM config + WHERE id = ${id} + RETURNING id + ` + + if (!result) { + throw new Error(`Config not found`) + } + }) + + res.status(200).json({ success: true, txid }) + } catch (error) { + if (error instanceof Error && error.message === `Config not found`) { + return res.status(404).json({ error: `Config not found` }) + } + + console.error(`Error deleting config:`, error) + res.status(500).json({ + error: `Failed to delete config`, + details: error instanceof Error ? error.message : String(error), + }) + } +}) + +// Start server +app.listen(PORT, () => { + console.log(`Server running on port ${PORT}`) +}) + +export default app diff --git a/examples/solid/todo/src/api/write-to-pg.ts b/examples/solid/todo/src/api/write-to-pg.ts new file mode 100644 index 00000000..7c9bab11 --- /dev/null +++ b/examples/solid/todo/src/api/write-to-pg.ts @@ -0,0 +1,106 @@ +import type postgres from "postgres" +import type { PendingMutation } from "../types" + +/** + * Get the table name from the relation metadata + */ +function getTableName(relation?: Array): string { + if (!relation || relation.length < 2) { + throw new Error(`could not find the table name`) + } + + // The table name is typically the second element in the relation array + // e.g. ['public', 'todos'] -> 'todos' + return relation[1] +} + +/** + * Process an array of PendingMutations and write to the database + */ +export async function processMutations( + sql: postgres.Sql>, + pendingMutations: Array +): Promise { + return await sql.begin(async (tx) => { + // Get the transaction ID + const [{ txid }] = await tx`SELECT txid_current() as txid` + + // Process each mutation in order + for (const mutation of pendingMutations) { + // Get the table name from the relation metadata + const tableName = getTableName( + mutation.syncMetadata.relation as Array | undefined + ) + + // Get the primary key columns from metadata + const primaryKey = (mutation.syncMetadata.primaryKey as + | Array + | undefined) || [`id`] + + // Process based on operation type + switch (mutation.type) { + case `insert`: { + const columns = Object.keys(mutation.modified) + const values = Object.values(mutation.modified) + const placeholders = values.map((_, i) => `$${i + 1}`).join(`, `) + + await tx.unsafe( + `INSERT INTO ${tableName} (${columns.join(`, `)}) VALUES (${placeholders})`, + values + ) + break + } + + case `update`: { + // Build SET clause + const setColumns = Object.keys(mutation.changes) + const setValues = Object.values(mutation.changes) + const setClause = setColumns + .map((col, i) => `${col} = $${i + 1}`) + .join(`, `) + + // Build WHERE clause for primary key columns starting after SET values + const whereClause = primaryKey + .map((column, i) => `${column} = $${i + setValues.length + 1}`) + .join(` AND `) + + // Combine all values + const allValues = [ + ...setValues, + ...primaryKey.map((k) => mutation.original[k]), + ] + + await tx.unsafe( + `UPDATE ${tableName} + SET ${setClause} + WHERE ${whereClause}`, + allValues + ) + break + } + + case `delete`: { + // Build WHERE clause for primary key columns + const whereClause = primaryKey + .map((column, i) => `${column} = $${i + 1}`) + .join(` AND `) + + // Extract primary key values in same order as columns + const primaryKeyValues = primaryKey.map((k) => mutation.original[k]) + + await tx.unsafe( + `DELETE FROM ${tableName} + WHERE ${whereClause}`, + primaryKeyValues + ) + break + } + + default: + throw new Error(`Unknown operation type: ${mutation.type}`) + } + } + + return Number(txid) + }) +} diff --git a/examples/solid/todo/src/assets/react.svg b/examples/solid/todo/src/assets/react.svg new file mode 100644 index 00000000..6c87de9b --- /dev/null +++ b/examples/solid/todo/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/solid/todo/src/db/index.ts b/examples/solid/todo/src/db/index.ts new file mode 100644 index 00000000..5a856e69 --- /dev/null +++ b/examples/solid/todo/src/db/index.ts @@ -0,0 +1,15 @@ +import { drizzle } from "drizzle-orm/node-postgres" +import { Pool } from "pg" +import * as schema from "./schema" + +// Create a PostgreSQL pool +const pool = new Pool({ + host: process.env.DB_HOST || `localhost`, + port: parseInt(process.env.DB_PORT || `5432`), + user: process.env.DB_USER || `postgres`, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME || `todo_app`, +}) + +// Create drizzle database instance +export const db = drizzle(pool, { schema }) diff --git a/examples/solid/todo/src/db/postgres.ts b/examples/solid/todo/src/db/postgres.ts new file mode 100644 index 00000000..67434843 --- /dev/null +++ b/examples/solid/todo/src/db/postgres.ts @@ -0,0 +1,10 @@ +import postgres from "postgres" + +// Create a postgres instance +export const sql = postgres({ + host: `localhost`, + port: 54322, + user: `postgres`, + password: `postgres`, + database: `todo_app`, +}) diff --git a/examples/solid/todo/src/db/schema.ts b/examples/solid/todo/src/db/schema.ts new file mode 100644 index 00000000..4bf9e0d0 --- /dev/null +++ b/examples/solid/todo/src/db/schema.ts @@ -0,0 +1,31 @@ +import { boolean, pgTable, serial, text, timestamp } from "drizzle-orm/pg-core" + +export const todos = pgTable(`todos`, { + id: serial(`id`).primaryKey(), + text: text(`text`).notNull(), + completed: boolean(`completed`).notNull().default(false), + created_at: timestamp(`created_at`, { withTimezone: true }) + .defaultNow() + .notNull(), + updated_at: timestamp(`updated_at`, { withTimezone: true }) + .notNull() + .defaultNow(), +}) + +export type Todo = typeof todos.$inferSelect +export type NewTodo = typeof todos.$inferInsert + +export const config = pgTable(`config`, { + id: serial(`id`).primaryKey(), + key: text(`key`).notNull().unique(), + value: text(`value`).notNull(), + created_at: timestamp(`created_at`, { withTimezone: true }) + .notNull() + .defaultNow(), + updated_at: timestamp(`updated_at`, { withTimezone: true }) + .notNull() + .defaultNow(), +}) + +export type Config = typeof config.$inferSelect +export type NewConfig = typeof config.$inferInsert diff --git a/examples/solid/todo/src/db/validation.ts b/examples/solid/todo/src/db/validation.ts new file mode 100644 index 00000000..1fc244b5 --- /dev/null +++ b/examples/solid/todo/src/db/validation.ts @@ -0,0 +1,77 @@ +import { createInsertSchema, createSelectSchema } from "drizzle-zod" +import { config, todos } from "./schema" +import type { z } from "zod" + +// Auto-generated schemas from Drizzle schema +export const insertTodoSchema = createInsertSchema(todos) +export const selectTodoSchema = createSelectSchema(todos) + +// Partial schema for updates +export const updateTodoSchema = insertTodoSchema.partial().strict() + +// Config schemas +export const insertConfigSchema = createInsertSchema(config).strict() +export const selectConfigSchema = createSelectSchema(config) +export const updateConfigSchema = insertConfigSchema.partial().strict() + +// Type inference +export type InsertTodo = z.infer +export type SelectTodo = z.infer +export type UpdateTodo = z.infer + +export type InsertConfig = z.infer +export type SelectConfig = z.infer +export type UpdateConfig = z.infer + +// Validation functions +export const validateInsertTodo = (data: unknown): InsertTodo => { + if (data.text === `really hard todo`) { + throw new Error(`we don't want to do really hard todos`) + } + return insertTodoSchema.parse(data) +} + +export const validateSelectTodo = (data: unknown): SelectTodo => { + return selectTodoSchema.parse(data) +} + +export const validateUpdateTodo = (data: unknown): UpdateTodo => { + return updateTodoSchema.parse(data) +} + +export const validateInsertConfig = (data: unknown): InsertConfig => { + return insertConfigSchema.parse(data) +} + +export const validateSelectConfig = (data: unknown): SelectConfig => { + return selectConfigSchema.parse(data) +} + +export const validateUpdateConfig = (data: unknown): UpdateConfig => { + return updateConfigSchema.parse(data) +} + +// Safe parsing functions that return Result type instead of throwing +export const safeParseInsertTodo = (data: unknown) => { + return insertTodoSchema.safeParse(data) +} + +export const safeParseSelectTodo = (data: unknown) => { + return selectTodoSchema.safeParse(data) +} + +export const safeParseUpdateTodo = (data: unknown) => { + return updateTodoSchema.safeParse(data) +} + +export const safeParseInsertConfig = (data: unknown) => { + return insertConfigSchema.safeParse(data) +} + +export const safeParseSelectConfig = (data: unknown) => { + return selectConfigSchema.safeParse(data) +} + +export const safeParseUpdateConfig = (data: unknown) => { + return updateConfigSchema.safeParse(data) +} diff --git a/examples/solid/todo/src/index.css b/examples/solid/todo/src/index.css new file mode 100644 index 00000000..5211a041 --- /dev/null +++ b/examples/solid/todo/src/index.css @@ -0,0 +1,94 @@ +@import "tailwindcss"; + +html, +body { + margin: 0; + padding: 0; +} + +button { + margin: 0; + padding: 0; + border: 0; + background: none; + font-size: 100%; + vertical-align: baseline; + font-family: inherit; + font-weight: inherit; + color: inherit; + appearance: none; +} + +body { + font: + 14px "Helvetica Neue", + Helvetica, + Arial, + sans-serif; + line-height: 1.4em; + background: #f5f5f5; + color: #4d4d4d; + margin: 0 auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-weight: 300; +} + +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/examples/solid/todo/src/main.tsx b/examples/solid/todo/src/main.tsx new file mode 100644 index 00000000..b9657f95 --- /dev/null +++ b/examples/solid/todo/src/main.tsx @@ -0,0 +1,8 @@ +/* @refresh reload */ +import { render } from "solid-js/web" +import "./index.css" +import App from "./App.tsx" + +const root = document.getElementById("root") + +render(() => , root!) diff --git a/examples/solid/todo/src/vite-env.d.ts b/examples/solid/todo/src/vite-env.d.ts new file mode 100644 index 00000000..11f02fe2 --- /dev/null +++ b/examples/solid/todo/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/examples/solid/todo/tsconfig.app.json b/examples/solid/todo/tsconfig.app.json new file mode 100644 index 00000000..9a0b51fd --- /dev/null +++ b/examples/solid/todo/tsconfig.app.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/examples/solid/todo/tsconfig.json b/examples/solid/todo/tsconfig.json new file mode 100644 index 00000000..1ffef600 --- /dev/null +++ b/examples/solid/todo/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/examples/solid/todo/tsconfig.node.json b/examples/solid/todo/tsconfig.node.json new file mode 100644 index 00000000..9728af2d --- /dev/null +++ b/examples/solid/todo/tsconfig.node.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/examples/solid/todo/vite.config.ts b/examples/solid/todo/vite.config.ts new file mode 100644 index 00000000..e5da6e59 --- /dev/null +++ b/examples/solid/todo/vite.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vite" +import solid from "vite-plugin-solid" +import tailwindcss from "@tailwindcss/vite" + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [tailwindcss(), solid()], +}) diff --git a/packages/solid-db/CHANGELOG.md b/packages/solid-db/CHANGELOG.md new file mode 100644 index 00000000..e89c1c65 --- /dev/null +++ b/packages/solid-db/CHANGELOG.md @@ -0,0 +1,4 @@ +# @tanstack/solid-db + +## 0.0.3 + diff --git a/packages/solid-db/README.md b/packages/solid-db/README.md new file mode 100644 index 00000000..0389247e --- /dev/null +++ b/packages/solid-db/README.md @@ -0,0 +1,3 @@ +# @tanstack/solid-db + +Solid hooks for TanStack DB. See [TanStack/db](https://github.com/TanStack/db) for more details. diff --git a/packages/solid-db/package.json b/packages/solid-db/package.json new file mode 100644 index 00000000..c4c61586 --- /dev/null +++ b/packages/solid-db/package.json @@ -0,0 +1,60 @@ +{ + "name": "@tanstack/solid-db", + "description": "Solid integration for @tanstack/db", + "version": "0.0.2", + "author": "Kyle Mathews", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/TanStack/db.git", + "directory": "packages/solid-db" + }, + "homepage": "https://tanstack.com/db", + "keywords": [ + "optimistic", + "solid", + "typescript" + ], + "packageManager": "pnpm@10.6.3", + "dependencies": { + "@tanstack/db": "workspace:*" + }, + "devDependencies": { + "@electric-sql/client": "1.0.0", + "@solidjs/testing-library": "^0.8.10", + "@vitest/coverage-istanbul": "^3.0.9", + "solid-js": "^1.9.4", + "vite-plugin-solid": "^2.11.6" + }, + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.cts", + "default": "./dist/cjs/index.cjs" + } + }, + "./package.json": "./package.json" + }, + "files": [ + "dist", + "src" + ], + "main": "dist/cjs/index.cjs", + "module": "dist/esm/index.js", + "peerDependencies": { + "solid-js": ">=1.8.0" + }, + "scripts": { + "build": "vite build", + "dev": "vite build --watch", + "test": "npx vitest --run", + "lint": "eslint . --fix" + }, + "sideEffects": false, + "type": "module", + "types": "dist/esm/index.d.ts" +} \ No newline at end of file diff --git a/packages/solid-db/src/index.ts b/packages/solid-db/src/index.ts new file mode 100644 index 00000000..e5e496ce --- /dev/null +++ b/packages/solid-db/src/index.ts @@ -0,0 +1,10 @@ +// Re-export all public APIs +export * from "./useOptimisticMutation" +export * from "./useLiveQuery" + +// Re-export everything from @tanstack/db +export * from "@tanstack/db" + +// Re-export some stuff explicitly to ensure the type & value is exported +export { Collection } from "@tanstack/db" +export { createTransaction } from "@tanstack/db" diff --git a/packages/solid-db/src/useLiveQuery.ts b/packages/solid-db/src/useLiveQuery.ts new file mode 100644 index 00000000..6cd3ef08 --- /dev/null +++ b/packages/solid-db/src/useLiveQuery.ts @@ -0,0 +1,84 @@ +import { compileQuery, queryBuilder } from "@tanstack/db" +import { createComputed, createMemo, onCleanup } from "solid-js" +import { createStore, reconcile } from "solid-js/store" +import type { Accessor } from "solid-js" +import type { + Collection, + Context, + InitialQueryBuilder, + QueryBuilder, + ResultsFromContext, + Schema, +} from "@tanstack/db" + +export interface UseLiveQueryReturn { + state: Accessor> + data: Accessor> + collection: Accessor> +} + +export function useLiveQuery< + TResultContext extends Context = Context, +>( + queryFn: ( + q: InitialQueryBuilder> + ) => QueryBuilder +): UseLiveQueryReturn> { + const compiledQuery = createMemo( + () => { + const compiled = compileQuery(queryFn(queryBuilder())) + const unsubCompiled = compiled.start() + + onCleanup(() => { + unsubCompiled() + }) + + return compiled + }, + undefined, + { name: `TanstackDBCompiledQueryMemo` } + ) + + const [state, setState] = createStore({ + value: compiledQuery().results.derivedState.state, + }) + + createComputed( + () => { + setState({ value: compiledQuery().results.derivedState.state }) + const unsub = compiledQuery().results.derivedState.subscribe((v) => { + setState({ value: reconcile(v.currentVal)(v.prevVal) }) + }) + + onCleanup(() => { + unsub() + }) + }, + undefined, + { name: `TanstackDBStateComputed` } + ) + + const [data, setData] = createStore( + compiledQuery().results.derivedArray.state + ) + createComputed( + () => { + setData(compiledQuery().results.derivedArray.state) + const unsub = compiledQuery().results.derivedArray.subscribe((v) => { + setData(reconcile(v.currentVal)(v.prevVal)) + }) + + onCleanup(() => { + unsub() + }) + }, + undefined, + { name: `TanstackDBDataComputed` } + ) + + return { + state: () => state.value, + data: () => data, + collection: () => compiledQuery().results, + } +} diff --git a/packages/solid-db/src/useOptimisticMutation.ts b/packages/solid-db/src/useOptimisticMutation.ts new file mode 100644 index 00000000..c8b1b84f --- /dev/null +++ b/packages/solid-db/src/useOptimisticMutation.ts @@ -0,0 +1,15 @@ +import { createTransaction } from "@tanstack/db" +import type { Transaction, TransactionConfig } from "@tanstack/db" + +export function useOptimisticMutation(config: TransactionConfig) { + return { + mutate: (callback: () => void): Transaction => { + const transaction = createTransaction(config) + transaction.mutate(callback) + return transaction + }, + createTransaction: (): Transaction => { + return createTransaction({ ...config, autoCommit: false }) + }, + } +} diff --git a/packages/solid-db/tests/test-setup.ts b/packages/solid-db/tests/test-setup.ts new file mode 100644 index 00000000..9b279c46 --- /dev/null +++ b/packages/solid-db/tests/test-setup.ts @@ -0,0 +1,6 @@ +import "@testing-library/jest-dom/vitest" +import { cleanup } from "@solidjs/testing-library" +import { afterEach } from "vitest" + +// https://testing-library.com/docs/solid-testing-library/api/#cleanup +afterEach(() => cleanup()) diff --git a/packages/solid-db/tests/useLiveQuery.test.tsx b/packages/solid-db/tests/useLiveQuery.test.tsx new file mode 100644 index 00000000..65a8ccfa --- /dev/null +++ b/packages/solid-db/tests/useLiveQuery.test.tsx @@ -0,0 +1,801 @@ +import { describe, expect, it } from "vitest" +import mitt from "mitt" +import { renderHook } from "@solidjs/testing-library" +import { Collection, createTransaction } from "@tanstack/db" +import { createEffect, createRoot, createSignal } from "solid-js" +import { useLiveQuery } from "../src/useLiveQuery" +import type { Accessor } from "solid-js" +import type { PendingMutation } from "@tanstack/db" + +type Person = { + id: string + name: string + age: number + email: string + isActive: boolean + team: string +} + +type Issue = { + id: string + title: string + description: string + userId: string +} + +const initialPersons: Array = [ + { + id: `1`, + name: `John Doe`, + age: 30, + email: `john.doe@example.com`, + isActive: true, + team: `team1`, + }, + { + id: `2`, + name: `Jane Doe`, + age: 25, + email: `jane.doe@example.com`, + isActive: true, + team: `team2`, + }, + { + id: `3`, + name: `John Smith`, + age: 35, + email: `john.smith@example.com`, + isActive: true, + team: `team1`, + }, +] + +const initialIssues: Array = [ + { + id: `1`, + title: `Issue 1`, + description: `Issue 1 description`, + userId: `1`, + }, + { + id: `2`, + title: `Issue 2`, + description: `Issue 2 description`, + userId: `2`, + }, + { + id: `3`, + title: `Issue 3`, + description: `Issue 3 description`, + userId: `1`, + }, +] + +describe(`Query Collections`, () => { + it(`should be able to query a collection`, () => + createRoot((dispose) => { + const emitter = mitt() + + // Create collection with mutation capability + const collection = new Collection({ + id: `optimistic-changes-test`, + sync: { + sync: ({ begin, write, commit }) => { + // Listen for sync events + emitter.on(`*`, (_, changes) => { + begin() + ;(changes as Array).forEach((change) => { + write({ + key: change.key, + type: change.type, + value: change.changes as Person, + }) + }) + commit() + }) + }, + }, + }) + + // Sync from initial state + emitter.emit( + `sync`, + initialPersons.map((person) => ({ + key: person.id, + type: `insert`, + changes: person, + })) + ) + + const { result } = renderHook(() => { + return useLiveQuery((q) => + q + .from({ collection }) + .where(`@age`, `>`, 30) + .keyBy(`@id`) + .select(`@id`, `@name`) + .orderBy({ "@id": `asc` }) + ) + }) + + expect(result.state().size).toBe(1) + expect(result.state().get(`3`)).toEqual({ + _orderByIndex: 0, + id: `3`, + name: `John Smith`, + }) + + expect(result.data().length).toBe(1) + expect(result.data()[0]).toEqual({ + _orderByIndex: 0, + id: `3`, + name: `John Smith`, + }) + + // Insert a new person + emitter.emit(`sync`, [ + { + key: `4`, + type: `insert`, + changes: { + id: `4`, + name: `Kyle Doe`, + age: 40, + email: `kyle.doe@example.com`, + isActive: true, + }, + }, + ]) + + expect(result.state().size).toBe(2) + expect(result.state().get(`3`)).toEqual({ + _orderByIndex: 0, + id: `3`, + name: `John Smith`, + }) + expect(result.state().get(`4`)).toEqual({ + _orderByIndex: 1, + id: `4`, + name: `Kyle Doe`, + }) + + expect(result.data().length).toBe(2) + expect(result.data()).toContainEqual({ + _orderByIndex: 0, + id: `3`, + name: `John Smith`, + }) + expect(result.data()).toContainEqual({ + _orderByIndex: 1, + id: `4`, + name: `Kyle Doe`, + }) + + // Update the person + emitter.emit(`sync`, [ + { + key: `4`, + type: `update`, + changes: { + name: `Kyle Doe 2`, + }, + }, + ]) + + expect(result.state().size).toBe(2) + expect(result.state().get(`4`)).toEqual({ + _orderByIndex: 1, + id: `4`, + name: `Kyle Doe 2`, + }) + + expect(result.data().length).toBe(2) + expect(result.data()).toContainEqual({ + _orderByIndex: 1, + id: `4`, + name: `Kyle Doe 2`, + }) + + // Delete the person + emitter.emit(`sync`, [ + { + key: `4`, + type: `delete`, + }, + ]) + + expect(result.state().size).toBe(1) + expect(result.state().get(`4`)).toBeUndefined() + + expect(result.data().length).toBe(1) + expect(result.data()).toContainEqual({ + _orderByIndex: 0, + id: `3`, + name: `John Smith`, + }) + + dispose() + })) + + it(`should join collections and return combined results`, () => + createRoot((dispose) => { + const emitter = mitt() + + // Create person collection + const personCollection = new Collection({ + id: `person-collection-test`, + sync: { + sync: ({ begin, write, commit }) => { + emitter.on(`sync-person`, (changes) => { + begin() + ;(changes as Array).forEach((change) => { + write({ + key: change.key, + type: change.type, + value: change.changes as Person, + }) + }) + commit() + }) + }, + }, + }) + + // Create issue collection + const issueCollection = new Collection({ + id: `issue-collection-test`, + sync: { + sync: ({ begin, write, commit }) => { + emitter.on(`sync-issue`, (changes) => { + begin() + ;(changes as Array).forEach((change) => { + write({ + key: change.key, + type: change.type, + value: change.changes as Issue, + }) + }) + commit() + }) + }, + }, + }) + + // Sync initial person data + emitter.emit( + `sync-person`, + initialPersons.map((person) => ({ + key: person.id, + type: `insert`, + changes: person, + })) + ) + + // Sync initial issue data + emitter.emit( + `sync-issue`, + initialIssues.map((issue) => ({ + key: issue.id, + type: `insert`, + changes: issue, + })) + ) + + const { result } = renderHook(() => { + return useLiveQuery((q) => + q + .from({ issues: issueCollection }) + .join({ + type: `inner`, + from: { persons: personCollection }, + on: [`@persons.id`, `=`, `@issues.userId`], + }) + .select(`@issues.id`, `@issues.title`, `@persons.name`) + .keyBy(`@id`) + ) + }) + + // Verify that we have the expected joined results + expect(result.state().size).toBe(3) + + expect(result.state().get(`1`)).toEqual({ + id: `1`, + name: `John Doe`, + title: `Issue 1`, + }) + + expect(result.state().get(`2`)).toEqual({ + id: `2`, + name: `Jane Doe`, + title: `Issue 2`, + }) + + expect(result.state().get(`3`)).toEqual({ + id: `3`, + name: `John Doe`, + title: `Issue 3`, + }) + + // Add a new issue for user 1 + emitter.emit(`sync-issue`, [ + { + key: `4`, + type: `insert`, + changes: { + id: `4`, + title: `Issue 4`, + description: `Issue 4 description`, + userId: `2`, + }, + }, + ]) + + expect(result.state().size).toBe(4) + expect(result.state().get(`4`)).toEqual({ + id: `4`, + name: `Jane Doe`, + title: `Issue 4`, + }) + + // Update an issue we're already joined with + emitter.emit(`sync-issue`, [ + { + key: `2`, + type: `update`, + changes: { + title: `Updated Issue 2`, + }, + }, + ]) + + // The updated title should be reflected in the joined results + expect(result.state().get(`2`)).toEqual({ + id: `2`, + name: `Jane Doe`, + title: `Updated Issue 2`, + }) + + // Delete an issue + emitter.emit(`sync-issue`, [ + { + key: `3`, + type: `delete`, + }, + ]) + + // After deletion, user 3 should no longer have a joined result + expect(result.state().get(`3`)).toBeUndefined() + + dispose() + })) + + it(`should recompile query when parameters change and change results`, () => + createRoot((dispose) => { + const emitter = mitt() + + // Create collection with mutation capability + const collection = new Collection({ + id: `params-change-test`, + sync: { + sync: ({ begin, write, commit }) => { + // Listen for sync events + emitter.on(`sync`, (changes) => { + begin() + ;(changes as Array).forEach((change) => { + write({ + key: change.key, + type: change.type, + value: change.changes as Person, + }) + }) + commit() + }) + }, + }, + }) + + // Sync from initial state + emitter.emit( + `sync`, + initialPersons.map((person) => ({ + key: person.id, + type: `insert`, + changes: person, + })) + ) + + const [minAge, setMinAge] = createSignal(30) + const { result } = renderHook( + (props: { minAge: Accessor }) => { + return useLiveQuery((q) => + q + .from({ collection }) + .where(`@age`, `>`, props.minAge()) + .keyBy(`@id`) + .select(`@id`, `@name`, `@age`) + ) + }, + { initialProps: [{ minAge: minAge }] } + ) + + // Initially should return only people older than 30 + expect(result.state().size).toBe(1) + expect(result.state().get(`3`)).toEqual({ + id: `3`, + name: `John Smith`, + age: 35, + }) + + // Change the parameter to include more people + setMinAge(20) + + // Now should return all people as they're all older than 20 + expect(result.state().size).toBe(3) + expect(result.state().get(`1`)).toEqual({ + id: `1`, + name: `John Doe`, + age: 30, + }) + expect(result.state().get(`2`)).toEqual({ + id: `2`, + name: `Jane Doe`, + age: 25, + }) + expect(result.state().get(`3`)).toEqual({ + id: `3`, + name: `John Smith`, + age: 35, + }) + + // Change to exclude everyone + setMinAge(50) + + // Should now be empty + expect(result.state().size).toBe(0) + + dispose() + })) + + it(`should stop old query when parameters change`, () => + createRoot((dispose) => { + const emitter = mitt() + + // Create collection with mutation capability + const collection = new Collection({ + id: `stop-query-test`, + sync: { + sync: ({ begin, write, commit }) => { + emitter.on(`sync`, (changes) => { + begin() + ;(changes as Array).forEach((change) => { + write({ + key: change.key, + type: change.type, + value: change.changes as Person, + }) + }) + commit() + }) + }, + }, + }) + + // Sync initial state + emitter.emit( + `sync`, + initialPersons.map((person) => ({ + key: person.id, + type: `insert`, + changes: person, + })) + ) + + const [minAge, setMinAge] = createSignal(30, { name: `MinAge` }) + const { owner } = renderHook( + (props: { minAge: Accessor }) => { + return useLiveQuery((q) => + q + .from({ collection }) + .where(`@age`, `>`, props.minAge()) + .keyBy(`@id`) + .select(`@id`, `@name`) + ) + }, + { initialProps: [{ minAge }] } + ) + + function getMinAgeFromUseLiveQueryOwner() { + return owner?.owned + ?.find((o) => o.name === `TanstackDBCompiledQueryMemo`) + ?.sources?.find((s) => s.name === `MinAge`)?.value + } + + const initialMinAge = getMinAgeFromUseLiveQueryOwner() + expect(initialMinAge).toBe(30) + + // Change the parameter + setMinAge(25) + + // Old query should be stopped and new query created + const updatedMinAge = getMinAgeFromUseLiveQueryOwner() + expect(updatedMinAge).toBe(25) + + dispose() + })) + + it(`should be able to query a result collection`, () => + createRoot((dispose) => { + const emitter = mitt() + + // Create collection with mutation capability + const collection = new Collection({ + id: `optimistic-changes-test`, + sync: { + sync: ({ begin, write, commit }) => { + // Listen for sync events + emitter.on(`*`, (_, changes) => { + begin() + ;(changes as Array).forEach((change) => { + write({ + key: change.key, + type: change.type, + value: change.changes as Person, + }) + }) + commit() + }) + }, + }, + }) + + // Sync from initial state + emitter.emit( + `sync`, + initialPersons.map((person) => ({ + key: person.id, + type: `insert`, + changes: person, + })) + ) + + // Initial query + const { result } = renderHook(() => { + return useLiveQuery((q) => + q + .from({ collection }) + .where(`@age`, `>`, 30) + .keyBy(`@id`) + .select(`@id`, `@name`, `@team`) + .orderBy({ "@id": `asc` }) + ) + }) + + // Grouped query derived from initial query + const { result: groupedResult } = renderHook(() => { + return useLiveQuery((q) => + q + .from({ queryResult: result.collection() }) + .groupBy(`@team`) + .keyBy(`@team`) + .select(`@team`, { count: { COUNT: `@id` } }) + ) + }) + + // Verify initial grouped results + expect(groupedResult.state().size).toBe(1) + expect(groupedResult.state().get(`team1`)).toEqual({ + team: `team1`, + count: 1, + }) + + // Insert two new users in different teams + emitter.emit(`sync`, [ + { + key: `5`, + type: `insert`, + changes: { + id: `5`, + name: `Sarah Jones`, + age: 32, + email: `sarah.jones@example.com`, + isActive: true, + team: `team1`, + }, + }, + { + key: `6`, + type: `insert`, + changes: { + id: `6`, + name: `Mike Wilson`, + age: 38, + email: `mike.wilson@example.com`, + isActive: true, + team: `team2`, + }, + }, + ]) + + // Verify the grouped results include the new team members + expect(groupedResult.state().size).toBe(2) + expect(groupedResult.state().get(`team1`)).toEqual({ + team: `team1`, + count: 2, + }) + expect(groupedResult.state().get(`team2`)).toEqual({ + team: `team2`, + count: 1, + }) + + dispose() + })) + + it(`optimistic state is dropped after commit`, () => + createRoot((dispose) => { + const emitter = mitt() + // Track renders and states + const renderStates: Array<{ + stateSize: number + hasTempKey: boolean + hasPermKey: boolean + timestamp: number + }> = [] + + // Create person collection + const personCollection = new Collection({ + id: `person-collection-test-bug`, + sync: { + sync: ({ begin, write, commit }) => { + // @ts-expect-error Mitt typing doesn't match our usage + emitter.on(`sync-person`, (changes: Array) => { + begin() + changes.forEach((change) => { + write({ + key: change.key, + type: change.type, + value: change.changes as Person, + }) + }) + commit() + }) + }, + }, + }) + + // Create issue collection + const issueCollection = new Collection({ + id: `issue-collection-test-bug`, + sync: { + sync: ({ begin, write, commit }) => { + // @ts-expect-error Mitt typing doesn't match our usage + emitter.on(`sync-issue`, (changes: Array) => { + begin() + changes.forEach((change) => { + write({ + key: change.key, + type: change.type, + value: change.changes as Issue, + }) + }) + commit() + }) + }, + }, + }) + + // Sync initial person data + emitter.emit( + `sync-person`, + initialPersons.map((person) => ({ + key: person.id, + type: `insert`, + changes: person, + })) + ) + + // Sync initial issue data + emitter.emit( + `sync-issue`, + initialIssues.map((issue) => ({ + key: issue.id, + type: `insert`, + changes: issue, + })) + ) + + // Render the hook with a query that joins persons and issues + const { result } = renderHook(() => { + const queryResult = useLiveQuery((q) => + q + .from({ issues: issueCollection }) + .join({ + type: `inner`, + from: { persons: personCollection }, + on: [`@persons.id`, `=`, `@issues.userId`], + }) + .select(`@issues.id`, `@issues.title`, `@persons.name`) + .keyBy(`@id`) + ) + + // Track each render state + createEffect(() => { + renderStates.push({ + stateSize: queryResult.state().size, + hasTempKey: queryResult.state().has(`temp-key`), + hasPermKey: queryResult.state().has(`4`), + timestamp: Date.now(), + }) + }) + + return queryResult + }) + + // Verify initial state + expect(result.state().size).toBe(3) + + // Reset render states array for clarity in the remaining test + renderStates.length = 0 + + // Create a transaction to perform an optimistic mutation + const tx = createTransaction({ + mutationFn: () => { + emitter.emit(`sync-issue`, [ + { + key: `4`, + type: `insert`, + changes: { + id: `4`, + title: `New Issue`, + description: `New Issue Description`, + userId: `1`, + }, + }, + ]) + return Promise.resolve() + }, + }) + + // Perform optimistic insert of a new issue + tx.mutate(() => + issueCollection.insert( + { + id: `temp-key`, + title: `New Issue`, + description: `New Issue Description`, + userId: `1`, + }, + { key: `temp-key` } + ) + ) + + // Verify optimistic state is immediately reflected + expect(result.state().size).toBe(4) + expect(result.state().get(`temp-key`)).toEqual({ + id: `temp-key`, + name: `John Doe`, + title: `New Issue`, + }) + + // Wait for the transaction to be committed + tx.isPersisted.promise.then(() => { + // Check if we had any render where the temp key was removed but the permanent key wasn't added yet + const hadFlicker = renderStates.some( + (state) => + !state.hasTempKey && !state.hasPermKey && state.stateSize === 3 + ) + + expect(hadFlicker).toBe(false) + + // Verify the temporary key is replaced by the permanent one + expect(result.state().size).toBe(4) + expect(result.state().get(`temp-key`)).toBeUndefined() + expect(result.state().get(`4`)).toEqual({ + id: `4`, + name: `John Doe`, + title: `New Issue`, + }) + }) + + dispose() + })) +}) diff --git a/packages/solid-db/tsconfig.json b/packages/solid-db/tsconfig.json new file mode 100644 index 00000000..fb7b5794 --- /dev/null +++ b/packages/solid-db/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "Bundler", + "declaration": true, + "outDir": "dist", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "jsx": "preserve", + "paths": { + "@tanstack/store": ["../store/src"], + "@tanstack/db": ["../db/src"] + } + }, + "include": ["src/**/*", "tests", "vite.config.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/solid-db/vite.config.ts b/packages/solid-db/vite.config.ts new file mode 100644 index 00000000..8102f8f7 --- /dev/null +++ b/packages/solid-db/vite.config.ts @@ -0,0 +1,25 @@ +import { defineConfig, mergeConfig } from "vitest/config" +import { tanstackViteConfig } from "@tanstack/config/vite" +import solid from "vite-plugin-solid" +import packageJson from "./package.json" + +const config = defineConfig({ + plugins: [solid()], + test: { + name: packageJson.name, + dir: `./tests`, + watch: false, + environment: `jsdom`, + setupFiles: [`./tests/test-setup.ts`], + coverage: { enabled: true, provider: `istanbul`, include: [`src/**/*`] }, + typecheck: { enabled: true }, + }, +}) + +export default mergeConfig( + config, + tanstackViteConfig({ + entry: `./src/index.ts`, + srcDir: `./src`, + }) +) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e69fa5d9..56992bd2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -203,6 +203,82 @@ importers: specifier: ^6.2.2 version: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + examples/solid/todo: + dependencies: + '@tanstack/db-collections': + specifier: workspace:* + version: link:../../../packages/db-collections + '@tanstack/query-core': + specifier: ^5.75.7 + version: 5.75.7 + '@tanstack/solid-db': + specifier: workspace:* + version: link:../../../packages/solid-db + cors: + specifier: ^2.8.5 + version: 2.8.5 + drizzle-orm: + specifier: ^0.40.1 + version: 0.40.1(@types/pg@8.11.11)(gel@2.0.1)(kysely@0.27.6)(pg@8.14.1)(postgres@3.4.5) + drizzle-zod: + specifier: ^0.7.0 + version: 0.7.0(drizzle-orm@0.40.1(@types/pg@8.11.11)(gel@2.0.1)(kysely@0.27.6)(pg@8.14.1)(postgres@3.4.5))(zod@3.24.2) + express: + specifier: ^4.19.2 + version: 4.21.2 + postgres: + specifier: ^3.4.5 + version: 3.4.5 + solid-js: + specifier: ^1.9.4 + version: 1.9.7 + tailwindcss: + specifier: ^4.0.17 + version: 4.0.17 + zod: + specifier: ^3.24.2 + version: 3.24.2 + devDependencies: + '@tailwindcss/vite': + specifier: ^4.0.0-alpha.8 + version: 4.0.14(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + '@types/cors': + specifier: ^2.8.17 + version: 2.8.17 + '@types/express': + specifier: ^4.17.21 + version: 4.17.21 + '@types/node': + specifier: ^22.13.10 + version: 22.13.10 + '@types/pg': + specifier: ^8.11.11 + version: 8.11.11 + concurrently: + specifier: ^9.1.2 + version: 9.1.2 + dotenv: + specifier: ^16.3.1 + version: 16.4.7 + drizzle-kit: + specifier: ^0.30.5 + version: 0.30.5 + pg: + specifier: ^8.14.1 + version: 8.14.1 + tsx: + specifier: ^4.6.2 + version: 4.19.3 + typescript: + specifier: ^5.8.2 + version: 5.8.2 + vite: + specifier: ^6.2.2 + version: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite-plugin-solid: + specifier: ^2.11.6 + version: 2.11.6(@testing-library/jest-dom@6.6.3)(solid-js@1.9.7)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + packages/db: dependencies: '@electric-sql/d2ts': @@ -281,6 +357,28 @@ importers: specifier: ^19.0.0 version: 19.0.0(react@19.0.0) + packages/solid-db: + dependencies: + '@tanstack/db': + specifier: workspace:* + version: link:../db + devDependencies: + '@electric-sql/client': + specifier: 1.0.0 + version: 1.0.0 + '@solidjs/testing-library': + specifier: ^0.8.10 + version: 0.8.10(solid-js@1.9.7) + '@vitest/coverage-istanbul': + specifier: ^3.0.9 + version: 3.0.9(vitest@3.0.9(@types/node@22.13.10)(happy-dom@17.4.4)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + solid-js: + specifier: ^1.9.4 + version: 1.9.7 + vite-plugin-solid: + specifier: ^2.11.6 + version: 2.11.6(@testing-library/jest-dom@6.6.3)(solid-js@1.9.7)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + packages/vue-db: dependencies: '@tanstack/db': @@ -335,6 +433,10 @@ packages: resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.18.6': + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.25.9': resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} @@ -349,6 +451,10 @@ packages: resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.25.9': resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} @@ -375,6 +481,12 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-self@7.25.9': resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} engines: {node: '>=6.9.0'} @@ -1507,6 +1619,16 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@solidjs/testing-library@0.8.10': + resolution: {integrity: sha512-qdeuIerwyq7oQTIrrKvV0aL9aFeuwTd86VYD3afdq5HYEwoox1OBTJy4y8A3TFZr8oAR0nujYgCzY/8wgHGfeQ==} + engines: {node: '>= 14'} + peerDependencies: + '@solidjs/router': '>=0.9.0' + solid-js: '>=1.0.0' + peerDependenciesMeta: + '@solidjs/router': + optional: true + '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -2102,6 +2224,16 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + babel-plugin-jsx-dom-expressions@0.39.8: + resolution: {integrity: sha512-/MVOIIjonylDXnrWmG23ZX82m9mtKATsVHB7zYlPfDR9Vdd/NBE48if+wv27bSkBtyO7EPMUlcUc4J63QwuACQ==} + peerDependencies: + '@babel/core': ^7.20.12 + + babel-preset-solid@1.9.6: + resolution: {integrity: sha512-HXTK9f93QxoH8dYn1M2mJdOlWgMsR88Lg/ul6QCZGkNTktjTE5HAf93YxQumHoCudLEtZrU1cFCMFOVho6GqFg==} + peerDependencies: + '@babel/core': ^7.0.0 + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -3032,6 +3164,9 @@ packages: resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} engines: {node: '>=18'} + html-entities@2.3.3: + resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} + html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -3234,6 +3369,10 @@ packages: resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} engines: {node: '>= 0.4'} + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -3524,6 +3663,10 @@ packages: resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} engines: {node: '>=16.10'} + merge-anything@5.1.7: + resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==} + engines: {node: '>=12.13'} + merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} @@ -4155,6 +4298,16 @@ packages: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} + seroval-plugins@1.3.1: + resolution: {integrity: sha512-dOlUoiI3fgZbQIcj6By+l865pzeWdP3XCSLdI3xlKnjCk5983yLWPsXytFOUI0BUZKG9qwqbj78n9yVcVwUqaQ==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.3.1: + resolution: {integrity: sha512-F+T9EQPdLzgdewgxnBh4mSc+vde+EOkU6dC9BDuu/bfGb+UyUlqM6t8znFCTPQSuai/ZcfFg0gu79h+bVW2O0w==} + engines: {node: '>=10'} + serve-static@1.16.2: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} @@ -4245,6 +4398,14 @@ packages: resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} engines: {node: '>=18'} + solid-js@1.9.7: + resolution: {integrity: sha512-/saTKi8iWEM233n5OSi1YHCCuh66ZIQ7aK2hsToPe4tqGm7qAejU1SwNuTPivbWAYq7SjuHVVYxxuZQNRbICiw==} + + solid-refresh@0.6.3: + resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==} + peerDependencies: + solid-js: ^1.3 + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -4609,6 +4770,9 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + validate-html-nesting@1.2.2: + resolution: {integrity: sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -4633,6 +4797,16 @@ packages: peerDependencies: vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + vite-plugin-solid@2.11.6: + resolution: {integrity: sha512-Sl5CTqJTGyEeOsmdH6BOgalIZlwH3t4/y0RQuFLMGnvWMBvxb4+lq7x3BSiAw6etf0QexfNJW7HSOO/Qf7pigg==} + peerDependencies: + '@testing-library/jest-dom': ^5.16.6 || ^5.17.0 || ^6.* + solid-js: ^1.7.2 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + '@testing-library/jest-dom': + optional: true + vite-tsconfig-paths@5.1.4: resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} peerDependencies: @@ -4681,6 +4855,14 @@ packages: yaml: optional: true + vitefu@1.0.6: + resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + vite: + optional: true + vitest@3.0.9: resolution: {integrity: sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -4941,6 +5123,10 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-module-imports@7.18.6': + dependencies: + '@babel/types': 7.26.10 + '@babel/helper-module-imports@7.25.9': dependencies: '@babel/traverse': 7.26.9 @@ -4959,6 +5145,8 @@ snapshots: '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-string-parser@7.25.9': {} '@babel/helper-validator-identifier@7.25.9': {} @@ -4978,6 +5166,11 @@ snapshots: dependencies: '@babel/types': 7.26.9 + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.9)': dependencies: '@babel/core': 7.26.9 @@ -5933,6 +6126,11 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} + '@solidjs/testing-library@0.8.10(solid-js@1.9.7)': + dependencies: + '@testing-library/dom': 10.4.0 + solid-js: 1.9.7 + '@standard-schema/spec@1.0.0': {} '@stylistic/eslint-plugin-js@4.2.0(eslint@9.22.0(jiti@2.4.2))': @@ -6659,6 +6857,21 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + babel-plugin-jsx-dom-expressions@0.39.8(@babel/core@7.26.9): + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-module-imports': 7.18.6 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.26.9) + '@babel/types': 7.26.10 + html-entities: 2.3.3 + parse5: 7.2.1 + validate-html-nesting: 1.2.2 + + babel-preset-solid@1.9.6(@babel/core@7.26.9): + dependencies: + '@babel/core': 7.26.9 + babel-plugin-jsx-dom-expressions: 0.39.8(@babel/core@7.26.9) + balanced-match@1.0.2: {} better-path-resolve@1.0.0: @@ -7752,6 +7965,8 @@ snapshots: dependencies: whatwg-encoding: 3.1.1 + html-entities@2.3.3: {} + html-escaper@2.0.2: {} http-errors@2.0.0: @@ -7944,6 +8159,8 @@ snapshots: call-bound: 1.0.3 get-intrinsic: 1.2.7 + is-what@4.1.16: {} + is-windows@1.0.2: {} isarray@2.0.5: {} @@ -8247,6 +8464,10 @@ snapshots: meow@12.1.1: {} + merge-anything@5.1.7: + dependencies: + is-what: 4.1.16 + merge-descriptors@1.0.3: {} merge-stream@2.0.0: {} @@ -8867,6 +9088,12 @@ snapshots: transitivePeerDependencies: - supports-color + seroval-plugins@1.3.1(seroval@1.3.1): + dependencies: + seroval: 1.3.1 + + seroval@1.3.1: {} + serve-static@1.16.2: dependencies: encodeurl: 2.0.0 @@ -8980,6 +9207,21 @@ snapshots: ansi-styles: 6.2.1 is-fullwidth-code-point: 5.0.0 + solid-js@1.9.7: + dependencies: + csstype: 3.1.3 + seroval: 1.3.1 + seroval-plugins: 1.3.1(seroval@1.3.1) + + solid-refresh@0.6.3(solid-js@1.9.7): + dependencies: + '@babel/generator': 7.26.9 + '@babel/helper-module-imports': 7.25.9 + '@babel/types': 7.26.10 + solid-js: 1.9.7 + transitivePeerDependencies: + - supports-color + source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -9350,6 +9592,8 @@ snapshots: utils-merge@1.0.1: {} + validate-html-nesting@1.2.2: {} + vary@1.1.2: {} vite-node@3.0.9(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0): @@ -9396,6 +9640,21 @@ snapshots: dependencies: vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite-plugin-solid@2.11.6(@testing-library/jest-dom@6.6.3)(solid-js@1.9.7)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)): + dependencies: + '@babel/core': 7.26.9 + '@types/babel__core': 7.20.5 + babel-preset-solid: 1.9.6(@babel/core@7.26.9) + merge-anything: 5.1.7 + solid-js: 1.9.7 + solid-refresh: 0.6.3(solid-js@1.9.7) + vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vitefu: 1.0.6(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + optionalDependencies: + '@testing-library/jest-dom': 6.6.3 + transitivePeerDependencies: + - supports-color + vite-tsconfig-paths@5.1.4(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)): dependencies: debug: 4.4.0 @@ -9420,6 +9679,10 @@ snapshots: tsx: 4.19.3 yaml: 2.7.0 + vitefu@1.0.6(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)): + optionalDependencies: + vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vitest@3.0.9(@types/node@22.13.10)(happy-dom@17.4.4)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0): dependencies: '@vitest/expect': 3.0.9