diff --git a/Dockerfile b/Dockerfile index f809fbc..676c0ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,11 +2,7 @@ FROM node:22-alpine AS base WORKDIR /app -RUN apk add --no-cache bash curl && \ - curl -o /usr/local/bin/wait-for-it https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh && \ - chmod +x /usr/local/bin/wait-for-it - -RUN npm install -g pnpm@9 +RUN npm install -g pnpm@10 COPY pnpm-lock.yaml . # Build Stage @@ -29,4 +25,4 @@ COPY --from=build /app/build ./build EXPOSE 3000 ENV BODY_SIZE_LIMIT=Infinity -CMD ["bash", "-c", "wait-for-it ${DATABASE_HOST:-localhost}:${DATABASE_PORT:-5432} -- node ./build/index.js"] +CMD ["node", "./build/index.js"] diff --git a/docker-compose.yaml b/docker-compose.yaml index 57a423f..2015066 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -3,7 +3,8 @@ services: build: . restart: unless-stopped depends_on: - - database + database: + condition: service_healthy user: ${CONTAINER_UID:-0}:${CONTAINER_GID:-0} volumes: - ./data/library:/app/data/library @@ -35,3 +36,8 @@ services: environment: - POSTGRES_USER=arkvault - POSTGRES_PASSWORD=${DATABASE_PASSWORD:?} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER}"] + interval: 5s + timeout: 5s + retries: 5 diff --git a/eslint.config.js b/eslint.config.js index 4027dc6..f12d6e7 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,21 +1,24 @@ -import prettier from "eslint-config-prettier"; -import js from "@eslint/js"; import { includeIgnoreFile } from "@eslint/compat"; +import js from "@eslint/js"; +import { defineConfig } from "eslint/config"; +import prettier from "eslint-config-prettier"; import svelte from "eslint-plugin-svelte"; import tailwind from "eslint-plugin-tailwindcss"; import globals from "globals"; -import { fileURLToPath } from "node:url"; import ts from "typescript-eslint"; +import { fileURLToPath } from "url"; +import svelteConfig from "./svelte.config.js"; + const gitignorePath = fileURLToPath(new URL("./.gitignore", import.meta.url)); -export default ts.config( +export default defineConfig( includeIgnoreFile(gitignorePath), js.configs.recommended, ...ts.configs.recommended, - ...svelte.configs["flat/recommended"], + ...svelte.configs.recommended, ...tailwind.configs["flat/recommended"], prettier, - ...svelte.configs["flat/prettier"], + ...svelte.configs.prettier, { languageOptions: { globals: { @@ -23,13 +26,18 @@ export default ts.config( ...globals.node, }, }, + rules: { + "no-undef": "off", + }, }, { - files: ["**/*.svelte"], - + files: ["**/*.svelte", "**/*.svelte.ts", "**/*.svelte.js"], languageOptions: { parserOptions: { + projectService: true, + extraFileExtensions: [".svelte"], parser: ts.parser, + svelteConfig, }, }, }, diff --git a/package.json b/package.json index e91eafa..3479c2c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "arkvault", "private": true, - "version": "0.5.1", + "version": "0.6.0", "type": "module", "scripts": { "dev": "vite dev", @@ -16,53 +16,57 @@ "db:migrate": "kysely migrate" }, "devDependencies": { - "@eslint/compat": "^1.3.1", - "@iconify-json/material-symbols": "^1.2.29", - "@sveltejs/adapter-node": "^5.2.13", - "@sveltejs/kit": "^2.22.5", - "@sveltejs/vite-plugin-svelte": "^4.0.4", + "@eslint/compat": "^2.0.0", + "@iconify-json/material-symbols": "^1.2.50", + "@sveltejs/adapter-node": "^5.4.0", + "@sveltejs/kit": "^2.49.2", + "@sveltejs/vite-plugin-svelte": "^6.2.1", + "@tanstack/svelte-virtual": "^3.13.13", + "@trpc/client": "^11.8.1", "@types/file-saver": "^2.0.7", "@types/ms": "^0.7.34", "@types/node-schedule": "^2.1.8", - "@types/pg": "^8.15.4", - "autoprefixer": "^10.4.21", - "axios": "^1.10.0", - "dexie": "^4.0.11", - "eslint": "^9.30.1", - "eslint-config-prettier": "^10.1.5", - "eslint-plugin-svelte": "^3.10.1", - "eslint-plugin-tailwindcss": "^3.18.0", - "exifreader": "^4.31.1", + "@types/pg": "^8.16.0", + "autoprefixer": "^10.4.23", + "axios": "^1.13.2", + "dexie": "^4.2.1", + "eslint": "^9.39.2", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-svelte": "^3.13.1", + "eslint-plugin-tailwindcss": "^3.18.2", + "exifreader": "^4.33.1", "file-saver": "^2.0.5", - "globals": "^16.3.0", + "globals": "^16.5.0", "heic2any": "^0.0.4", - "kysely-ctl": "^0.13.1", - "lru-cache": "^11.1.0", - "mime": "^4.0.7", - "p-limit": "^6.2.0", - "prettier": "^3.6.2", - "prettier-plugin-svelte": "^3.4.0", - "prettier-plugin-tailwindcss": "^0.6.14", - "svelte": "^5.35.6", - "svelte-check": "^4.2.2", - "tailwindcss": "^3.4.17", - "typescript": "^5.8.3", - "typescript-eslint": "^8.36.0", - "unplugin-icons": "^22.1.0", - "vite": "^5.4.19" + "kysely-ctl": "^0.19.0", + "lru-cache": "^11.2.4", + "mime": "^4.1.0", + "p-limit": "^7.2.0", + "prettier": "^3.7.4", + "prettier-plugin-svelte": "^3.4.1", + "prettier-plugin-tailwindcss": "^0.7.2", + "svelte": "^5.46.1", + "svelte-check": "^4.3.5", + "tailwindcss": "^3.4.19", + "typescript": "^5.9.3", + "typescript-eslint": "^8.50.1", + "unplugin-icons": "^22.5.0", + "vite": "^7.3.0" }, "dependencies": { - "@fastify/busboy": "^3.1.1", - "argon2": "^0.43.0", - "kysely": "^0.28.2", + "@fastify/busboy": "^3.2.0", + "@trpc/server": "^11.8.1", + "argon2": "^0.44.0", + "kysely": "^0.28.9", "ms": "^2.1.3", "node-schedule": "^2.1.1", "pg": "^8.16.3", - "uuid": "^11.1.0", - "zod": "^3.25.76" + "superjson": "^2.2.6", + "uuid": "^13.0.0", + "zod": "^4.2.1" }, "engines": { "node": "^22.0.0", - "pnpm": "^9.0.0" + "pnpm": "^10.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d0d9407..9dcf04f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,14 +9,17 @@ importers: .: dependencies: '@fastify/busboy': - specifier: ^3.1.1 - version: 3.1.1 + specifier: ^3.2.0 + version: 3.2.0 + '@trpc/server': + specifier: ^11.8.1 + version: 11.8.1(typescript@5.9.3) argon2: - specifier: ^0.43.0 - version: 0.43.0 + specifier: ^0.44.0 + version: 0.44.0 kysely: - specifier: ^0.28.2 - version: 0.28.2 + specifier: ^0.28.9 + version: 0.28.9 ms: specifier: ^2.1.3 version: 2.1.3 @@ -26,28 +29,37 @@ importers: pg: specifier: ^8.16.3 version: 8.16.3 + superjson: + specifier: ^2.2.6 + version: 2.2.6 uuid: - specifier: ^11.1.0 - version: 11.1.0 + specifier: ^13.0.0 + version: 13.0.0 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: ^4.2.1 + version: 4.2.1 devDependencies: '@eslint/compat': - specifier: ^1.3.1 - version: 1.3.1(eslint@9.30.1(jiti@2.4.2)) + specifier: ^2.0.0 + version: 2.0.0(eslint@9.39.2(jiti@1.21.7)) '@iconify-json/material-symbols': - specifier: ^1.2.29 - version: 1.2.29 + specifier: ^1.2.50 + version: 1.2.50 '@sveltejs/adapter-node': - specifier: ^5.2.13 - version: 5.2.13(@sveltejs/kit@2.22.5(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)))(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13))) + specifier: ^5.4.0 + version: 5.4.0(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0))) '@sveltejs/kit': - specifier: ^2.22.5 - version: 2.22.5(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)))(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)) + specifier: ^2.49.2 + version: 2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)) '@sveltejs/vite-plugin-svelte': - specifier: ^4.0.4 - version: 4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)) + specifier: ^6.2.1 + version: 6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)) + '@tanstack/svelte-virtual': + specifier: ^3.13.13 + version: 3.13.13(svelte@5.46.1) + '@trpc/client': + specifier: ^11.8.1 + version: 11.8.1(@trpc/server@11.8.1(typescript@5.9.3))(typescript@5.9.3) '@types/file-saver': specifier: ^2.0.7 version: 2.0.7 @@ -58,83 +70,83 @@ importers: specifier: ^2.1.8 version: 2.1.8 '@types/pg': - specifier: ^8.15.4 - version: 8.15.4 + specifier: ^8.16.0 + version: 8.16.0 autoprefixer: - specifier: ^10.4.21 - version: 10.4.21(postcss@8.5.6) + specifier: ^10.4.23 + version: 10.4.23(postcss@8.5.6) axios: - specifier: ^1.10.0 - version: 1.10.0 + specifier: ^1.13.2 + version: 1.13.2 dexie: - specifier: ^4.0.11 - version: 4.0.11 + specifier: ^4.2.1 + version: 4.2.1 eslint: - specifier: ^9.30.1 - version: 9.30.1(jiti@2.4.2) + specifier: ^9.39.2 + version: 9.39.2(jiti@1.21.7) eslint-config-prettier: - specifier: ^10.1.5 - version: 10.1.5(eslint@9.30.1(jiti@2.4.2)) + specifier: ^10.1.8 + version: 10.1.8(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-svelte: - specifier: ^3.10.1 - version: 3.10.1(eslint@9.30.1(jiti@2.4.2))(svelte@5.35.6) + specifier: ^3.13.1 + version: 3.13.1(eslint@9.39.2(jiti@1.21.7))(svelte@5.46.1) eslint-plugin-tailwindcss: - specifier: ^3.18.0 - version: 3.18.0(tailwindcss@3.4.17) + specifier: ^3.18.2 + version: 3.18.2(tailwindcss@3.4.19(yaml@2.8.0)) exifreader: - specifier: ^4.31.1 - version: 4.31.1 + specifier: ^4.33.1 + version: 4.33.1 file-saver: specifier: ^2.0.5 version: 2.0.5 globals: - specifier: ^16.3.0 - version: 16.3.0 + specifier: ^16.5.0 + version: 16.5.0 heic2any: specifier: ^0.0.4 version: 0.0.4 kysely-ctl: - specifier: ^0.13.1 - version: 0.13.1(kysely@0.28.2) + specifier: ^0.19.0 + version: 0.19.0(kysely@0.28.9)(typescript@5.9.3) lru-cache: - specifier: ^11.1.0 - version: 11.1.0 + specifier: ^11.2.4 + version: 11.2.4 mime: - specifier: ^4.0.7 - version: 4.0.7 + specifier: ^4.1.0 + version: 4.1.0 p-limit: - specifier: ^6.2.0 - version: 6.2.0 + specifier: ^7.2.0 + version: 7.2.0 prettier: - specifier: ^3.6.2 - version: 3.6.2 + specifier: ^3.7.4 + version: 3.7.4 prettier-plugin-svelte: - specifier: ^3.4.0 - version: 3.4.0(prettier@3.6.2)(svelte@5.35.6) + specifier: ^3.4.1 + version: 3.4.1(prettier@3.7.4)(svelte@5.46.1) prettier-plugin-tailwindcss: - specifier: ^0.6.14 - version: 0.6.14(prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.35.6))(prettier@3.6.2) + specifier: ^0.7.2 + version: 0.7.2(prettier-plugin-svelte@3.4.1(prettier@3.7.4)(svelte@5.46.1))(prettier@3.7.4) svelte: - specifier: ^5.35.6 - version: 5.35.6 + specifier: ^5.46.1 + version: 5.46.1 svelte-check: - specifier: ^4.2.2 - version: 4.2.2(picomatch@4.0.2)(svelte@5.35.6)(typescript@5.8.3) + specifier: ^4.3.5 + version: 4.3.5(picomatch@4.0.3)(svelte@5.46.1)(typescript@5.9.3) tailwindcss: - specifier: ^3.4.17 - version: 3.4.17 + specifier: ^3.4.19 + version: 3.4.19(yaml@2.8.0) typescript: - specifier: ^5.8.3 - version: 5.8.3 + specifier: ^5.9.3 + version: 5.9.3 typescript-eslint: - specifier: ^8.36.0 - version: 8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + specifier: ^8.50.1 + version: 8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) unplugin-icons: - specifier: ^22.1.0 - version: 22.1.0(svelte@5.35.6) + specifier: ^22.5.0 + version: 22.5.0(svelte@5.46.1) vite: - specifier: ^5.4.19 - version: 5.4.19(@types/node@24.0.13) + specifier: ^7.3.0 + version: 7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0) packages: @@ -142,253 +154,262 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} - '@antfu/utils@8.1.1': - resolution: {integrity: sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==} + '@epic-web/invariant@1.0.0': + resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/compat@1.3.1': - resolution: {integrity: sha512-k8MHony59I5EPic6EQTCNOuPoVBnoYXkP+20xvwFjN7t0qI3ImyvyBgg+hIVPwC8JaxVjjUZld+cLfBLFDLucg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/compat@2.0.0': + resolution: {integrity: sha512-T9AfE1G1uv4wwq94ozgTGio5EUQBqAVe1X9qsQtSNVEYW6j3hvtZVm8Smr4qL1qDPFg+lOB2cL5RxTRMzq4CTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: ^8.40 || 9 peerDependenciesMeta: eslint: optional: true - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.3.0': - resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.14.0': - resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.1': - resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} + '@eslint/core@1.0.0': + resolution: {integrity: sha512-PRfWP+8FOldvbApr6xL7mNCw4cJcSTq4GA7tYbgq15mRb0kWKO/wEB2jr+uwjFH3sZvEZneZyCUGTxsv4Sahyw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/eslintrc@3.3.3': + resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + '@eslint/js@9.39.2': + resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.30.1': - resolution: {integrity: sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==} + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.3': - resolution: {integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@fastify/busboy@3.1.1': - resolution: {integrity: sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==} + '@fastify/busboy@3.2.0': + resolution: {integrity: sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==} '@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==} + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.3': resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@iconify-json/material-symbols@1.2.29': - resolution: {integrity: sha512-UUSrsl0gHF0GjAB9eZOpXrj7/v55ayMzo3QnMwUqP/FSfSkITKLR7CsBmUIFS8eEj8eRTfBNWA1yiIJR6UOdWg==} + '@iconify-json/material-symbols@1.2.50': + resolution: {integrity: sha512-71tjHR70h46LHtBFab3fAd2V/wPTO7JMV5lKnRn3IcF303LaFgAlO0BZeTJDcmCv9d0snRZmnoLZAJVD7/eisw==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - '@iconify/utils@2.3.0': - resolution: {integrity: sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==} + '@iconify/utils@3.1.0': + resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - '@jridgewell/gen-mapping@0.3.12': - resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.5.4': - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.29': - resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -406,15 +427,11 @@ packages: resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==} engines: {node: '>=10'} - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@rollup/plugin-commonjs@28.0.6': - resolution: {integrity: sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw==} + '@rollup/plugin-commonjs@28.0.9': + resolution: {integrity: sha512-PIR4/OHZ79romx0BVVll/PkwWpJ7e5lsqFa3gFfcrFPWwLXLV39JVUzQV9RKjWerE7B845Hqjj9VYlQeieZ2dA==} engines: {node: '>=16.0.0 || 14 >= 14.17'} peerDependencies: rollup: ^2.68.0||^3.0.0||^4.0.0 @@ -431,8 +448,8 @@ packages: rollup: optional: true - '@rollup/plugin-node-resolve@16.0.1': - resolution: {integrity: sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==} + '@rollup/plugin-node-resolve@16.0.3': + resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^2.78.0||^3.0.0||^4.0.0 @@ -440,8 +457,8 @@ packages: rollup: optional: true - '@rollup/pluginutils@5.2.0': - resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -449,139 +466,175 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.44.2': - resolution: {integrity: sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q==} + '@rollup/rollup-android-arm-eabi@4.54.0': + resolution: {integrity: sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.44.2': - resolution: {integrity: sha512-Yt5MKrOosSbSaAK5Y4J+vSiID57sOvpBNBR6K7xAaQvk3MkcNVV0f9fE20T+41WYN8hDn6SGFlFrKudtx4EoxA==} + '@rollup/rollup-android-arm64@4.54.0': + resolution: {integrity: sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.44.2': - resolution: {integrity: sha512-EsnFot9ZieM35YNA26nhbLTJBHD0jTwWpPwmRVDzjylQT6gkar+zenfb8mHxWpRrbn+WytRRjE0WKsfaxBkVUA==} + '@rollup/rollup-darwin-arm64@4.54.0': + resolution: {integrity: sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.44.2': - resolution: {integrity: sha512-dv/t1t1RkCvJdWWxQ2lWOO+b7cMsVw5YFaS04oHpZRWehI1h0fV1gF4wgGCTyQHHjJDfbNpwOi6PXEafRBBezw==} + '@rollup/rollup-darwin-x64@4.54.0': + resolution: {integrity: sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.44.2': - resolution: {integrity: sha512-W4tt4BLorKND4qeHElxDoim0+BsprFTwb+vriVQnFFtT/P6v/xO5I99xvYnVzKWrK6j7Hb0yp3x7V5LUbaeOMg==} + '@rollup/rollup-freebsd-arm64@4.54.0': + resolution: {integrity: sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.44.2': - resolution: {integrity: sha512-tdT1PHopokkuBVyHjvYehnIe20fxibxFCEhQP/96MDSOcyjM/shlTkZZLOufV3qO6/FQOSiJTBebhVc12JyPTA==} + '@rollup/rollup-freebsd-x64@4.54.0': + resolution: {integrity: sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.44.2': - resolution: {integrity: sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.54.0': + resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.44.2': - resolution: {integrity: sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA==} + '@rollup/rollup-linux-arm-musleabihf@4.54.0': + resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.44.2': - resolution: {integrity: sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A==} + '@rollup/rollup-linux-arm64-gnu@4.54.0': + resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.44.2': - resolution: {integrity: sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A==} + '@rollup/rollup-linux-arm64-musl@4.54.0': + resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.44.2': - resolution: {integrity: sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g==} + '@rollup/rollup-linux-loong64-gnu@4.54.0': + resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.44.2': - resolution: {integrity: sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw==} + '@rollup/rollup-linux-ppc64-gnu@4.54.0': + resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.44.2': - resolution: {integrity: sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg==} + '@rollup/rollup-linux-riscv64-gnu@4.54.0': + resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.44.2': - resolution: {integrity: sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg==} + '@rollup/rollup-linux-riscv64-musl@4.54.0': + resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.44.2': - resolution: {integrity: sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw==} + '@rollup/rollup-linux-s390x-gnu@4.54.0': + resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.44.2': - resolution: {integrity: sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ==} + '@rollup/rollup-linux-x64-gnu@4.54.0': + resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.44.2': - resolution: {integrity: sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg==} + '@rollup/rollup-linux-x64-musl@4.54.0': + resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.44.2': - resolution: {integrity: sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw==} + '@rollup/rollup-openharmony-arm64@4.54.0': + resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.54.0': + resolution: {integrity: sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.44.2': - resolution: {integrity: sha512-+qMUrkbUurpE6DVRjiJCNGZBGo9xM4Y0FXU5cjgudWqIBWbcLkjE3XprJUsOFgC6xjBClwVa9k6O3A7K3vxb5Q==} + '@rollup/rollup-win32-ia32-msvc@4.54.0': + resolution: {integrity: sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.44.2': - resolution: {integrity: sha512-3+QZROYfJ25PDcxFF66UEk8jGWigHJeecZILvkPkyQN7oc5BvFo4YEXFkOs154j3FTMp9mn9Ky8RCOwastduEA==} + '@rollup/rollup-win32-x64-gnu@4.54.0': + resolution: {integrity: sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==} cpu: [x64] os: [win32] - '@sveltejs/acorn-typescript@1.0.5': - resolution: {integrity: sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==} + '@rollup/rollup-win32-x64-msvc@4.54.0': + resolution: {integrity: sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==} + cpu: [x64] + os: [win32] + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@sveltejs/acorn-typescript@1.0.8': + resolution: {integrity: sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA==} peerDependencies: acorn: ^8.9.0 - '@sveltejs/adapter-node@5.2.13': - resolution: {integrity: sha512-yS2TVFmIrxjGhYaV5/iIUrJ3mJl6zjaYn0lBD70vTLnYvJeqf3cjvLXeXCUCuYinhSBoyF4DpfGla49BnIy7sQ==} + '@sveltejs/adapter-node@5.4.0': + resolution: {integrity: sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==} peerDependencies: '@sveltejs/kit': ^2.4.0 - '@sveltejs/kit@2.22.5': - resolution: {integrity: sha512-l5i+LcDaoymD2mg5ziptnHmzzF79+c9twJiDoLWAPKq7afMEe4mvGesJ+LVtm33A92mLzd2KUHgtGSqTrvfkvg==} + '@sveltejs/kit@2.49.2': + resolution: {integrity: sha512-Vp3zX/qlwerQmHMP6x0Ry1oY7eKKRcOWGc2P59srOp4zcqyn+etJyQpELgOi4+ZSUgteX8Y387NuwruLgGXLUQ==} engines: {node: '>=18.13'} hasBin: true peerDependencies: + '@opentelemetry/api': ^1.0.0 '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 svelte: ^4.0.0 || ^5.0.0-next.0 vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true - '@sveltejs/vite-plugin-svelte-inspector@3.0.1': - resolution: {integrity: sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22} + '@sveltejs/vite-plugin-svelte-inspector@5.0.1': + resolution: {integrity: sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==} + engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: - '@sveltejs/vite-plugin-svelte': ^4.0.0-next.0||^4.0.0 - svelte: ^5.0.0-next.96 || ^5.0.0 - vite: ^5.0.0 + '@sveltejs/vite-plugin-svelte': ^6.0.0-next.0 + svelte: ^5.0.0 + vite: ^6.3.0 || ^7.0.0 - '@sveltejs/vite-plugin-svelte@4.0.4': - resolution: {integrity: sha512-0ba1RQ/PHen5FGpdSrW7Y3fAMQjrXantECALeOiOdBdzR5+5vPP6HVZRLmZaQL+W8m++o+haIAKq5qT+MiZ7VA==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22} + '@sveltejs/vite-plugin-svelte@6.2.1': + resolution: {integrity: sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==} + engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: - svelte: ^5.0.0-next.96 || ^5.0.0 - vite: ^5.0.0 + svelte: ^5.0.0 + vite: ^6.3.0 || ^7.0.0 + + '@tanstack/svelte-virtual@3.13.13': + resolution: {integrity: sha512-VDOvbRw3R+XBQdFodEJ4E7AOmEyo3Bmr4zL4DLVnJ0fxICdbvY5F5t8zSwJ4f7lqjckXi0yKFzY8WBtjaNbsGQ==} + peerDependencies: + svelte: ^3.48.0 || ^4.0.0 || ^5.0.0 + + '@tanstack/virtual-core@3.13.13': + resolution: {integrity: sha512-uQFoSdKKf5S8k51W5t7b2qpfkyIbdHMzAn+AMQvHPxKUPeo1SsGaA4JRISQT87jm28b7z8OEqPcg1IOZagQHcA==} + + '@trpc/client@11.8.1': + resolution: {integrity: sha512-L/SJFGanr9xGABmuDoeXR4xAdHJmsXsiF9OuH+apecJ+8sUITzVT1EPeqp0ebqA6lBhEl5pPfg3rngVhi/h60Q==} + peerDependencies: + '@trpc/server': 11.8.1 + typescript: '>=5.7.2' + + '@trpc/server@11.8.1': + resolution: {integrity: sha512-P4rzZRpEL7zDFgjxK65IdyH0e41FMFfTkQkuq0BA5tKcr7E6v9/v38DEklCpoDN6sPiB1Sigy/PUEzHENhswDA==} + peerDependencies: + typescript: '>=5.7.2' '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} @@ -601,72 +654,72 @@ packages: '@types/node-schedule@2.1.8': resolution: {integrity: sha512-k00g6Yj/oUg/CDC+MeLHUzu0+OFxWbIqrFfDiLi6OPKxTujvpv29mHGM8GtKr7B+9Vv92FcK/8mRqi1DK5f3hA==} - '@types/node@24.0.13': - resolution: {integrity: sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ==} + '@types/node@25.0.3': + resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==} - '@types/pg@8.15.4': - resolution: {integrity: sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==} + '@types/pg@8.16.0': + resolution: {integrity: sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==} '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - '@typescript-eslint/eslint-plugin@8.36.0': - resolution: {integrity: sha512-lZNihHUVB6ZZiPBNgOQGSxUASI7UJWhT8nHyUGCnaQ28XFCw98IfrMCG3rUl1uwUWoAvodJQby2KTs79UTcrAg==} + '@typescript-eslint/eslint-plugin@8.50.1': + resolution: {integrity: sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.36.0 + '@typescript-eslint/parser': ^8.50.1 eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.36.0': - resolution: {integrity: sha512-FuYgkHwZLuPbZjQHzJXrtXreJdFMKl16BFYyRrLxDhWr6Qr7Kbcu2s1Yhu8tsiMXw1S0W1pjfFfYEt+R604s+Q==} + '@typescript-eslint/parser@8.50.1': + resolution: {integrity: sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.36.0': - resolution: {integrity: sha512-JAhQFIABkWccQYeLMrHadu/fhpzmSQ1F1KXkpzqiVxA/iYI6UnRt2trqXHt1sYEcw1mxLnB9rKMsOxXPxowN/g==} + '@typescript-eslint/project-service@8.50.1': + resolution: {integrity: sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.36.0': - resolution: {integrity: sha512-wCnapIKnDkN62fYtTGv2+RY8FlnBYA3tNm0fm91kc2BjPhV2vIjwwozJ7LToaLAyb1ca8BxrS7vT+Pvvf7RvqA==} + '@typescript-eslint/scope-manager@8.50.1': + resolution: {integrity: sha512-mfRx06Myt3T4vuoHaKi8ZWNTPdzKPNBhiblze5N50//TSHOAQQevl/aolqA/BcqqbJ88GUnLqjjcBc8EWdBcVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.36.0': - resolution: {integrity: sha512-Nhh3TIEgN18mNbdXpd5Q8mSCBnrZQeY9V7Ca3dqYvNDStNIGRmJA6dmrIPMJ0kow3C7gcQbpsG2rPzy1Ks/AnA==} + '@typescript-eslint/tsconfig-utils@8.50.1': + resolution: {integrity: sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.36.0': - resolution: {integrity: sha512-5aaGYG8cVDd6cxfk/ynpYzxBRZJk7w/ymto6uiyUFtdCozQIsQWh7M28/6r57Fwkbweng8qAzoMCPwSJfWlmsg==} + '@typescript-eslint/type-utils@8.50.1': + resolution: {integrity: sha512-7J3bf022QZE42tYMO6SL+6lTPKFk/WphhRPe9Tw/el+cEwzLz1Jjz2PX3GtGQVxooLDKeMVmMt7fWpYRdG5Etg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.36.0': - resolution: {integrity: sha512-xGms6l5cTJKQPZOKM75Dl9yBfNdGeLRsIyufewnxT4vZTrjC0ImQT4fj8QmtJK84F58uSh5HVBSANwcfiXxABQ==} + '@typescript-eslint/types@8.50.1': + resolution: {integrity: sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.36.0': - resolution: {integrity: sha512-JaS8bDVrfVJX4av0jLpe4ye0BpAaUW7+tnS4Y4ETa3q7NoZgzYbN9zDQTJ8kPb5fQ4n0hliAt9tA4Pfs2zA2Hg==} + '@typescript-eslint/typescript-estree@8.50.1': + resolution: {integrity: sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.36.0': - resolution: {integrity: sha512-VOqmHu42aEMT+P2qYjylw6zP/3E/HvptRwdn/PZxyV27KhZg2IOszXod4NcXisWzPAGSS4trE/g4moNj6XmH2g==} + '@typescript-eslint/utils@8.50.1': + resolution: {integrity: sha512-lCLp8H1T9T7gPbEuJSnHwnSuO9mDf8mfK/Nion5mZmiEaQD9sWf9W4dfeFqRyqRjF06/kBuTmAqcs9sewM2NbQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.36.0': - resolution: {integrity: sha512-vZrhV2lRPWDuGoxcmrzRZyxAggPL+qp3WzUrlZD+slFueDiYHxeBa34dUXPuC0RmGKzl4lS5kFJYvKCq9cnNDA==} + '@typescript-eslint/visitor-keys@8.50.1': + resolution: {integrity: sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@xmldom/xmldom@0.9.8': @@ -686,22 +739,10 @@ packages: 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-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} - engines: {node: '>=12'} - ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -712,8 +753,8 @@ packages: arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - argon2@0.43.0: - resolution: {integrity: sha512-u/HKLcbWShVDhkfwI4hWyiUf3qyX8QhTfaIv2cWE18uqhXCmR5hb6Ed7oqYi2KCQegeAnRhiFzbjzm7i5yl1GA==} + argon2@0.44.0: + resolution: {integrity: sha512-zHPGN3S55sihSQo0dBbK0A5qpi2R31z7HZDZnry3ifOyj8bZZnpZND2gpmhnRGO1V/d555RwBqIK5W4Mrmv3ig==} engines: {node: '>=16.17.0'} argparse@2.0.1: @@ -726,15 +767,15 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - autoprefixer@10.4.21: - resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} + autoprefixer@10.4.23: + resolution: {integrity: sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 - axios@1.10.0: - resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + axios@1.13.2: + resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -743,6 +784,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + baseline-browser-mapping@2.9.11: + resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} + hasBin: true + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -757,15 +802,15 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.25.1: - resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - c12@3.0.4: - resolution: {integrity: sha512-t5FaZTYbbCtvxuZq9xxIruYydrAGsJ+8UdP0pZzMiK2xl/gNiSOy0OxhLzHUEEb0m1QXYqfzfvyIFEmz/g9lqg==} + c12@3.3.3: + resolution: {integrity: sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q==} peerDependencies: - magicast: ^0.3.5 + magicast: '*' peerDependenciesMeta: magicast: optional: true @@ -782,8 +827,8 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - caniuse-lite@1.0.30001727: - resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} + caniuse-lite@1.0.30001761: + resolution: {integrity: sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -797,6 +842,10 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} @@ -839,10 +888,19 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + copy-anything@4.0.5: + resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} + engines: {node: '>=18'} + cron-parser@4.9.0: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} + cross-env@10.1.0: + resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} + engines: {node: '>=20'} + hasBin: true + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -852,8 +910,8 @@ packages: engines: {node: '>=4'} hasBin: true - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -878,11 +936,11 @@ packages: destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - devalue@5.1.1: - resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + devalue@5.6.1: + resolution: {integrity: sha512-jDwizj+IlEZBunHcOuuFVBnIMPAEHvTsJj0BcIp94xYguLRVBcXO853px/MyIJvbVzWdsGvrRweIUWJw8hBP7A==} - dexie@4.0.11: - resolution: {integrity: sha512-SOKO002EqlvBYYKQSew3iymBoN2EQ4BDw/3yprjh7kAfFzjBYkaMNa/pZvcA7HSWlcKSQb9XhPe3wKyQ0x4A8A==} + dexie@4.2.1: + resolution: {integrity: sha512-Ckej0NS6jxQ4Po3OrSQBFddayRhTCic2DoCAG5zacOfOVB9P2Q5Xc5uL/nVa7ZVs+HdMnvUPzLFCB/JwpB6Csg==} didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -890,25 +948,16 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - dotenv@16.6.1: - resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} engines: {node: '>=12'} dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - electron-to-chromium@1.5.182: - resolution: {integrity: sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + electron-to-chromium@1.5.267: + resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} @@ -926,9 +975,9 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} hasBin: true escalade@3.2.0: @@ -939,14 +988,14 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-prettier@10.1.5: - resolution: {integrity: sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==} + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} hasBin: true peerDependencies: eslint: '>=7.0.0' - eslint-plugin-svelte@3.10.1: - resolution: {integrity: sha512-csCh2x0ge/DugXC7dCANh46Igi7bjMZEy6rHZCdS13AoGVJSu7a90Kru3I8oMYLGEemPRE1hQXadxvRPVMAAXQ==} + eslint-plugin-svelte@3.13.1: + resolution: {integrity: sha512-Ng+kV/qGS8P/isbNYVE3sJORtubB+yLEcYICMkUWNaDTb0SwZni/JhAYXh/Dz/q2eThUwWY0VMPZ//KYD1n3eQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 @@ -955,8 +1004,8 @@ packages: svelte: optional: true - eslint-plugin-tailwindcss@3.18.0: - resolution: {integrity: sha512-PQDU4ZMzFH0eb2DrfHPpbgo87Zgg2EXSMOj1NSfzdZm+aJzpuwGerfowMIaVehSREEa0idbf/eoNYAOHSJoDAQ==} + eslint-plugin-tailwindcss@3.18.2: + resolution: {integrity: sha512-QbkMLDC/OkkjFQ1iz/5jkMdHfiMu/uwujUHLAJK5iwNHD8RTxVTlsUezE0toTZ6VhybNBsk+gYGPDq2agfeRNA==} engines: {node: '>=18.12.0'} peerDependencies: tailwindcss: ^3.4.0 @@ -973,8 +1022,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.30.1: - resolution: {integrity: sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==} + eslint@9.39.2: + resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -994,8 +1043,8 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} - esrap@2.1.0: - resolution: {integrity: sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==} + esrap@2.2.1: + resolution: {integrity: sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==} esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} @@ -1012,11 +1061,11 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - exifreader@4.31.1: - resolution: {integrity: sha512-rkSg/NejDN9D+8GuRWZ2Y4G8KSrj0hdaeMoew8d0J5cF5oS0p6DVar2PSQ0fP3assu6s1PYh6M1lhtS7Kigk6Q==} + exifreader@4.33.1: + resolution: {integrity: sha512-KsVc4bRfZW255PSst5Opt5jUeLp+SD2+q6fmXQkMMkphpFCDBFjzNAvswgQa1YcMrXq+9Na6HJ6gS3wo2x7RRw==} - exsolve@1.0.7: - resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1031,11 +1080,12 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -1064,8 +1114,8 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -1073,16 +1123,12 @@ packages: debug: optional: true - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - - form-data@4.0.3: - resolution: {integrity: sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} - fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} @@ -1112,29 +1158,18 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - 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'} - - globals@16.3.0: - resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1182,10 +1217,6 @@ packages: 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'} @@ -1203,22 +1234,23 @@ packages: is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + is-what@5.5.0: + resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} + engines: {node: '>=18'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jiti@1.21.7: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true json-buffer@3.0.1: @@ -1240,23 +1272,26 @@ packages: known-css-properties@0.37.0: resolution: {integrity: sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==} - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - - kysely-ctl@0.13.1: - resolution: {integrity: sha512-DhTgpt1ru3Y74rI8O3IRLJ5HV09vMSz4q2KEeqaUX0GYMB09zO1KsdwSsF+ZMa8bHeS4F4J3Vjfbc4ulJQ1r0A==} - engines: {node: '>=18'} + kysely-ctl@0.19.0: + resolution: {integrity: sha512-89hzOd1cy/H063jB2E9wYHq+uKYpaHv6Mb5RiNFpRZL6BYCah9ncsdl3x5b52eirxry4UyWSmGNN3sFv+gK+ig==} + engines: {node: '>=20'} hasBin: true peerDependencies: kysely: '>=0.18.1 <0.29.0' - kysely-postgres-js: ^2 + kysely-neon: ^2 + kysely-postgres-js: ^2 || ^3 + kysely-prisma-postgres: ^0.1 peerDependenciesMeta: + kysely-neon: + optional: true kysely-postgres-js: optional: true + kysely-prisma-postgres: + optional: true - kysely@0.28.2: - resolution: {integrity: sha512-4YAVLoF0Sf0UTqlhgQMFU9iQECdah7n+13ANkiuVfRvlK+uI0Etbgd7bVP36dKlG+NXWbhGua8vnGt+sdhvT7A==} - engines: {node: '>=18.0.0'} + kysely@0.28.9: + resolution: {integrity: sha512-3BeXMoiOhpOwu62CiVpO6lxfq4eS6KMYfQdMsN/2kUCRNuF2YiEr7u0HLHaQU+O4Xu8YXE3bHVkwaQ85i72EuA==} + engines: {node: '>=20.0.0'} levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} @@ -1273,8 +1308,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - local-pkg@1.1.1: - resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} + local-pkg@1.1.2: + resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} engines: {node: '>=14'} locate-character@3.0.0: @@ -1290,19 +1325,16 @@ packages: long-timeout@0.1.1: resolution: {integrity: sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==} - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - lru-cache@11.1.0: - resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + lru-cache@11.2.4: + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} - luxon@3.7.1: - resolution: {integrity: sha512-RkRWjA926cTvz5rAb1BqyWkKbbjzCGchDUIKMCUvNi17j6f6j8uHGDV82Aqcqtzd+icoYpELmG3ksgGiFNNcNg==} + luxon@3.7.2: + resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} engines: {node: '>=12'} - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} @@ -1324,8 +1356,8 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime@4.0.7: - resolution: {integrity: sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ==} + mime@4.1.0: + resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} engines: {node: '>=16'} hasBin: true @@ -1336,12 +1368,8 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - mlly@1.7.4: - resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -1365,19 +1393,19 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - node-addon-api@8.4.0: - resolution: {integrity: sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==} + node-addon-api@8.5.0: + resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==} engines: {node: ^18 || ^20 || >= 21} - node-fetch-native@1.6.6: - resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} node-gyp-build@4.8.4: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} node-schedule@2.1.1: resolution: {integrity: sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==} @@ -1387,12 +1415,8 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} - - nypm@0.6.0: - resolution: {integrity: sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg==} + nypm@0.6.2: + resolution: {integrity: sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==} engines: {node: ^14.16.0 || >=16.10.0} hasBin: true @@ -1404,8 +1428,8 @@ packages: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} - ofetch@1.4.1: - resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} @@ -1418,19 +1442,16 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} - p-limit@6.2.0: - resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} - engines: {node: '>=18'} + p-limit@7.2.0: + resolution: {integrity: sha512-ATHLtwoTNDloHRFFxFJdHnG6n2WUeFjaR8XQMFdKIv0xkXjrER8/iG9iu265jOM95zXHAfv9oTkqhrfbIzosrQ==} + engines: {node: '>=20'} p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - - package-manager-detector@1.3.0: - resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -1447,15 +1468,11 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + perfect-debounce@2.0.0: + resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} pg-cloudflare@1.2.7: resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} @@ -1498,8 +1515,8 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} pify@2.3.0: @@ -1513,8 +1530,8 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - pkg-types@2.2.0: - resolution: {integrity: sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==} + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} postcss-import@15.1.0: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} @@ -1522,8 +1539,8 @@ packages: peerDependencies: postcss: ^8.0.0 - postcss-js@4.0.1: - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 @@ -1540,16 +1557,22 @@ packages: ts-node: optional: true - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} peerDependencies: + jiti: '>=1.21.0' postcss: '>=8.0.9' - ts-node: '>=9.0.0' + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: + jiti: + optional: true postcss: optional: true - ts-node: + tsx: + optional: true + yaml: optional: true postcss-nested@6.2.0: @@ -1574,8 +1597,8 @@ packages: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} - postcss-selector-parser@7.1.0: - resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} engines: {node: '>=4'} postcss-value-parser@4.2.0: @@ -1589,8 +1612,8 @@ packages: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} - postgres-bytea@1.0.0: - resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + postgres-bytea@1.0.1: + resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} engines: {node: '>=0.10.0'} postgres-date@1.0.7: @@ -1605,15 +1628,15 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-plugin-svelte@3.4.0: - resolution: {integrity: sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==} + prettier-plugin-svelte@3.4.1: + resolution: {integrity: sha512-xL49LCloMoZRvSwa6IEdN2GV6cq2IqpYGstYtMT+5wmml1/dClEoI0MZR78MiVPpu6BdQFfN0/y73yO6+br5Pg==} peerDependencies: prettier: ^3.0.0 svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 - prettier-plugin-tailwindcss@0.6.14: - resolution: {integrity: sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==} - engines: {node: '>=14.21.3'} + prettier-plugin-tailwindcss@0.7.2: + resolution: {integrity: sha512-LkphyK3Fw+q2HdMOoiEHWf93fNtYJwfamoKPl7UwtjFQdei/iIBoX11G6j706FzN3ymX9mPVi97qIY8328vdnA==} + engines: {node: '>=20.19'} peerDependencies: '@ianvs/prettier-plugin-sort-imports': '*' '@prettier/plugin-hermes': '*' @@ -1625,14 +1648,12 @@ packages: prettier: ^3.0 prettier-plugin-astro: '*' prettier-plugin-css-order: '*' - prettier-plugin-import-sort: '*' prettier-plugin-jsdoc: '*' prettier-plugin-marko: '*' prettier-plugin-multiline-arrays: '*' prettier-plugin-organize-attributes: '*' prettier-plugin-organize-imports: '*' prettier-plugin-sort-imports: '*' - prettier-plugin-style-order: '*' prettier-plugin-svelte: '*' peerDependenciesMeta: '@ianvs/prettier-plugin-sort-imports': @@ -1653,8 +1674,6 @@ packages: optional: true prettier-plugin-css-order: optional: true - prettier-plugin-import-sort: - optional: true prettier-plugin-jsdoc: optional: true prettier-plugin-marko: @@ -1667,13 +1686,11 @@ packages: optional: true prettier-plugin-sort-imports: optional: true - prettier-plugin-style-order: - optional: true prettier-plugin-svelte: optional: true - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + prettier@3.7.4: + resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} engines: {node: '>=14'} hasBin: true @@ -1684,8 +1701,8 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - quansync@0.2.10: - resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -1704,12 +1721,16 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} hasBin: true @@ -1717,8 +1738,8 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.44.2: - resolution: {integrity: sha512-PVoapzTwSEcelaWGth3uR66u7ZRo6qhPHc0f2uRO9fX6XDVNrIiGYS0Pj9+R8yIIYSD/mCx2b16Ws9itljKSPg==} + rollup@4.54.0: + resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1729,13 +1750,13 @@ packages: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true - set-cookie-parser@2.7.1: - resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} @@ -1745,12 +1766,8 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sirv@3.0.1: - resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} sorted-array-functions@1.3.0: @@ -1764,34 +1781,22 @@ packages: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true + superjson@2.2.6: + resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==} + engines: {node: '>=16'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -1800,29 +1805,29 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte-check@4.2.2: - resolution: {integrity: sha512-1+31EOYZ7NKN0YDMKusav2hhEoA51GD9Ws6o//0SphMT0ve9mBTsTUEX7OmDMadUP3KjNHsSKtJrqdSaD8CrGQ==} + svelte-check@4.3.5: + resolution: {integrity: sha512-e4VWZETyXaKGhpkxOXP+B/d0Fp/zKViZoJmneZWe/05Y2aqSKj3YN2nLfYPJBQ87WEiY4BQCQ9hWGu9mPT1a1Q==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: svelte: ^4.0.0 || ^5.0.0-next.0 typescript: '>=5.0.0' - svelte-eslint-parser@1.2.0: - resolution: {integrity: sha512-mbPtajIeuiyU80BEyGvwAktBeTX7KCr5/0l+uRGLq1dafwRNrjfM5kHGJScEBlPG3ipu6dJqfW/k0/fujvIEVw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + svelte-eslint-parser@1.4.1: + resolution: {integrity: sha512-1eqkfQ93goAhjAXxZiu1SaKI9+0/sxp4JIWQwUpsz7ybehRE5L8dNuz7Iry7K22R47p5/+s9EM+38nHV2OlgXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.24.0} peerDependencies: svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: svelte: optional: true - svelte@5.35.6: - resolution: {integrity: sha512-p7PVLQYrvCxJuxzGfOv/l71hVuHC6EZk5UDjbt/bndMYaBcUV5sFjDsj+PSIYvz1vcfbG6inX83/xIUeik1xGA==} + svelte@5.46.1: + resolution: {integrity: sha512-ynjfCHD3nP2el70kN5Pmg37sSi0EjOm9FgHYQdC4giWG/hzO3AatzXXJJgP305uIhGQxSufJLuYWtkY8uK/8RA==} engines: {node: '>=18'} - tailwindcss@3.4.17: - resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} engines: {node: '>=14.0.0'} hasBin: true @@ -1833,11 +1838,13 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} - tinyexec@1.0.1: - resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -1856,30 +1863,40 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.36.0: - resolution: {integrity: sha512-fTCqxthY+h9QbEgSIBfL9iV6CvKDFuoxg6bHPNpJ9HIUzS+jy2lCEyCmGyZRWEBSaykqcDPf1SJ+BfCI8DRopA==} + typescript-eslint@8.50.1: + resolution: {integrity: sha512-ytTHO+SoYSbhAH9CrYnMhiLx8To6PSSvqnvXyPUgPETCvB6eBKmTI9w6XMPS3HsBRGkwTVBX+urA8dYQx6bHfQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - undici-types@7.8.0: - resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - unplugin-icons@22.1.0: - resolution: {integrity: sha512-ect2ZNtk1Zgwb0NVHd0C1IDW/MV+Jk/xaq4t8o6rYdVS3+L660ZdD5kTSQZvsgdwCvquRw+/wYn75hsweRjoIA==} + unplugin-icons@22.5.0: + resolution: {integrity: sha512-MBlMtT5RuMYZy4TZgqUL2OTtOdTUVsS1Mhj6G1pEzMlFJlEnq6mhUfoIt45gBWxHcsOdXJDWLg3pRZ+YmvAVWQ==} peerDependencies: '@svgr/core': '>=7.0.0' '@svgx/core': ^1.0.1 @@ -1901,12 +1918,12 @@ packages: vue-template-es2015-compiler: optional: true - unplugin@2.3.5: - resolution: {integrity: sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==} + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -1917,26 +1934,31 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + uuid@13.0.0: + resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} hasBin: true - vite@5.4.19: - resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} - engines: {node: ^18.0.0 || >=20.0.0} + vite@7.3.0: + resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: '@types/node': optional: true + jiti: + optional: true less: optional: true lightningcss: @@ -1951,6 +1973,10 @@ packages: optional: true terser: optional: true + tsx: + optional: true + yaml: + optional: true vitefu@1.1.1: resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} @@ -1972,14 +1998,6 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -1997,209 +2015,204 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yocto-queue@1.2.1: - resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} - zimmerframe@1.1.2: - resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.2.1: + resolution: {integrity: sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==} snapshots: '@alloc/quick-lru@5.2.0': {} - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 - '@antfu/install-pkg@1.1.0': dependencies: - package-manager-detector: 1.3.0 - tinyexec: 1.0.1 + package-manager-detector: 1.6.0 + tinyexec: 1.0.2 - '@antfu/utils@8.1.1': {} + '@epic-web/invariant@1.0.0': {} - '@esbuild/aix-ppc64@0.21.5': + '@esbuild/aix-ppc64@0.27.2': optional: true - '@esbuild/android-arm64@0.21.5': + '@esbuild/android-arm64@0.27.2': optional: true - '@esbuild/android-arm@0.21.5': + '@esbuild/android-arm@0.27.2': optional: true - '@esbuild/android-x64@0.21.5': + '@esbuild/android-x64@0.27.2': optional: true - '@esbuild/darwin-arm64@0.21.5': + '@esbuild/darwin-arm64@0.27.2': optional: true - '@esbuild/darwin-x64@0.21.5': + '@esbuild/darwin-x64@0.27.2': optional: true - '@esbuild/freebsd-arm64@0.21.5': + '@esbuild/freebsd-arm64@0.27.2': optional: true - '@esbuild/freebsd-x64@0.21.5': + '@esbuild/freebsd-x64@0.27.2': optional: true - '@esbuild/linux-arm64@0.21.5': + '@esbuild/linux-arm64@0.27.2': optional: true - '@esbuild/linux-arm@0.21.5': + '@esbuild/linux-arm@0.27.2': optional: true - '@esbuild/linux-ia32@0.21.5': + '@esbuild/linux-ia32@0.27.2': optional: true - '@esbuild/linux-loong64@0.21.5': + '@esbuild/linux-loong64@0.27.2': optional: true - '@esbuild/linux-mips64el@0.21.5': + '@esbuild/linux-mips64el@0.27.2': optional: true - '@esbuild/linux-ppc64@0.21.5': + '@esbuild/linux-ppc64@0.27.2': optional: true - '@esbuild/linux-riscv64@0.21.5': + '@esbuild/linux-riscv64@0.27.2': optional: true - '@esbuild/linux-s390x@0.21.5': + '@esbuild/linux-s390x@0.27.2': optional: true - '@esbuild/linux-x64@0.21.5': + '@esbuild/linux-x64@0.27.2': optional: true - '@esbuild/netbsd-x64@0.21.5': + '@esbuild/netbsd-arm64@0.27.2': optional: true - '@esbuild/openbsd-x64@0.21.5': + '@esbuild/netbsd-x64@0.27.2': optional: true - '@esbuild/sunos-x64@0.21.5': + '@esbuild/openbsd-arm64@0.27.2': optional: true - '@esbuild/win32-arm64@0.21.5': + '@esbuild/openbsd-x64@0.27.2': optional: true - '@esbuild/win32-ia32@0.21.5': + '@esbuild/openharmony-arm64@0.27.2': optional: true - '@esbuild/win32-x64@0.21.5': + '@esbuild/sunos-x64@0.27.2': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.30.1(jiti@2.4.2))': + '@esbuild/win32-arm64@0.27.2': + optional: true + + '@esbuild/win32-ia32@0.27.2': + optional: true + + '@esbuild/win32-x64@0.27.2': + optional: true + + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2(jiti@1.21.7))': dependencies: - eslint: 9.30.1(jiti@2.4.2) + eslint: 9.39.2(jiti@1.21.7) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} + '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@1.3.1(eslint@9.30.1(jiti@2.4.2))': - optionalDependencies: - eslint: 9.30.1(jiti@2.4.2) - - '@eslint/config-array@0.21.0': + '@eslint/compat@2.0.0(eslint@9.39.2(jiti@1.21.7))': dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.1 + '@eslint/core': 1.0.0 + optionalDependencies: + eslint: 9.39.2(jiti@1.21.7) + + '@eslint/config-array@0.21.1': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.3.0': {} + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 - '@eslint/core@0.14.0': + '@eslint/core@0.17.0': dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@0.15.1': + '@eslint/core@1.0.0': dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.1': + '@eslint/eslintrc@3.3.3': dependencies: ajv: 6.12.6 - debug: 4.4.1 + debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.30.1': {} + '@eslint/js@9.39.2': {} - '@eslint/object-schema@2.1.6': {} + '@eslint/object-schema@2.1.7': {} - '@eslint/plugin-kit@0.3.3': + '@eslint/plugin-kit@0.4.1': dependencies: - '@eslint/core': 0.15.1 + '@eslint/core': 0.17.0 levn: 0.4.1 - '@fastify/busboy@3.1.1': {} + '@fastify/busboy@3.2.0': {} '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.6': + '@humanfs/node@0.16.7': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/retry': 0.4.3 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.3': {} - '@iconify-json/material-symbols@1.2.29': + '@iconify-json/material-symbols@1.2.50': dependencies: '@iconify/types': 2.0.0 '@iconify/types@2.0.0': {} - '@iconify/utils@2.3.0': + '@iconify/utils@3.1.0': dependencies: '@antfu/install-pkg': 1.1.0 - '@antfu/utils': 8.1.1 '@iconify/types': 2.0.0 - debug: 4.4.1 - globals: 15.15.0 - kolorist: 1.8.0 - local-pkg: 1.1.1 - mlly: 1.7.4 - transitivePeerDependencies: - - supports-color + mlly: 1.8.0 - '@isaacs/cliui@8.0.2': + '@jridgewell/gen-mapping@0.3.13': dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/gen-mapping@0.3.12': + '@jridgewell/remapping@2.3.5': dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - '@jridgewell/trace-mapping': 0.3.29 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/sourcemap-codec@1.5.4': {} + '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.29': + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/sourcemap-codec': 1.5.5 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -2211,163 +2224,184 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 + fastq: 1.20.1 '@phc/format@1.0.0': {} - '@pkgjs/parseargs@0.11.0': - optional: true - '@polka/url@1.0.0-next.29': {} - '@rollup/plugin-commonjs@28.0.6(rollup@4.44.2)': + '@rollup/plugin-commonjs@28.0.9(rollup@4.54.0)': dependencies: - '@rollup/pluginutils': 5.2.0(rollup@4.44.2) + '@rollup/pluginutils': 5.3.0(rollup@4.54.0) commondir: 1.0.1 estree-walker: 2.0.2 - fdir: 6.4.6(picomatch@4.0.2) + fdir: 6.5.0(picomatch@4.0.3) is-reference: 1.2.1 - magic-string: 0.30.17 - picomatch: 4.0.2 + magic-string: 0.30.21 + picomatch: 4.0.3 optionalDependencies: - rollup: 4.44.2 + rollup: 4.54.0 - '@rollup/plugin-json@6.1.0(rollup@4.44.2)': + '@rollup/plugin-json@6.1.0(rollup@4.54.0)': dependencies: - '@rollup/pluginutils': 5.2.0(rollup@4.44.2) + '@rollup/pluginutils': 5.3.0(rollup@4.54.0) optionalDependencies: - rollup: 4.44.2 + rollup: 4.54.0 - '@rollup/plugin-node-resolve@16.0.1(rollup@4.44.2)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.54.0)': dependencies: - '@rollup/pluginutils': 5.2.0(rollup@4.44.2) + '@rollup/pluginutils': 5.3.0(rollup@4.54.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 - resolve: 1.22.10 + resolve: 1.22.11 optionalDependencies: - rollup: 4.44.2 + rollup: 4.54.0 - '@rollup/pluginutils@5.2.0(rollup@4.44.2)': + '@rollup/pluginutils@5.3.0(rollup@4.54.0)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 - picomatch: 4.0.2 + picomatch: 4.0.3 optionalDependencies: - rollup: 4.44.2 + rollup: 4.54.0 - '@rollup/rollup-android-arm-eabi@4.44.2': + '@rollup/rollup-android-arm-eabi@4.54.0': optional: true - '@rollup/rollup-android-arm64@4.44.2': + '@rollup/rollup-android-arm64@4.54.0': optional: true - '@rollup/rollup-darwin-arm64@4.44.2': + '@rollup/rollup-darwin-arm64@4.54.0': optional: true - '@rollup/rollup-darwin-x64@4.44.2': + '@rollup/rollup-darwin-x64@4.54.0': optional: true - '@rollup/rollup-freebsd-arm64@4.44.2': + '@rollup/rollup-freebsd-arm64@4.54.0': optional: true - '@rollup/rollup-freebsd-x64@4.44.2': + '@rollup/rollup-freebsd-x64@4.54.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.44.2': + '@rollup/rollup-linux-arm-gnueabihf@4.54.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.44.2': + '@rollup/rollup-linux-arm-musleabihf@4.54.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.44.2': + '@rollup/rollup-linux-arm64-gnu@4.54.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.44.2': + '@rollup/rollup-linux-arm64-musl@4.54.0': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.44.2': + '@rollup/rollup-linux-loong64-gnu@4.54.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.44.2': + '@rollup/rollup-linux-ppc64-gnu@4.54.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.44.2': + '@rollup/rollup-linux-riscv64-gnu@4.54.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.44.2': + '@rollup/rollup-linux-riscv64-musl@4.54.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.44.2': + '@rollup/rollup-linux-s390x-gnu@4.54.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.44.2': + '@rollup/rollup-linux-x64-gnu@4.54.0': optional: true - '@rollup/rollup-linux-x64-musl@4.44.2': + '@rollup/rollup-linux-x64-musl@4.54.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.44.2': + '@rollup/rollup-openharmony-arm64@4.54.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.44.2': + '@rollup/rollup-win32-arm64-msvc@4.54.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.44.2': + '@rollup/rollup-win32-ia32-msvc@4.54.0': optional: true - '@sveltejs/acorn-typescript@1.0.5(acorn@8.15.0)': + '@rollup/rollup-win32-x64-gnu@4.54.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.54.0': + optional: true + + '@standard-schema/spec@1.1.0': {} + + '@sveltejs/acorn-typescript@1.0.8(acorn@8.15.0)': dependencies: acorn: 8.15.0 - '@sveltejs/adapter-node@5.2.13(@sveltejs/kit@2.22.5(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)))(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)))': + '@sveltejs/adapter-node@5.4.0(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)))': dependencies: - '@rollup/plugin-commonjs': 28.0.6(rollup@4.44.2) - '@rollup/plugin-json': 6.1.0(rollup@4.44.2) - '@rollup/plugin-node-resolve': 16.0.1(rollup@4.44.2) - '@sveltejs/kit': 2.22.5(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)))(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)) - rollup: 4.44.2 + '@rollup/plugin-commonjs': 28.0.9(rollup@4.54.0) + '@rollup/plugin-json': 6.1.0(rollup@4.54.0) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.54.0) + '@sveltejs/kit': 2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)) + rollup: 4.54.0 - '@sveltejs/kit@2.22.5(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)))(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13))': + '@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0))': dependencies: - '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)) + '@standard-schema/spec': 1.1.0 + '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 - devalue: 5.1.1 + devalue: 5.6.1 esm-env: 1.2.2 kleur: 4.1.5 - magic-string: 0.30.17 + magic-string: 0.30.21 mrmime: 2.0.1 sade: 1.8.1 - set-cookie-parser: 2.7.1 - sirv: 3.0.1 - svelte: 5.35.6 - vite: 5.4.19(@types/node@24.0.13) + set-cookie-parser: 2.7.2 + sirv: 3.0.2 + svelte: 5.46.1 + vite: 7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0) - '@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)))(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)) - debug: 4.4.1 - svelte: 5.35.6 - vite: 5.4.19(@types/node@24.0.13) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)) + debug: 4.4.3 + svelte: 5.46.1 + vite: 7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13))': + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)))(svelte@5.35.6)(vite@5.4.19(@types/node@24.0.13)) - debug: 4.4.1 + '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)) + debug: 4.4.3 deepmerge: 4.3.1 - kleur: 4.1.5 - magic-string: 0.30.17 - svelte: 5.35.6 - vite: 5.4.19(@types/node@24.0.13) - vitefu: 1.1.1(vite@5.4.19(@types/node@24.0.13)) + magic-string: 0.30.21 + svelte: 5.46.1 + vite: 7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0) + vitefu: 1.1.1(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)) transitivePeerDependencies: - supports-color + '@tanstack/svelte-virtual@3.13.13(svelte@5.46.1)': + dependencies: + '@tanstack/virtual-core': 3.13.13 + svelte: 5.46.1 + + '@tanstack/virtual-core@3.13.13': {} + + '@trpc/client@11.8.1(@trpc/server@11.8.1(typescript@5.9.3))(typescript@5.9.3)': + dependencies: + '@trpc/server': 11.8.1(typescript@5.9.3) + typescript: 5.9.3 + + '@trpc/server@11.8.1(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + '@types/cookie@0.6.0': {} '@types/estree@1.0.8': {} @@ -2380,110 +2414,109 @@ snapshots: '@types/node-schedule@2.1.8': dependencies: - '@types/node': 24.0.13 + '@types/node': 25.0.3 - '@types/node@24.0.13': + '@types/node@25.0.3': dependencies: - undici-types: 7.8.0 + undici-types: 7.16.0 - '@types/pg@8.15.4': + '@types/pg@8.16.0': dependencies: - '@types/node': 24.0.13 + '@types/node': 25.0.3 pg-protocol: 1.10.3 pg-types: 2.2.0 '@types/resolve@1.20.2': {} - '@typescript-eslint/eslint-plugin@8.36.0(@typescript-eslint/parser@8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.36.0 - '@typescript-eslint/type-utils': 8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.36.0 - eslint: 9.30.1(jiti@2.4.2) - graphemer: 1.4.0 + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.50.1 + '@typescript-eslint/type-utils': 8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.50.1 + eslint: 9.39.2(jiti@1.21.7) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.36.0 - '@typescript-eslint/types': 8.36.0 - '@typescript-eslint/typescript-estree': 8.36.0(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.36.0 - debug: 4.4.1 - eslint: 9.30.1(jiti@2.4.2) - typescript: 5.8.3 + '@typescript-eslint/scope-manager': 8.50.1 + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.50.1 + debug: 4.4.3 + eslint: 9.39.2(jiti@1.21.7) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.36.0(typescript@5.8.3)': + '@typescript-eslint/project-service@8.50.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.36.0(typescript@5.8.3) - '@typescript-eslint/types': 8.36.0 - debug: 4.4.1 - typescript: 5.8.3 + '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.9.3) + '@typescript-eslint/types': 8.50.1 + debug: 4.4.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.36.0': + '@typescript-eslint/scope-manager@8.50.1': dependencies: - '@typescript-eslint/types': 8.36.0 - '@typescript-eslint/visitor-keys': 8.36.0 + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/visitor-keys': 8.50.1 - '@typescript-eslint/tsconfig-utils@8.36.0(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.50.1(typescript@5.9.3)': dependencies: - typescript: 5.8.3 + typescript: 5.9.3 - '@typescript-eslint/type-utils@8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.36.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) - debug: 4.4.1 - eslint: 9.30.1(jiti@2.4.2) - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.2(jiti@1.21.7) + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.36.0': {} + '@typescript-eslint/types@8.50.1': {} - '@typescript-eslint/typescript-estree@8.36.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.50.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.36.0(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.36.0(typescript@5.8.3) - '@typescript-eslint/types': 8.36.0 - '@typescript-eslint/visitor-keys': 8.36.0 - debug: 4.4.1 - fast-glob: 3.3.3 - is-glob: 4.0.3 + '@typescript-eslint/project-service': 8.50.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.9.3) + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/visitor-keys': 8.50.1 + debug: 4.4.3 minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + semver: 7.7.3 + tinyglobby: 0.2.15 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/utils@8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.36.0 - '@typescript-eslint/types': 8.36.0 - '@typescript-eslint/typescript-estree': 8.36.0(typescript@5.8.3) - eslint: 9.30.1(jiti@2.4.2) - typescript: 5.8.3 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.50.1 + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) + eslint: 9.39.2(jiti@1.21.7) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.36.0': + '@typescript-eslint/visitor-keys@8.50.1': dependencies: - '@typescript-eslint/types': 8.36.0 + '@typescript-eslint/types': 8.50.1 eslint-visitor-keys: 4.2.1 '@xmldom/xmldom@0.9.8': @@ -2502,16 +2535,10 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ansi-regex@5.0.1: {} - - ansi-regex@6.1.0: {} - ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - ansi-styles@6.2.1: {} - any-promise@1.3.0: {} anymatch@3.1.3: @@ -2521,10 +2548,11 @@ snapshots: arg@5.0.2: {} - argon2@0.43.0: + argon2@0.44.0: dependencies: '@phc/format': 1.0.0 - node-addon-api: 8.4.0 + cross-env: 10.1.0 + node-addon-api: 8.5.0 node-gyp-build: 4.8.4 argparse@2.0.1: {} @@ -2533,20 +2561,19 @@ snapshots: asynckit@0.4.0: {} - autoprefixer@10.4.21(postcss@8.5.6): + autoprefixer@10.4.23(postcss@8.5.6): dependencies: - browserslist: 4.25.1 - caniuse-lite: 1.0.30001727 - fraction.js: 4.3.7 - normalize-range: 0.1.2 + browserslist: 4.28.1 + caniuse-lite: 1.0.30001761 + fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.6 postcss-value-parser: 4.2.0 - axios@1.10.0: + axios@1.13.2: dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.3 + follow-redirects: 1.15.11 + form-data: 4.0.5 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -2555,6 +2582,8 @@ snapshots: balanced-match@1.0.2: {} + baseline-browser-mapping@2.9.11: {} + binary-extensions@2.3.0: {} brace-expansion@1.1.12: @@ -2570,26 +2599,27 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.25.1: + browserslist@4.28.1: dependencies: - caniuse-lite: 1.0.30001727 - electron-to-chromium: 1.5.182 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.1) + baseline-browser-mapping: 2.9.11 + caniuse-lite: 1.0.30001761 + electron-to-chromium: 1.5.267 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) - c12@3.0.4: + c12@3.3.3: dependencies: - chokidar: 4.0.3 + chokidar: 5.0.0 confbox: 0.2.2 defu: 6.1.4 - dotenv: 16.6.1 - exsolve: 1.0.7 + dotenv: 17.2.3 + exsolve: 1.0.8 giget: 2.0.0 - jiti: 2.4.2 + jiti: 2.6.1 ohash: 2.0.11 pathe: 2.0.3 - perfect-debounce: 1.0.0 - pkg-types: 2.2.0 + perfect-debounce: 2.0.0 + pkg-types: 2.3.0 rc9: 2.1.2 call-bind-apply-helpers@1.0.2: @@ -2601,7 +2631,7 @@ snapshots: camelcase-css@2.0.1: {} - caniuse-lite@1.0.30001727: {} + caniuse-lite@1.0.30001761: {} chalk@4.1.2: dependencies: @@ -2624,6 +2654,10 @@ snapshots: dependencies: readdirp: 4.1.2 + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + citty@0.1.6: dependencies: consola: 3.4.2 @@ -2654,9 +2688,18 @@ snapshots: cookie@0.6.0: {} + copy-anything@4.0.5: + dependencies: + is-what: 5.5.0 + cron-parser@4.9.0: dependencies: - luxon: 3.7.1 + luxon: 3.7.2 + + cross-env@10.1.0: + dependencies: + '@epic-web/invariant': 1.0.0 + cross-spawn: 7.0.6 cross-spawn@7.0.6: dependencies: @@ -2666,7 +2709,7 @@ snapshots: cssesc@3.0.0: {} - debug@4.4.1: + debug@4.4.3: dependencies: ms: 2.1.3 @@ -2680,15 +2723,15 @@ snapshots: destr@2.0.5: {} - devalue@5.1.1: {} + devalue@5.6.1: {} - dexie@4.0.11: {} + dexie@4.2.1: {} didyoumean@1.2.2: {} dlv@1.1.3: {} - dotenv@16.6.1: {} + dotenv@17.2.3: {} dunder-proto@1.0.1: dependencies: @@ -2696,13 +2739,7 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - eastasianwidth@0.2.0: {} - - electron-to-chromium@1.5.182: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} + electron-to-chromium@1.5.267: {} es-define-property@1.0.1: {} @@ -2719,63 +2756,66 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 - esbuild@0.21.5: + esbuild@0.27.2: optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 escalade@3.2.0: {} escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.5(eslint@9.30.1(jiti@2.4.2)): + eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@1.21.7)): dependencies: - eslint: 9.30.1(jiti@2.4.2) + eslint: 9.39.2(jiti@1.21.7) - eslint-plugin-svelte@3.10.1(eslint@9.30.1(jiti@2.4.2))(svelte@5.35.6): + eslint-plugin-svelte@3.13.1(eslint@9.39.2(jiti@1.21.7))(svelte@5.46.1): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) - '@jridgewell/sourcemap-codec': 1.5.4 - eslint: 9.30.1(jiti@2.4.2) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7)) + '@jridgewell/sourcemap-codec': 1.5.5 + eslint: 9.39.2(jiti@1.21.7) esutils: 2.0.3 - globals: 16.3.0 + globals: 16.5.0 known-css-properties: 0.37.0 postcss: 8.5.6 postcss-load-config: 3.1.4(postcss@8.5.6) postcss-safe-parser: 7.0.1(postcss@8.5.6) - semver: 7.7.2 - svelte-eslint-parser: 1.2.0(svelte@5.35.6) + semver: 7.7.3 + svelte-eslint-parser: 1.4.1(svelte@5.46.1) optionalDependencies: - svelte: 5.35.6 + svelte: 5.46.1 transitivePeerDependencies: - ts-node - eslint-plugin-tailwindcss@3.18.0(tailwindcss@3.4.17): + eslint-plugin-tailwindcss@3.18.2(tailwindcss@3.4.19(yaml@2.8.0)): dependencies: fast-glob: 3.3.3 postcss: 8.5.6 - tailwindcss: 3.4.17 + tailwindcss: 3.4.19(yaml@2.8.0) eslint-scope@8.4.0: dependencies: @@ -2786,25 +2826,24 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.30.1(jiti@2.4.2): + eslint@9.39.2(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.0 - '@eslint/core': 0.14.0 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.30.1 - '@eslint/plugin-kit': 0.3.3 - '@humanfs/node': 0.16.6 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.3 + '@eslint/js': 9.39.2 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -2824,7 +2863,7 @@ snapshots: natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: - jiti: 2.4.2 + jiti: 1.21.7 transitivePeerDependencies: - supports-color @@ -2840,9 +2879,9 @@ snapshots: dependencies: estraverse: 5.3.0 - esrap@2.1.0: + esrap@2.2.1: dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/sourcemap-codec': 1.5.5 esrecurse@4.3.0: dependencies: @@ -2854,11 +2893,11 @@ snapshots: esutils@2.0.3: {} - exifreader@4.31.1: + exifreader@4.33.1: optionalDependencies: '@xmldom/xmldom': 0.9.8 - exsolve@1.0.7: {} + exsolve@1.0.8: {} fast-deep-equal@3.1.3: {} @@ -2874,13 +2913,13 @@ snapshots: fast-levenshtein@2.0.6: {} - fastq@1.19.1: + fastq@1.20.1: dependencies: reusify: 1.1.0 - fdir@6.4.6(picomatch@4.0.2): + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: - picomatch: 4.0.2 + picomatch: 4.0.3 file-entry-cache@8.0.0: dependencies: @@ -2904,14 +2943,9 @@ snapshots: flatted@3.3.3: {} - follow-redirects@1.15.9: {} + follow-redirects@1.15.11: {} - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - form-data@4.0.3: + form-data@4.0.5: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -2919,7 +2953,7 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 - fraction.js@4.3.7: {} + fraction.js@5.3.4: {} fsevents@2.3.3: optional: true @@ -2949,8 +2983,8 @@ snapshots: citty: 0.1.6 consola: 3.4.2 defu: 6.1.4 - node-fetch-native: 1.6.6 - nypm: 0.6.0 + node-fetch-native: 1.6.7 + nypm: 0.6.2 pathe: 2.0.3 glob-parent@5.1.2: @@ -2961,25 +2995,12 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.4.5: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - globals@14.0.0: {} - globals@15.15.0: {} - - globals@16.3.0: {} + globals@16.5.0: {} gopd@1.2.0: {} - graphemer@1.4.0: {} - has-flag@4.0.0: {} has-symbols@1.1.0: {} @@ -3015,8 +3036,6 @@ snapshots: is-extglob@2.1.1: {} - is-fullwidth-code-point@3.0.0: {} - is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -3033,19 +3052,15 @@ snapshots: dependencies: '@types/estree': 1.0.8 - isexe@2.0.0: {} + is-what@5.5.0: {} - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 + isexe@2.0.0: {} jiti@1.21.7: {} - jiti@2.4.2: {} + jiti@2.6.1: {} - js-yaml@4.1.0: + js-yaml@4.1.1: dependencies: argparse: 2.0.1 @@ -3063,24 +3078,25 @@ snapshots: known-css-properties@0.37.0: {} - kolorist@1.8.0: {} - - kysely-ctl@0.13.1(kysely@0.28.2): + kysely-ctl@0.19.0(kysely@0.28.9)(typescript@5.9.3): dependencies: - c12: 3.0.4 + c12: 3.3.3 citty: 0.1.6 + confbox: 0.2.2 consola: 3.4.2 - jiti: 2.4.2 - kysely: 0.28.2 - nypm: 0.6.0 - ofetch: 1.4.1 + jiti: 2.6.1 + kysely: 0.28.9 + nypm: 0.6.2 + ofetch: 1.5.1 pathe: 2.0.3 - pkg-types: 2.2.0 - std-env: 3.9.0 + pkg-types: 2.3.0 + std-env: 3.10.0 + tsconfck: 3.1.6(typescript@5.9.3) transitivePeerDependencies: - magicast + - typescript - kysely@0.28.2: {} + kysely@0.28.9: {} levn@0.4.1: dependencies: @@ -3093,11 +3109,11 @@ snapshots: lines-and-columns@1.2.4: {} - local-pkg@1.1.1: + local-pkg@1.1.2: dependencies: - mlly: 1.7.4 - pkg-types: 2.2.0 - quansync: 0.2.10 + mlly: 1.8.0 + pkg-types: 2.3.0 + quansync: 0.2.11 locate-character@3.0.0: {} @@ -3109,15 +3125,13 @@ snapshots: long-timeout@0.1.1: {} - lru-cache@10.4.3: {} + lru-cache@11.2.4: {} - lru-cache@11.1.0: {} + luxon@3.7.2: {} - luxon@3.7.1: {} - - magic-string@0.30.17: + magic-string@0.30.21: dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/sourcemap-codec': 1.5.5 math-intrinsics@1.1.0: {} @@ -3134,7 +3148,7 @@ snapshots: dependencies: mime-db: 1.52.0 - mime@4.0.7: {} + mime@4.1.0: {} minimatch@3.1.2: dependencies: @@ -3144,9 +3158,7 @@ snapshots: dependencies: brace-expansion: 2.0.2 - minipass@7.1.2: {} - - mlly@1.7.4: + mlly@1.8.0: dependencies: acorn: 8.15.0 pathe: 2.0.3 @@ -3169,13 +3181,13 @@ snapshots: natural-compare@1.4.0: {} - node-addon-api@8.4.0: {} + node-addon-api@8.5.0: {} - node-fetch-native@1.6.6: {} + node-fetch-native@1.6.7: {} node-gyp-build@4.8.4: {} - node-releases@2.0.19: {} + node-releases@2.0.27: {} node-schedule@2.1.1: dependencies: @@ -3185,24 +3197,22 @@ snapshots: normalize-path@3.0.0: {} - normalize-range@0.1.2: {} - - nypm@0.6.0: + nypm@0.6.2: dependencies: citty: 0.1.6 consola: 3.4.2 pathe: 2.0.3 - pkg-types: 2.2.0 - tinyexec: 0.3.2 + pkg-types: 2.3.0 + tinyexec: 1.0.2 object-assign@4.1.1: {} object-hash@3.0.0: {} - ofetch@1.4.1: + ofetch@1.5.1: dependencies: destr: 2.0.5 - node-fetch-native: 1.6.6 + node-fetch-native: 1.6.7 ufo: 1.6.1 ohash@2.0.11: {} @@ -3220,17 +3230,15 @@ snapshots: dependencies: yocto-queue: 0.1.0 - p-limit@6.2.0: + p-limit@7.2.0: dependencies: - yocto-queue: 1.2.1 + yocto-queue: 1.2.2 p-locate@5.0.0: dependencies: p-limit: 3.1.0 - package-json-from-dist@1.0.1: {} - - package-manager-detector@1.3.0: {} + package-manager-detector@1.6.0: {} parent-module@1.0.1: dependencies: @@ -3242,14 +3250,9 @@ snapshots: path-parse@1.0.7: {} - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - pathe@2.0.3: {} - perfect-debounce@1.0.0: {} + perfect-debounce@2.0.0: {} pg-cloudflare@1.2.7: optional: true @@ -3268,7 +3271,7 @@ snapshots: dependencies: pg-int8: 1.0.1 postgres-array: 2.0.0 - postgres-bytea: 1.0.0 + postgres-bytea: 1.0.1 postgres-date: 1.0.7 postgres-interval: 1.2.0 @@ -3290,7 +3293,7 @@ snapshots: picomatch@2.3.1: {} - picomatch@4.0.2: {} + picomatch@4.0.3: {} pify@2.3.0: {} @@ -3299,13 +3302,13 @@ snapshots: pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.7.4 + mlly: 1.8.0 pathe: 2.0.3 - pkg-types@2.2.0: + pkg-types@2.3.0: dependencies: confbox: 0.2.2 - exsolve: 1.0.7 + exsolve: 1.0.8 pathe: 2.0.3 postcss-import@15.1.0(postcss@8.5.6): @@ -3313,9 +3316,9 @@ snapshots: postcss: 8.5.6 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.10 + resolve: 1.22.11 - postcss-js@4.0.1(postcss@8.5.6): + postcss-js@4.1.0(postcss@8.5.6): dependencies: camelcase-css: 2.0.1 postcss: 8.5.6 @@ -3327,12 +3330,13 @@ snapshots: optionalDependencies: postcss: 8.5.6 - postcss-load-config@4.0.2(postcss@8.5.6): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.0): dependencies: lilconfig: 3.1.3 - yaml: 2.8.0 optionalDependencies: + jiti: 1.21.7 postcss: 8.5.6 + yaml: 2.8.0 postcss-nested@6.2.0(postcss@8.5.6): dependencies: @@ -3352,7 +3356,7 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-selector-parser@7.1.0: + postcss-selector-parser@7.1.1: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 @@ -3367,7 +3371,7 @@ snapshots: postgres-array@2.0.0: {} - postgres-bytea@1.0.0: {} + postgres-bytea@1.0.1: {} postgres-date@1.0.7: {} @@ -3377,24 +3381,24 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.35.6): + prettier-plugin-svelte@3.4.1(prettier@3.7.4)(svelte@5.46.1): dependencies: - prettier: 3.6.2 - svelte: 5.35.6 + prettier: 3.7.4 + svelte: 5.46.1 - prettier-plugin-tailwindcss@0.6.14(prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.35.6))(prettier@3.6.2): + prettier-plugin-tailwindcss@0.7.2(prettier-plugin-svelte@3.4.1(prettier@3.7.4)(svelte@5.46.1))(prettier@3.7.4): dependencies: - prettier: 3.6.2 + prettier: 3.7.4 optionalDependencies: - prettier-plugin-svelte: 3.4.0(prettier@3.6.2)(svelte@5.35.6) + prettier-plugin-svelte: 3.4.1(prettier@3.7.4)(svelte@5.46.1) - prettier@3.6.2: {} + prettier@3.7.4: {} proxy-from-env@1.1.0: {} punycode@2.3.1: {} - quansync@0.2.10: {} + quansync@0.2.11: {} queue-microtask@1.2.3: {} @@ -3413,9 +3417,11 @@ snapshots: readdirp@4.1.2: {} + readdirp@5.0.0: {} + resolve-from@4.0.0: {} - resolve@1.22.10: + resolve@1.22.11: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 @@ -3423,30 +3429,32 @@ snapshots: reusify@1.1.0: {} - rollup@4.44.2: + rollup@4.54.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.44.2 - '@rollup/rollup-android-arm64': 4.44.2 - '@rollup/rollup-darwin-arm64': 4.44.2 - '@rollup/rollup-darwin-x64': 4.44.2 - '@rollup/rollup-freebsd-arm64': 4.44.2 - '@rollup/rollup-freebsd-x64': 4.44.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.44.2 - '@rollup/rollup-linux-arm-musleabihf': 4.44.2 - '@rollup/rollup-linux-arm64-gnu': 4.44.2 - '@rollup/rollup-linux-arm64-musl': 4.44.2 - '@rollup/rollup-linux-loongarch64-gnu': 4.44.2 - '@rollup/rollup-linux-powerpc64le-gnu': 4.44.2 - '@rollup/rollup-linux-riscv64-gnu': 4.44.2 - '@rollup/rollup-linux-riscv64-musl': 4.44.2 - '@rollup/rollup-linux-s390x-gnu': 4.44.2 - '@rollup/rollup-linux-x64-gnu': 4.44.2 - '@rollup/rollup-linux-x64-musl': 4.44.2 - '@rollup/rollup-win32-arm64-msvc': 4.44.2 - '@rollup/rollup-win32-ia32-msvc': 4.44.2 - '@rollup/rollup-win32-x64-msvc': 4.44.2 + '@rollup/rollup-android-arm-eabi': 4.54.0 + '@rollup/rollup-android-arm64': 4.54.0 + '@rollup/rollup-darwin-arm64': 4.54.0 + '@rollup/rollup-darwin-x64': 4.54.0 + '@rollup/rollup-freebsd-arm64': 4.54.0 + '@rollup/rollup-freebsd-x64': 4.54.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.54.0 + '@rollup/rollup-linux-arm-musleabihf': 4.54.0 + '@rollup/rollup-linux-arm64-gnu': 4.54.0 + '@rollup/rollup-linux-arm64-musl': 4.54.0 + '@rollup/rollup-linux-loong64-gnu': 4.54.0 + '@rollup/rollup-linux-ppc64-gnu': 4.54.0 + '@rollup/rollup-linux-riscv64-gnu': 4.54.0 + '@rollup/rollup-linux-riscv64-musl': 4.54.0 + '@rollup/rollup-linux-s390x-gnu': 4.54.0 + '@rollup/rollup-linux-x64-gnu': 4.54.0 + '@rollup/rollup-linux-x64-musl': 4.54.0 + '@rollup/rollup-openharmony-arm64': 4.54.0 + '@rollup/rollup-win32-arm64-msvc': 4.54.0 + '@rollup/rollup-win32-ia32-msvc': 4.54.0 + '@rollup/rollup-win32-x64-gnu': 4.54.0 + '@rollup/rollup-win32-x64-msvc': 4.54.0 fsevents: 2.3.3 run-parallel@1.2.0: @@ -3457,9 +3465,9 @@ snapshots: dependencies: mri: 1.2.0 - semver@7.7.2: {} + semver@7.7.3: {} - set-cookie-parser@2.7.1: {} + set-cookie-parser@2.7.2: {} shebang-command@2.0.0: dependencies: @@ -3467,9 +3475,7 @@ snapshots: shebang-regex@3.0.0: {} - signal-exit@4.1.0: {} - - sirv@3.0.1: + sirv@3.0.2: dependencies: '@polka/url': 1.0.0-next.29 mrmime: 2.0.1 @@ -3481,87 +3487,72 @@ snapshots: split2@4.2.0: {} - std-env@3.9.0: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 + std-env@3.10.0: {} strip-json-comments@3.1.1: {} - sucrase@3.35.0: + sucrase@3.35.1: dependencies: - '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 - glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.7 + tinyglobby: 0.2.15 ts-interface-checker: 0.1.13 + superjson@2.2.6: + dependencies: + copy-anything: 4.0.5 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.2.2(picomatch@4.0.2)(svelte@5.35.6)(typescript@5.8.3): + svelte-check@4.3.5(picomatch@4.0.3)(svelte@5.46.1)(typescript@5.9.3): dependencies: - '@jridgewell/trace-mapping': 0.3.29 + '@jridgewell/trace-mapping': 0.3.31 chokidar: 4.0.3 - fdir: 6.4.6(picomatch@4.0.2) + fdir: 6.5.0(picomatch@4.0.3) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.35.6 - typescript: 5.8.3 + svelte: 5.46.1 + typescript: 5.9.3 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.2.0(svelte@5.35.6): + svelte-eslint-parser@1.4.1(svelte@5.46.1): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 postcss: 8.5.6 postcss-scss: 4.0.9(postcss@8.5.6) - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 optionalDependencies: - svelte: 5.35.6 + svelte: 5.46.1 - svelte@5.35.6: + svelte@5.46.1: dependencies: - '@ampproject/remapping': 2.3.0 - '@jridgewell/sourcemap-codec': 1.5.4 - '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) '@types/estree': 1.0.8 acorn: 8.15.0 aria-query: 5.3.2 axobject-query: 4.1.0 clsx: 2.1.1 + devalue: 5.6.1 esm-env: 1.2.2 - esrap: 2.1.0 + esrap: 2.2.1 is-reference: 3.0.3 locate-character: 3.0.0 - magic-string: 0.30.17 - zimmerframe: 1.1.2 + magic-string: 0.30.21 + zimmerframe: 1.1.4 - tailwindcss@3.4.17: + tailwindcss@3.4.19(yaml@2.8.0): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -3579,14 +3570,15 @@ snapshots: picocolors: 1.1.1 postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) - postcss-js: 4.0.1(postcss@8.5.6) - postcss-load-config: 4.0.2(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.0) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 - resolve: 1.22.10 - sucrase: 3.35.0 + resolve: 1.22.11 + sucrase: 3.35.1 transitivePeerDependencies: - - ts-node + - tsx + - yaml thenify-all@1.6.0: dependencies: @@ -3596,9 +3588,12 @@ snapshots: dependencies: any-promise: 1.3.0 - tinyexec@0.3.2: {} + tinyexec@1.0.2: {} - tinyexec@1.0.1: {} + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 to-regex-range@5.0.1: dependencies: @@ -3606,53 +3601,59 @@ snapshots: totalist@3.0.1: {} - ts-api-utils@2.1.0(typescript@5.8.3): + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: - typescript: 5.8.3 + typescript: 5.9.3 ts-interface-checker@0.1.13: {} + tsconfck@3.1.6(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3): + typescript-eslint@8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.36.0(@typescript-eslint/parser@8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.30.1(jiti@2.4.2) - typescript: 5.8.3 + '@typescript-eslint/eslint-plugin': 8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.39.2(jiti@1.21.7) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - typescript@5.8.3: {} + typescript@5.9.3: {} ufo@1.6.1: {} - undici-types@7.8.0: {} + undici-types@7.16.0: {} - unplugin-icons@22.1.0(svelte@5.35.6): + unplugin-icons@22.5.0(svelte@5.46.1): dependencies: '@antfu/install-pkg': 1.1.0 - '@iconify/utils': 2.3.0 - debug: 4.4.1 - local-pkg: 1.1.1 - unplugin: 2.3.5 + '@iconify/utils': 3.1.0 + debug: 4.4.3 + local-pkg: 1.1.2 + unplugin: 2.3.11 optionalDependencies: - svelte: 5.35.6 + svelte: 5.46.1 transitivePeerDependencies: - supports-color - unplugin@2.3.5: + unplugin@2.3.11: dependencies: + '@jridgewell/remapping': 2.3.5 acorn: 8.15.0 - picomatch: 4.0.2 + picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 - update-browserslist-db@1.1.3(browserslist@4.25.1): + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: - browserslist: 4.25.1 + browserslist: 4.28.1 escalade: 3.2.0 picocolors: 1.1.1 @@ -3662,20 +3663,25 @@ snapshots: util-deprecate@1.0.2: {} - uuid@11.1.0: {} + uuid@13.0.0: {} - vite@5.4.19(@types/node@24.0.13): + vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0): dependencies: - esbuild: 0.21.5 + esbuild: 0.27.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.44.2 + rollup: 4.54.0 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.0.13 + '@types/node': 25.0.3 fsevents: 2.3.3 + jiti: 1.21.7 + yaml: 2.8.0 - vitefu@1.1.1(vite@5.4.19(@types/node@24.0.13)): + vitefu@1.1.1(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0)): optionalDependencies: - vite: 5.4.19(@types/node@24.0.13) + vite: 7.3.0(@types/node@25.0.3)(jiti@1.21.7)(yaml@2.8.0) webpack-virtual-modules@0.6.2: {} @@ -3685,28 +3691,17 @@ snapshots: 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 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - xtend@4.0.2: {} yaml@1.10.2: {} - yaml@2.8.0: {} + yaml@2.8.0: + optional: true yocto-queue@0.1.0: {} - yocto-queue@1.2.1: {} + yocto-queue@1.2.2: {} - zimmerframe@1.1.2: {} + zimmerframe@1.1.4: {} - zod@3.25.76: {} + zod@4.2.1: {} diff --git a/src/lib/components/atoms/buttons/FileThumbnailButton.svelte b/src/lib/components/atoms/buttons/FileThumbnailButton.svelte new file mode 100644 index 0000000..c18101c --- /dev/null +++ b/src/lib/components/atoms/buttons/FileThumbnailButton.svelte @@ -0,0 +1,42 @@ + + +{#if $info} + +{/if} diff --git a/src/lib/components/atoms/buttons/index.ts b/src/lib/components/atoms/buttons/index.ts index fc5022f..4ed77f2 100644 --- a/src/lib/components/atoms/buttons/index.ts +++ b/src/lib/components/atoms/buttons/index.ts @@ -1,5 +1,6 @@ export { default as ActionEntryButton } from "./ActionEntryButton.svelte"; export { default as Button } from "./Button.svelte"; export { default as EntryButton } from "./EntryButton.svelte"; +export { default as FileThumbnailButton } from "./FileThumbnailButton.svelte"; export { default as FloatingButton } from "./FloatingButton.svelte"; export { default as TextButton } from "./TextButton.svelte"; diff --git a/src/lib/components/molecules/Categories/Categories.svelte b/src/lib/components/molecules/Categories/Categories.svelte index a11313e..54368c6 100644 --- a/src/lib/components/molecules/Categories/Categories.svelte +++ b/src/lib/components/molecules/Categories/Categories.svelte @@ -3,7 +3,7 @@ import type { SvelteHTMLElements } from "svelte/elements"; import { get, type Writable } from "svelte/store"; import type { CategoryInfo } from "$lib/modules/filesystem"; - import { SortBy, sortEntries } from "$lib/modules/util"; + import { SortBy, sortEntries } from "$lib/utils"; import Category from "./Category.svelte"; import type { SelectedCategory } from "./service"; diff --git a/src/lib/components/molecules/labels/DirectoryEntryLabel.svelte b/src/lib/components/molecules/labels/DirectoryEntryLabel.svelte index 319e0df..e85665d 100644 --- a/src/lib/components/molecules/labels/DirectoryEntryLabel.svelte +++ b/src/lib/components/molecules/labels/DirectoryEntryLabel.svelte @@ -3,6 +3,7 @@ import { IconLabel } from "$lib/components/molecules"; import IconFolder from "~icons/material-symbols/folder"; + import IconDriveFolderUpload from "~icons/material-symbols/drive-folder-upload"; import IconDraft from "~icons/material-symbols/draft"; interface Props { @@ -11,7 +12,7 @@ subtext?: string; textClass?: ClassValue; thumbnail?: string; - type: "directory" | "file"; + type: "directory" | "parent-directory" | "file"; } let { @@ -30,6 +31,8 @@ {name} {:else if type === "directory"} + {:else if type === "parent-directory"} + {:else} {/if} diff --git a/src/lib/components/organisms/Category/Category.svelte b/src/lib/components/organisms/Category/Category.svelte index 295bf99..ce3abcd 100644 --- a/src/lib/components/organisms/Category/Category.svelte +++ b/src/lib/components/organisms/Category/Category.svelte @@ -4,8 +4,8 @@ import { CheckBox } from "$lib/components/atoms"; import { SubCategories, type SelectedCategory } from "$lib/components/molecules"; import { getFileInfo, type FileInfo, type CategoryInfo } from "$lib/modules/filesystem"; - import { SortBy, sortEntries } from "$lib/modules/util"; import { masterKeyStore } from "$lib/stores"; + import { SortBy, sortEntries } from "$lib/utils"; import File from "./File.svelte"; import type { SelectedFile } from "./service"; diff --git a/src/lib/components/organisms/Category/File.svelte b/src/lib/components/organisms/Category/File.svelte index 7d49cf3..8e3fc12 100644 --- a/src/lib/components/organisms/Category/File.svelte +++ b/src/lib/components/organisms/Category/File.svelte @@ -32,7 +32,7 @@ }; $effect(() => { - if ($info?.dataKey) { + if ($info) { requestFileThumbnailDownload($info.id, $info.dataKey) .then((thumbnailUrl) => { thumbnail = thumbnailUrl ?? undefined; diff --git a/src/lib/components/organisms/Gallery.svelte b/src/lib/components/organisms/Gallery.svelte new file mode 100644 index 0000000..8537ac5 --- /dev/null +++ b/src/lib/components/organisms/Gallery.svelte @@ -0,0 +1,148 @@ + + +
+
+ {#each $virtualizer.getVirtualItems() as virtualRow (virtualRow.key)} + {@const row = rows[virtualRow.index]!} +
+ {#if row.type === "header"} +

{row.label}

+ {:else} +
+ {#each row.items as { info }} + + {/each} +
+ {/if} +
+ {/each} +
+ {#if $virtualizer.getVirtualItems().length === 0} +
+

+ {#if files.length === 0} + 업로드된 파일이 없어요. + {:else if filesWithDate.length === 0} + 파일 목록을 불러오고 있어요. + {:else} + 사진 또는 동영상이 없어요. + {/if} +

+
+ {/if} +
diff --git a/src/lib/components/organisms/index.ts b/src/lib/components/organisms/index.ts index 64f9861..9687bfe 100644 --- a/src/lib/components/organisms/index.ts +++ b/src/lib/components/organisms/index.ts @@ -1,3 +1,4 @@ export * from "./Category"; export { default as Category } from "./Category"; +export { default as Gallery } from "./Gallery.svelte"; export * from "./modals"; diff --git a/src/lib/hooks/callApi.ts b/src/lib/hooks/callApi.ts deleted file mode 100644 index 1699ec2..0000000 --- a/src/lib/hooks/callApi.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const callGetApi = async (input: RequestInfo, fetchInternal = fetch) => { - return await fetchInternal(input); -}; - -export const callPostApi = async (input: RequestInfo, payload?: T, fetchInternal = fetch) => { - return await fetchInternal(input, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: payload ? JSON.stringify(payload) : undefined, - }); -}; diff --git a/src/lib/hooks/index.ts b/src/lib/hooks/index.ts deleted file mode 100644 index e3b8dde..0000000 --- a/src/lib/hooks/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./callApi"; -export * from "./gotoStateful"; diff --git a/src/lib/modules/file/upload.ts b/src/lib/modules/file/upload.ts index b5b00a1..31aabd8 100644 --- a/src/lib/modules/file/upload.ts +++ b/src/lib/modules/file/upload.ts @@ -13,8 +13,6 @@ import { } from "$lib/modules/crypto"; import { generateThumbnail } from "$lib/modules/thumbnail"; import type { - DuplicateFileScanRequest, - DuplicateFileScanResponse, FileThumbnailUploadRequest, FileUploadRequest, FileUploadResponse, @@ -25,18 +23,17 @@ import { type HmacSecret, type FileUploadStatus, } from "$lib/stores"; +import { trpc } from "$trpc/client"; const requestDuplicateFileScan = limitFunction( async (file: File, hmacSecret: HmacSecret, onDuplicate: () => Promise) => { const fileBuffer = await file.arrayBuffer(); const fileSigned = encodeToBase64(await signMessageHmac(fileBuffer, hmacSecret.secret)); - const res = await axios.post("/api/file/scanDuplicates", { + const files = await trpc().file.listByHash.query({ hskVersion: hmacSecret.version, contentHmac: fileSigned, - } satisfies DuplicateFileScanRequest); - const { files }: DuplicateFileScanResponse = res.data; - + }); if (files.length === 0 || (await onDuplicate())) { return { fileBuffer, fileSigned }; } else { diff --git a/src/lib/modules/filesystem.ts b/src/lib/modules/filesystem.ts index c160534..9f447bf 100644 --- a/src/lib/modules/filesystem.ts +++ b/src/lib/modules/filesystem.ts @@ -1,5 +1,5 @@ +import { TRPCClientError } from "@trpc/client"; import { get, writable, type Writable } from "svelte/store"; -import { callGetApi } from "$lib/hooks"; import { getDirectoryInfos as getDirectoryInfosFromIndexedDB, getDirectoryInfo as getDirectoryInfoFromIndexedDB, @@ -18,16 +18,12 @@ import { type CategoryId, } from "$lib/indexedDB"; import { unwrapDataKey, decryptString } from "$lib/modules/crypto"; -import type { - CategoryInfoResponse, - CategoryFileListResponse, - DirectoryInfoResponse, - FileInfoResponse, -} from "$lib/server/schemas"; +import { trpc } from "$trpc/client"; export type DirectoryInfo = | { id: "root"; + parentId?: undefined; dataKey?: undefined; dataKeyVersion?: undefined; name?: undefined; @@ -36,6 +32,7 @@ export type DirectoryInfo = } | { id: number; + parentId: DirectoryId; dataKey?: CryptoKey; dataKeyVersion?: Date; name: string; @@ -45,6 +42,7 @@ export type DirectoryInfo = export interface FileInfo { id: number; + parentId: DirectoryId; dataKey?: CryptoKey; dataKeyVersion?: Date; contentType: string; @@ -97,7 +95,13 @@ const fetchDirectoryInfoFromIndexedDB = async ( info.set({ id, subDirectoryIds, fileIds }); } else { if (!directory) return; - info.set({ id, name: directory.name, subDirectoryIds, fileIds }); + info.set({ + id, + parentId: directory.parentId, + name: directory.name, + subDirectoryIds, + fileIds, + }); } }; @@ -106,20 +110,19 @@ const fetchDirectoryInfoFromServer = async ( info: Writable, masterKey: CryptoKey, ) => { - const res = await callGetApi(`/api/directory/${id}`); - if (res.status === 404) { - info.set(null); - await deleteDirectoryInfo(id as number); - return; - } else if (!res.ok) { + let data; + try { + data = await trpc().directory.get.query({ id }); + } catch (e) { + if (e instanceof TRPCClientError && e.data?.code === "NOT_FOUND") { + info.set(null); + await deleteDirectoryInfo(id as number); + return; + } throw new Error("Failed to fetch directory information"); } - const { - metadata, - subDirectories: subDirectoryIds, - files: fileIds, - }: DirectoryInfoResponse = await res.json(); + const { metadata, subDirectories: subDirectoryIds, files: fileIds } = data; if (id === "root") { info.set({ id, subDirectoryIds, fileIds }); @@ -129,6 +132,7 @@ const fetchDirectoryInfoFromServer = async ( info.set({ id, + parentId: metadata!.parent, dataKey, dataKeyVersion: new Date(metadata!.dekVersion), name, @@ -179,16 +183,17 @@ const fetchFileInfoFromServer = async ( info: Writable, masterKey: CryptoKey, ) => { - const res = await callGetApi(`/api/file/${id}`); - if (res.status === 404) { - info.set(null); - await deleteFileInfo(id); - return; - } else if (!res.ok) { + let metadata; + try { + metadata = await trpc().file.get.query({ id }); + } catch (e) { + if (e instanceof TRPCClientError && e.data?.code === "NOT_FOUND") { + info.set(null); + await deleteFileInfo(id); + return; + } throw new Error("Failed to fetch file information"); } - - const metadata: FileInfoResponse = await res.json(); const { dataKey } = await unwrapDataKey(metadata.dek, masterKey); const name = await decryptString(metadata.name, metadata.nameIv, dataKey); @@ -204,6 +209,7 @@ const fetchFileInfoFromServer = async ( info.set({ id, + parentId: metadata.parent, dataKey, dataKeyVersion: new Date(metadata.dekVersion), contentType: metadata.contentType, @@ -273,16 +279,19 @@ const fetchCategoryInfoFromServer = async ( info: Writable, masterKey: CryptoKey, ) => { - let res = await callGetApi(`/api/category/${id}`); - if (res.status === 404) { - info.set(null); - await deleteCategoryInfo(id as number); - return; - } else if (!res.ok) { + let data; + try { + data = await trpc().category.get.query({ id }); + } catch (e) { + if (e instanceof TRPCClientError && e.data?.code === "NOT_FOUND") { + info.set(null); + await deleteCategoryInfo(id as number); + return; + } throw new Error("Failed to fetch category information"); } - const { metadata, subCategories }: CategoryInfoResponse = await res.json(); + const { metadata, subCategories } = data; if (id === "root") { info.set({ id, subCategoryIds: subCategories }); @@ -290,12 +299,13 @@ const fetchCategoryInfoFromServer = async ( const { dataKey } = await unwrapDataKey(metadata!.dek, masterKey); const name = await decryptString(metadata!.name, metadata!.nameIv, dataKey); - res = await callGetApi(`/api/category/${id}/file/list?recurse=true`); - if (!res.ok) { + let files; + try { + files = await trpc().category.files.query({ id, recurse: true }); + } catch { throw new Error("Failed to fetch category files"); } - const { files }: CategoryFileListResponse = await res.json(); const filesMapped = files.map(({ file, isRecursive }) => ({ id: file, isRecursive })); let isFileRecursive: boolean | undefined = undefined; diff --git a/src/lib/modules/key.ts b/src/lib/modules/key.ts index 945902c..d5276a5 100644 --- a/src/lib/modules/key.ts +++ b/src/lib/modules/key.ts @@ -5,14 +5,14 @@ import type { ClientKeys } from "$lib/stores"; const serializedClientKeysSchema = z.intersection( z.object({ generator: z.literal("ArkVault"), - exportedAt: z.string().datetime(), + exportedAt: z.iso.datetime(), }), z.object({ version: z.literal(1), - encryptKey: z.string().base64().nonempty(), - decryptKey: z.string().base64().nonempty(), - signKey: z.string().base64().nonempty(), - verifyKey: z.string().base64().nonempty(), + encryptKey: z.base64().nonempty(), + decryptKey: z.base64().nonempty(), + signKey: z.base64().nonempty(), + verifyKey: z.base64().nonempty(), }), ); diff --git a/src/lib/modules/thumbnail.ts b/src/lib/modules/thumbnail.ts index 2d5cd55..d9a995b 100644 --- a/src/lib/modules/thumbnail.ts +++ b/src/lib/modules/thumbnail.ts @@ -67,10 +67,15 @@ const generateVideoThumbnail = (videoUrl: string, time = 0) => { return new Promise((resolve, reject) => { const video = document.createElement("video"); video.onloadedmetadata = () => { - video.currentTime = Math.min(time, video.duration); - video.requestVideoFrameCallback(() => { + if (video.videoWidth === 0 || video.videoHeight === 0) { + return reject(); + } + + const callbackId = video.requestVideoFrameCallback(() => { captureVideoThumbnail(video).then(resolve).catch(reject); + video.cancelVideoFrameCallback(callbackId); }); + video.currentTime = Math.min(time, video.duration); }; video.onerror = reject; diff --git a/src/lib/server/db/client.ts b/src/lib/server/db/client.ts index 373357a..272df61 100644 --- a/src/lib/server/db/client.ts +++ b/src/lib/server/db/client.ts @@ -98,22 +98,6 @@ export const createUserClient = async (userId: number, clientId: number) => { } }; -export const getAllUserClients = async (userId: number) => { - const userClients = await db - .selectFrom("user_client") - .selectAll() - .where("user_id", "=", userId) - .execute(); - return userClients.map( - ({ user_id, client_id, state }) => - ({ - userId: user_id, - clientId: client_id, - state, - }) satisfies UserClient, - ); -}; - export const getUserClient = async (userId: number, clientId: number) => { const userClient = await db .selectFrom("user_client") diff --git a/src/lib/server/db/index.ts b/src/lib/server/db/index.ts new file mode 100644 index 0000000..5c21deb --- /dev/null +++ b/src/lib/server/db/index.ts @@ -0,0 +1,10 @@ +export * as CategoryRepo from "./category"; +export * as ClientRepo from "./client"; +export * as FileRepo from "./file"; +export * as HskRepo from "./hsk"; +export * as MediaRepo from "./media"; +export * as MekRepo from "./mek"; +export * as SessionRepo from "./session"; +export * as UserRepo from "./user"; + +export * from "./error"; diff --git a/src/lib/server/db/mek.ts b/src/lib/server/db/mek.ts index d6eecb0..65d00f8 100644 --- a/src/lib/server/db/mek.ts +++ b/src/lib/server/db/mek.ts @@ -60,19 +60,6 @@ export const registerInitialMek = async ( }); }; -export const getInitialMek = async (userId: number) => { - const mek = await db - .selectFrom("master_encryption_key") - .selectAll() - .where("user_id", "=", userId) - .where("version", "=", 1) - .limit(1) - .executeTakeFirst(); - return mek - ? ({ userId: mek.user_id, version: mek.version, state: mek.state } satisfies Mek) - : null; -}; - export const getAllValidClientMeks = async (userId: number, clientId: number) => { const clientMeks = await db .selectFrom("client_master_encryption_key") diff --git a/src/lib/server/db/user.ts b/src/lib/server/db/user.ts index 3964a94..f718d4f 100644 --- a/src/lib/server/db/user.ts +++ b/src/lib/server/db/user.ts @@ -27,10 +27,6 @@ export const getUserByEmail = async (email: string) => { return user ? (user satisfies User) : null; }; -export const setUserNickname = async (userId: number, nickname: string) => { - await db.updateTable("user").set({ nickname }).where("id", "=", userId).execute(); -}; - export const setUserPassword = async (userId: number, password: string) => { await db.updateTable("user").set({ password }).where("id", "=", userId).execute(); }; diff --git a/src/lib/server/middlewares/authenticate.ts b/src/lib/server/middlewares/authenticate.ts index 8585bce..ecd1adf 100644 --- a/src/lib/server/middlewares/authenticate.ts +++ b/src/lib/server/middlewares/authenticate.ts @@ -1,13 +1,7 @@ import { error, redirect, type Handle } from "@sveltejs/kit"; -import env from "$lib/server/loadenv"; -import { authenticate, AuthenticationError } from "$lib/server/modules/auth"; +import { cookieOptions, authenticate, AuthenticationError } from "$lib/server/modules/auth"; export const authenticateMiddleware: Handle = async ({ event, resolve }) => { - const { pathname, search } = event.url; - if (pathname === "/api/auth/login") { - return await resolve(event); - } - try { const sessionIdSigned = event.cookies.get("sessionId"); if (!sessionIdSigned) { @@ -16,15 +10,11 @@ export const authenticateMiddleware: Handle = async ({ event, resolve }) => { const { ip, userAgent } = event.locals; event.locals.session = await authenticate(sessionIdSigned, ip, userAgent); - event.cookies.set("sessionId", sessionIdSigned, { - path: "/", - maxAge: env.session.exp / 1000, - secure: true, - sameSite: "strict", - }); + event.cookies.set("sessionId", sessionIdSigned, cookieOptions); } catch (e) { if (e instanceof AuthenticationError) { - if (pathname === "/auth/login") { + const { pathname, search } = event.url; + if (pathname === "/auth/login" || pathname.startsWith("/api/trpc")) { return await resolve(event); } else if (pathname.startsWith("/api")) { error(e.status, e.message); diff --git a/src/lib/server/modules/auth.ts b/src/lib/server/modules/auth.ts index d25033d..b736a49 100644 --- a/src/lib/server/modules/auth.ts +++ b/src/lib/server/modules/auth.ts @@ -1,20 +1,25 @@ import { error } from "@sveltejs/kit"; -import { getUserClient } from "$lib/server/db/client"; -import { IntegrityError } from "$lib/server/db/error"; -import { createSession, refreshSession } from "$lib/server/db/session"; +import { ClientRepo, SessionRepo, IntegrityError } from "$lib/server/db"; import env from "$lib/server/loadenv"; -import { issueSessionId, verifySessionId } from "$lib/server/modules/crypto"; +import { verifySessionId } from "$lib/server/modules/crypto"; -interface Session { +export interface Session { sessionId: string; userId: number; clientId?: number; } -interface ClientSession extends Session { +export interface ClientSession extends Session { clientId: number; } +export type SessionPermission = + | "any" + | "notClient" + | "anyClient" + | "pendingClient" + | "activeClient"; + export class AuthenticationError extends Error { constructor( public status: 400 | 401, @@ -25,11 +30,22 @@ export class AuthenticationError extends Error { } } -export const startSession = async (userId: number, ip: string, userAgent: string) => { - const { sessionId, sessionIdSigned } = await issueSessionId(32, env.session.secret); - await createSession(userId, sessionId, ip, userAgent); - return sessionIdSigned; -}; +export class AuthorizationError extends Error { + constructor( + public status: 403 | 500, + message: string, + ) { + super(message); + this.name = "AuthorizationError"; + } +} + +export const cookieOptions = { + path: "/", + maxAge: env.session.exp / 1000, + secure: true, + sameSite: "strict", +} as const; export const authenticate = async (sessionIdSigned: string, ip: string, userAgent: string) => { const sessionId = verifySessionId(sessionIdSigned, env.session.secret); @@ -38,7 +54,7 @@ export const authenticate = async (sessionIdSigned: string, ip: string, userAgen } try { - const { userId, clientId } = await refreshSession(sessionId, ip, userAgent); + const { userId, clientId } = await SessionRepo.refreshSession(sessionId, ip, userAgent); return { id: sessionId, userId, @@ -52,34 +68,12 @@ export const authenticate = async (sessionIdSigned: string, ip: string, userAgen } }; -export async function authorize(locals: App.Locals, requiredPermission: "any"): Promise; - -export async function authorize( +export const authorizeInternal = async ( locals: App.Locals, - requiredPermission: "notClient", -): Promise; - -export async function authorize( - locals: App.Locals, - requiredPermission: "anyClient", -): Promise; - -export async function authorize( - locals: App.Locals, - requiredPermission: "pendingClient", -): Promise; - -export async function authorize( - locals: App.Locals, - requiredPermission: "activeClient", -): Promise; - -export async function authorize( - locals: App.Locals, - requiredPermission: "any" | "notClient" | "anyClient" | "pendingClient" | "activeClient", -): Promise { + requiredPermission: SessionPermission, +): Promise => { if (!locals.session) { - error(500, "Unauthenticated"); + throw new AuthorizationError(500, "Unauthenticated"); } const { id: sessionId, userId, clientId } = locals.session; @@ -89,39 +83,63 @@ export async function authorize( break; case "notClient": if (clientId) { - error(403, "Forbidden"); + throw new AuthorizationError(403, "Forbidden"); } break; case "anyClient": if (!clientId) { - error(403, "Forbidden"); + throw new AuthorizationError(403, "Forbidden"); } break; case "pendingClient": { if (!clientId) { - error(403, "Forbidden"); + throw new AuthorizationError(403, "Forbidden"); } - const userClient = await getUserClient(userId, clientId); + const userClient = await ClientRepo.getUserClient(userId, clientId); if (!userClient) { - error(500, "Invalid session id"); + throw new AuthorizationError(500, "Invalid session id"); } else if (userClient.state !== "pending") { - error(403, "Forbidden"); + throw new AuthorizationError(403, "Forbidden"); } break; } case "activeClient": { if (!clientId) { - error(403, "Forbidden"); + throw new AuthorizationError(403, "Forbidden"); } - const userClient = await getUserClient(userId, clientId); + const userClient = await ClientRepo.getUserClient(userId, clientId); if (!userClient) { - error(500, "Invalid session id"); + throw new AuthorizationError(500, "Invalid session id"); } else if (userClient.state !== "active") { - error(403, "Forbidden"); + throw new AuthorizationError(403, "Forbidden"); } break; } } return { sessionId, userId, clientId }; +}; + +export async function authorize( + locals: App.Locals, + requiredPermission: "any" | "notClient", +): Promise; + +export async function authorize( + locals: App.Locals, + requiredPermission: "anyClient" | "pendingClient" | "activeClient", +): Promise; + +export async function authorize( + locals: App.Locals, + requiredPermission: SessionPermission, +): Promise { + try { + return await authorizeInternal(locals, requiredPermission); + } catch (e) { + if (e instanceof AuthorizationError) { + error(e.status, e.message); + } + throw e; + } } diff --git a/src/lib/server/modules/filesystem.ts b/src/lib/server/modules/filesystem.ts new file mode 100644 index 0000000..65cb9ec --- /dev/null +++ b/src/lib/server/modules/filesystem.ts @@ -0,0 +1,7 @@ +import { unlink } from "fs/promises"; + +export const safeUnlink = async (path: string | null | undefined) => { + if (path) { + await unlink(path).catch(console.error); + } +}; diff --git a/src/lib/server/modules/mek.ts b/src/lib/server/modules/mek.ts deleted file mode 100644 index 1605d75..0000000 --- a/src/lib/server/modules/mek.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { error } from "@sveltejs/kit"; -import { getUserClientWithDetails } from "$lib/server/db/client"; -import { getInitialMek } from "$lib/server/db/mek"; -import { verifySignature } from "$lib/server/modules/crypto"; - -export const isInitialMekNeeded = async (userId: number) => { - const initialMek = await getInitialMek(userId); - return !initialMek; -}; - -export const verifyClientEncMekSig = async ( - userId: number, - clientId: number, - version: number, - encMek: string, - encMekSig: string, -) => { - const userClient = await getUserClientWithDetails(userId, clientId); - if (!userClient) { - error(500, "Invalid session id"); - } - - const data = JSON.stringify({ version, key: encMek }); - return verifySignature(Buffer.from(data), encMekSig, userClient.sigPubKey); -}; diff --git a/src/lib/server/schemas/auth.ts b/src/lib/server/schemas/auth.ts deleted file mode 100644 index b413f9d..0000000 --- a/src/lib/server/schemas/auth.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { z } from "zod"; - -export const passwordChangeRequest = z.object({ - oldPassword: z.string().trim().nonempty(), - newPassword: z.string().trim().nonempty(), -}); -export type PasswordChangeRequest = z.input; - -export const loginRequest = z.object({ - email: z.string().email(), - password: z.string().trim().nonempty(), -}); -export type LoginRequest = z.input; - -export const sessionUpgradeRequest = z.object({ - encPubKey: z.string().base64().nonempty(), - sigPubKey: z.string().base64().nonempty(), -}); -export type SessionUpgradeRequest = z.input; - -export const sessionUpgradeResponse = z.object({ - id: z.number().int().positive(), - challenge: z.string().base64().nonempty(), -}); -export type SessionUpgradeResponse = z.output; - -export const sessionUpgradeVerifyRequest = z.object({ - id: z.number().int().positive(), - answerSig: z.string().base64().nonempty(), - force: z.boolean().default(false), -}); -export type SessionUpgradeVerifyRequest = z.input; diff --git a/src/lib/server/schemas/category.ts b/src/lib/server/schemas/category.ts index 55ae413..0bb07a7 100644 --- a/src/lib/server/schemas/category.ts +++ b/src/lib/server/schemas/category.ts @@ -1,55 +1,3 @@ import { z } from "zod"; -export const categoryIdSchema = z.union([z.literal("root"), z.number().int().positive()]); - -export const categoryInfoResponse = z.object({ - metadata: z - .object({ - parent: categoryIdSchema, - mekVersion: z.number().int().positive(), - dek: z.string().base64().nonempty(), - dekVersion: z.string().datetime(), - name: z.string().base64().nonempty(), - nameIv: z.string().base64().nonempty(), - }) - .optional(), - subCategories: z.number().int().positive().array(), -}); -export type CategoryInfoResponse = z.output; - -export const categoryFileAddRequest = z.object({ - file: z.number().int().positive(), -}); -export type CategoryFileAddRequest = z.input; - -export const categoryFileListResponse = z.object({ - files: z.array( - z.object({ - file: z.number().int().positive(), - isRecursive: z.boolean(), - }), - ), -}); -export type CategoryFileListResponse = z.output; - -export const categoryFileRemoveRequest = z.object({ - file: z.number().int().positive(), -}); -export type CategoryFileRemoveRequest = z.input; - -export const categoryRenameRequest = z.object({ - dekVersion: z.string().datetime(), - name: z.string().base64().nonempty(), - nameIv: z.string().base64().nonempty(), -}); -export type CategoryRenameRequest = z.input; - -export const categoryCreateRequest = z.object({ - parent: categoryIdSchema, - mekVersion: z.number().int().positive(), - dek: z.string().base64().nonempty(), - dekVersion: z.string().datetime(), - name: z.string().base64().nonempty(), - nameIv: z.string().base64().nonempty(), -}); -export type CategoryCreateRequest = z.input; +export const categoryIdSchema = z.union([z.literal("root"), z.int().positive()]); diff --git a/src/lib/server/schemas/client.ts b/src/lib/server/schemas/client.ts deleted file mode 100644 index 08a76b7..0000000 --- a/src/lib/server/schemas/client.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { z } from "zod"; - -export const clientListResponse = z.object({ - clients: z.array( - z.object({ - id: z.number().int().positive(), - state: z.enum(["pending", "active"]), - }), - ), -}); -export type ClientListResponse = z.output; - -export const clientRegisterRequest = z.object({ - encPubKey: z.string().base64().nonempty(), - sigPubKey: z.string().base64().nonempty(), -}); -export type ClientRegisterRequest = z.input; - -export const clientRegisterResponse = z.object({ - id: z.number().int().positive(), - challenge: z.string().base64().nonempty(), -}); -export type ClientRegisterResponse = z.output; - -export const clientRegisterVerifyRequest = z.object({ - id: z.number().int().positive(), - answerSig: z.string().base64().nonempty(), -}); -export type ClientRegisterVerifyRequest = z.input; - -export const clientStatusResponse = z.object({ - id: z.number().int().positive(), - state: z.enum(["pending", "active"]), - isInitialMekNeeded: z.boolean(), -}); -export type ClientStatusResponse = z.output; diff --git a/src/lib/server/schemas/directory.ts b/src/lib/server/schemas/directory.ts index ffd13bc..dba44b9 100644 --- a/src/lib/server/schemas/directory.ts +++ b/src/lib/server/schemas/directory.ts @@ -1,41 +1,3 @@ import { z } from "zod"; -export const directoryIdSchema = z.union([z.literal("root"), z.number().int().positive()]); - -export const directoryInfoResponse = z.object({ - metadata: z - .object({ - parent: directoryIdSchema, - mekVersion: z.number().int().positive(), - dek: z.string().base64().nonempty(), - dekVersion: z.string().datetime(), - name: z.string().base64().nonempty(), - nameIv: z.string().base64().nonempty(), - }) - .optional(), - subDirectories: z.number().int().positive().array(), - files: z.number().int().positive().array(), -}); -export type DirectoryInfoResponse = z.output; - -export const directoryDeleteResponse = z.object({ - deletedFiles: z.number().int().positive().array(), -}); -export type DirectoryDeleteResponse = z.output; - -export const directoryRenameRequest = z.object({ - dekVersion: z.string().datetime(), - name: z.string().base64().nonempty(), - nameIv: z.string().base64().nonempty(), -}); -export type DirectoryRenameRequest = z.input; - -export const directoryCreateRequest = z.object({ - parent: directoryIdSchema, - mekVersion: z.number().int().positive(), - dek: z.string().base64().nonempty(), - dekVersion: z.string().datetime(), - name: z.string().base64().nonempty(), - nameIv: z.string().base64().nonempty(), -}); -export type DirectoryCreateRequest = z.input; +export const directoryIdSchema = z.union([z.literal("root"), z.int().positive()]); diff --git a/src/lib/server/schemas/file.ts b/src/lib/server/schemas/file.ts index 8b9cfe9..811e590 100644 --- a/src/lib/server/schemas/file.ts +++ b/src/lib/server/schemas/file.ts @@ -2,90 +2,35 @@ import mime from "mime"; import { z } from "zod"; import { directoryIdSchema } from "./directory"; -export const fileInfoResponse = z.object({ - parent: directoryIdSchema, - mekVersion: z.number().int().positive(), - dek: z.string().base64().nonempty(), - dekVersion: z.string().datetime(), - contentType: z - .string() - .trim() - .nonempty() - .refine((value) => mime.getExtension(value) !== null), // MIME type - contentIv: z.string().base64().nonempty(), - name: z.string().base64().nonempty(), - nameIv: z.string().base64().nonempty(), - createdAt: z.string().base64().nonempty().optional(), - createdAtIv: z.string().base64().nonempty().optional(), - lastModifiedAt: z.string().base64().nonempty(), - lastModifiedAtIv: z.string().base64().nonempty(), - categories: z.number().int().positive().array(), -}); -export type FileInfoResponse = z.output; - -export const fileRenameRequest = z.object({ - dekVersion: z.string().datetime(), - name: z.string().base64().nonempty(), - nameIv: z.string().base64().nonempty(), -}); -export type FileRenameRequest = z.input; - -export const fileThumbnailInfoResponse = z.object({ - updatedAt: z.string().datetime(), - contentIv: z.string().base64().nonempty(), -}); -export type FileThumbnailInfoResponse = z.output; - export const fileThumbnailUploadRequest = z.object({ - dekVersion: z.string().datetime(), - contentIv: z.string().base64().nonempty(), + dekVersion: z.iso.datetime(), + contentIv: z.base64().nonempty(), }); export type FileThumbnailUploadRequest = z.input; -export const fileListResponse = z.object({ - files: z.number().int().positive().array(), -}); -export type FileListResponse = z.output; - -export const duplicateFileScanRequest = z.object({ - hskVersion: z.number().int().positive(), - contentHmac: z.string().base64().nonempty(), -}); -export type DuplicateFileScanRequest = z.input; - -export const duplicateFileScanResponse = z.object({ - files: z.number().int().positive().array(), -}); -export type DuplicateFileScanResponse = z.output; - -export const missingThumbnailFileScanResponse = z.object({ - files: z.number().int().positive().array(), -}); -export type MissingThumbnailFileScanResponse = z.output; - export const fileUploadRequest = z.object({ parent: directoryIdSchema, - mekVersion: z.number().int().positive(), - dek: z.string().base64().nonempty(), - dekVersion: z.string().datetime(), - hskVersion: z.number().int().positive(), - contentHmac: z.string().base64().nonempty(), + mekVersion: z.int().positive(), + dek: z.base64().nonempty(), + dekVersion: z.iso.datetime(), + hskVersion: z.int().positive(), + contentHmac: z.base64().nonempty(), contentType: z .string() .trim() .nonempty() .refine((value) => mime.getExtension(value) !== null), // MIME type - contentIv: z.string().base64().nonempty(), - name: z.string().base64().nonempty(), - nameIv: z.string().base64().nonempty(), - createdAt: z.string().base64().nonempty().optional(), - createdAtIv: z.string().base64().nonempty().optional(), - lastModifiedAt: z.string().base64().nonempty(), - lastModifiedAtIv: z.string().base64().nonempty(), + contentIv: z.base64().nonempty(), + name: z.base64().nonempty(), + nameIv: z.base64().nonempty(), + createdAt: z.base64().nonempty().optional(), + createdAtIv: z.base64().nonempty().optional(), + lastModifiedAt: z.base64().nonempty(), + lastModifiedAtIv: z.base64().nonempty(), }); export type FileUploadRequest = z.input; export const fileUploadResponse = z.object({ - file: z.number().int().positive(), + file: z.int().positive(), }); export type FileUploadResponse = z.output; diff --git a/src/lib/server/schemas/hsk.ts b/src/lib/server/schemas/hsk.ts deleted file mode 100644 index 6f6b428..0000000 --- a/src/lib/server/schemas/hsk.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod"; - -export const hmacSecretListResponse = z.object({ - hsks: z.array( - z.object({ - version: z.number().int().positive(), - state: z.enum(["active"]), - mekVersion: z.number().int().positive(), - hsk: z.string().base64().nonempty(), - }), - ), -}); -export type HmacSecretListResponse = z.output; - -export const initialHmacSecretRegisterRequest = z.object({ - mekVersion: z.number().int().positive(), - hsk: z.string().base64().nonempty(), -}); -export type InitialHmacSecretRegisterRequest = z.input; diff --git a/src/lib/server/schemas/index.ts b/src/lib/server/schemas/index.ts index 1fed0d0..f7a2bc1 100644 --- a/src/lib/server/schemas/index.ts +++ b/src/lib/server/schemas/index.ts @@ -1,8 +1,3 @@ -export * from "./auth"; export * from "./category"; -export * from "./client"; export * from "./directory"; export * from "./file"; -export * from "./hsk"; -export * from "./mek"; -export * from "./user"; diff --git a/src/lib/server/schemas/mek.ts b/src/lib/server/schemas/mek.ts deleted file mode 100644 index 3d6f468..0000000 --- a/src/lib/server/schemas/mek.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod"; - -export const masterKeyListResponse = z.object({ - meks: z.array( - z.object({ - version: z.number().int().positive(), - state: z.enum(["active", "retired"]), - mek: z.string().base64().nonempty(), - mekSig: z.string().base64().nonempty(), - }), - ), -}); -export type MasterKeyListResponse = z.output; - -export const initialMasterKeyRegisterRequest = z.object({ - mek: z.string().base64().nonempty(), - mekSig: z.string().base64().nonempty(), -}); -export type InitialMasterKeyRegisterRequest = z.input; diff --git a/src/lib/server/schemas/user.ts b/src/lib/server/schemas/user.ts deleted file mode 100644 index 9aec819..0000000 --- a/src/lib/server/schemas/user.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { z } from "zod"; - -export const userInfoResponse = z.object({ - email: z.string().email(), - nickname: z.string().nonempty(), -}); -export type UserInfoResponse = z.output; - -export const nicknameChangeRequest = z.object({ - newNickname: z.string().trim().min(2).max(8), -}); -export type NicknameChangeRequest = z.input; diff --git a/src/lib/server/services/auth.ts b/src/lib/server/services/auth.ts deleted file mode 100644 index 1c6867f..0000000 --- a/src/lib/server/services/auth.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { error } from "@sveltejs/kit"; -import argon2 from "argon2"; -import { getClient, getClientByPubKeys, getUserClient } from "$lib/server/db/client"; -import { IntegrityError } from "$lib/server/db/error"; -import { - upgradeSession, - deleteSession, - deleteAllOtherSessions, - registerSessionUpgradeChallenge, - consumeSessionUpgradeChallenge, -} from "$lib/server/db/session"; -import { getUser, getUserByEmail, setUserPassword } from "$lib/server/db/user"; -import env from "$lib/server/loadenv"; -import { startSession } from "$lib/server/modules/auth"; -import { verifySignature, generateChallenge } from "$lib/server/modules/crypto"; - -const hashPassword = async (password: string) => { - return await argon2.hash(password); -}; - -const verifyPassword = async (hash: string, password: string) => { - return await argon2.verify(hash, password); -}; - -export const changePassword = async ( - userId: number, - sessionId: string, - oldPassword: string, - newPassword: string, -) => { - if (oldPassword === newPassword) { - error(400, "Same passwords"); - } else if (newPassword.length < 8) { - error(400, "Too short password"); - } - - const user = await getUser(userId); - if (!user) { - error(500, "Invalid session id"); - } else if (!(await verifyPassword(user.password, oldPassword))) { - error(403, "Invalid password"); - } - - await setUserPassword(userId, await hashPassword(newPassword)); - await deleteAllOtherSessions(userId, sessionId); -}; - -export const login = async (email: string, password: string, ip: string, userAgent: string) => { - const user = await getUserByEmail(email); - if (!user || !(await verifyPassword(user.password, password))) { - error(401, "Invalid email or password"); - } - - return { sessionIdSigned: await startSession(user.id, ip, userAgent) }; -}; - -export const logout = async (sessionId: string) => { - await deleteSession(sessionId); -}; - -export const createSessionUpgradeChallenge = async ( - sessionId: string, - userId: number, - ip: string, - encPubKey: string, - sigPubKey: string, -) => { - const client = await getClientByPubKeys(encPubKey, sigPubKey); - const userClient = client ? await getUserClient(userId, client.id) : undefined; - if (!client) { - error(401, "Invalid public key(s)"); - } else if (!userClient || userClient.state === "challenging") { - error(403, "Unregistered client"); - } - - const { answer, challenge } = await generateChallenge(32, encPubKey); - const { id } = await registerSessionUpgradeChallenge( - sessionId, - client.id, - answer.toString("base64"), - ip, - new Date(Date.now() + env.challenge.sessionUpgradeExp), - ); - - return { id, challenge: challenge.toString("base64") }; -}; - -export const verifySessionUpgradeChallenge = async ( - sessionId: string, - userId: number, - ip: string, - challengeId: number, - answerSig: string, - force: boolean, -) => { - const challenge = await consumeSessionUpgradeChallenge(challengeId, sessionId, ip); - if (!challenge) { - error(403, "Invalid challenge answer"); - } - - const client = await getClient(challenge.clientId); - if (!client) { - error(500, "Invalid challenge answer"); - } else if ( - !verifySignature(Buffer.from(challenge.answer, "base64"), answerSig, client.sigPubKey) - ) { - error(403, "Invalid challenge answer signature"); - } - - try { - await upgradeSession(userId, sessionId, client.id, force); - } catch (e) { - if (e instanceof IntegrityError) { - if (e.message === "Session not found") { - error(500, "Invalid challenge answer"); - } else if (!force && e.message === "Session already exists") { - error(409, "Already logged in"); - } - } - throw e; - } -}; diff --git a/src/lib/server/services/category.ts b/src/lib/server/services/category.ts deleted file mode 100644 index cb3db7a..0000000 --- a/src/lib/server/services/category.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { error } from "@sveltejs/kit"; -import { - registerCategory, - getAllCategoriesByParent, - getCategory, - setCategoryEncName, - unregisterCategory, - type CategoryId, - type NewCategory, -} from "$lib/server/db/category"; -import { IntegrityError } from "$lib/server/db/error"; -import { - getAllFilesByCategory, - getFile, - addFileToCategory, - removeFileFromCategory, -} from "$lib/server/db/file"; -import type { Ciphertext } from "$lib/server/db/schema"; - -export const getCategoryInformation = async (userId: number, categoryId: CategoryId) => { - const category = categoryId !== "root" ? await getCategory(userId, categoryId) : undefined; - if (category === null) { - error(404, "Invalid category id"); - } - - const categories = await getAllCategoriesByParent(userId, categoryId); - return { - metadata: category && { - parentId: category.parentId ?? ("root" as const), - mekVersion: category.mekVersion, - encDek: category.encDek, - dekVersion: category.dekVersion, - encName: category.encName, - }, - categories: categories.map(({ id }) => id), - }; -}; - -export const deleteCategory = async (userId: number, categoryId: number) => { - try { - await unregisterCategory(userId, categoryId); - } catch (e) { - if (e instanceof IntegrityError && e.message === "Category not found") { - error(404, "Invalid category id"); - } - throw e; - } -}; - -export const addCategoryFile = async (userId: number, categoryId: number, fileId: number) => { - const category = await getCategory(userId, categoryId); - const file = await getFile(userId, fileId); - if (!category) { - error(404, "Invalid category id"); - } else if (!file) { - error(404, "Invalid file id"); - } - - try { - await addFileToCategory(fileId, categoryId); - } catch (e) { - if (e instanceof IntegrityError && e.message === "File already added to category") { - error(400, "File already added"); - } - throw e; - } -}; - -export const getCategoryFiles = async (userId: number, categoryId: number, recurse: boolean) => { - const category = await getCategory(userId, categoryId); - if (!category) { - error(404, "Invalid category id"); - } - - const files = await getAllFilesByCategory(userId, categoryId, recurse); - return { files }; -}; - -export const removeCategoryFile = async (userId: number, categoryId: number, fileId: number) => { - const category = await getCategory(userId, categoryId); - const file = await getFile(userId, fileId); - if (!category) { - error(404, "Invalid category id"); - } else if (!file) { - error(404, "Invalid file id"); - } - - try { - await removeFileFromCategory(fileId, categoryId); - } catch (e) { - if (e instanceof IntegrityError && e.message === "File not found in category") { - error(400, "File not added"); - } - throw e; - } -}; - -export const renameCategory = async ( - userId: number, - categoryId: number, - dekVersion: Date, - newEncName: Ciphertext, -) => { - try { - await setCategoryEncName(userId, categoryId, dekVersion, newEncName); - } catch (e) { - if (e instanceof IntegrityError) { - if (e.message === "Category not found") { - error(404, "Invalid category id"); - } else if (e.message === "Invalid DEK version") { - error(400, "Invalid DEK version"); - } - } - throw e; - } -}; - -export const createCategory = async (params: NewCategory) => { - const oneMinuteAgo = new Date(Date.now() - 60 * 1000); - const oneMinuteLater = new Date(Date.now() + 60 * 1000); - if (params.dekVersion <= oneMinuteAgo || params.dekVersion >= oneMinuteLater) { - error(400, "Invalid DEK version"); - } - - try { - await registerCategory(params); - } catch (e) { - if (e instanceof IntegrityError && e.message === "Inactive MEK version") { - error(400, "Inactive MEK version"); - } - throw e; - } -}; diff --git a/src/lib/server/services/client.ts b/src/lib/server/services/client.ts deleted file mode 100644 index 811e58c..0000000 --- a/src/lib/server/services/client.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { error } from "@sveltejs/kit"; -import { - createClient, - getClient, - getClientByPubKeys, - createUserClient, - getAllUserClients, - getUserClient, - setUserClientStateToPending, - registerUserClientChallenge, - consumeUserClientChallenge, -} from "$lib/server/db/client"; -import { IntegrityError } from "$lib/server/db/error"; -import { verifyPubKey, verifySignature, generateChallenge } from "$lib/server/modules/crypto"; -import { isInitialMekNeeded } from "$lib/server/modules/mek"; -import env from "$lib/server/loadenv"; - -export const getUserClientList = async (userId: number) => { - const userClients = await getAllUserClients(userId); - return { - userClients: userClients.map(({ clientId, state }) => ({ - id: clientId, - state: state as "pending" | "active", - })), - }; -}; - -const expiresAt = () => new Date(Date.now() + env.challenge.userClientExp); - -const createUserClientChallenge = async ( - ip: string, - userId: number, - clientId: number, - encPubKey: string, -) => { - const { answer, challenge } = await generateChallenge(32, encPubKey); - const { id } = await registerUserClientChallenge( - userId, - clientId, - answer.toString("base64"), - ip, - expiresAt(), - ); - return { id, challenge: challenge.toString("base64") }; -}; - -export const registerUserClient = async ( - userId: number, - ip: string, - encPubKey: string, - sigPubKey: string, -) => { - const client = await getClientByPubKeys(encPubKey, sigPubKey); - if (client) { - try { - await createUserClient(userId, client.id); - return await createUserClientChallenge(ip, userId, client.id, encPubKey); - } catch (e) { - if (e instanceof IntegrityError && e.message === "User client already exists") { - error(409, "Client already registered"); - } - throw e; - } - } else { - if (encPubKey === sigPubKey) { - error(400, "Same public keys"); - } else if (!verifyPubKey(encPubKey) || !verifyPubKey(sigPubKey)) { - error(400, "Invalid public key(s)"); - } - - try { - const { id: clientId } = await createClient(encPubKey, sigPubKey, userId); - return await createUserClientChallenge(ip, userId, clientId, encPubKey); - } catch (e) { - if (e instanceof IntegrityError && e.message === "Public key(s) already registered") { - error(409, "Public key(s) already used"); - } - throw e; - } - } -}; - -export const verifyUserClient = async ( - userId: number, - ip: string, - challengeId: number, - answerSig: string, -) => { - const challenge = await consumeUserClientChallenge(challengeId, userId, ip); - if (!challenge) { - error(403, "Invalid challenge answer"); - } - - const client = await getClient(challenge.clientId); - if (!client) { - error(500, "Invalid challenge answer"); - } else if ( - !verifySignature(Buffer.from(challenge.answer, "base64"), answerSig, client.sigPubKey) - ) { - error(403, "Invalid challenge answer signature"); - } - - await setUserClientStateToPending(userId, client.id); -}; - -export const getUserClientStatus = async (userId: number, clientId: number) => { - const userClient = await getUserClient(userId, clientId); - if (!userClient) { - error(500, "Invalid session id"); - } - - return { - state: userClient.state as "pending" | "active", - isInitialMekNeeded: await isInitialMekNeeded(userId), - }; -}; diff --git a/src/lib/server/services/directory.ts b/src/lib/server/services/directory.ts deleted file mode 100644 index fdab587..0000000 --- a/src/lib/server/services/directory.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { error } from "@sveltejs/kit"; -import { unlink } from "fs/promises"; -import { IntegrityError } from "$lib/server/db/error"; -import { - registerDirectory, - getAllDirectoriesByParent, - getDirectory, - setDirectoryEncName, - unregisterDirectory, - getAllFilesByParent, - type DirectoryId, - type NewDirectory, -} from "$lib/server/db/file"; -import type { Ciphertext } from "$lib/server/db/schema"; - -export const getDirectoryInformation = async (userId: number, directoryId: DirectoryId) => { - const directory = directoryId !== "root" ? await getDirectory(userId, directoryId) : undefined; - if (directory === null) { - error(404, "Invalid directory id"); - } - - const directories = await getAllDirectoriesByParent(userId, directoryId); - const files = await getAllFilesByParent(userId, directoryId); - return { - metadata: directory && { - parentId: directory.parentId ?? ("root" as const), - mekVersion: directory.mekVersion, - encDek: directory.encDek, - dekVersion: directory.dekVersion, - encName: directory.encName, - }, - directories: directories.map(({ id }) => id), - files: files.map(({ id }) => id), - }; -}; - -const safeUnlink = async (path: string | null) => { - if (path) { - await unlink(path).catch(console.error); - } -}; - -export const deleteDirectory = async (userId: number, directoryId: number) => { - try { - const files = await unregisterDirectory(userId, directoryId); - return { - files: files.map(({ id, path, thumbnailPath }) => { - safeUnlink(path); // Intended - safeUnlink(thumbnailPath); // Intended - return id; - }), - }; - } catch (e) { - if (e instanceof IntegrityError && e.message === "Directory not found") { - error(404, "Invalid directory id"); - } - throw e; - } -}; - -export const renameDirectory = async ( - userId: number, - directoryId: number, - dekVersion: Date, - newEncName: Ciphertext, -) => { - try { - await setDirectoryEncName(userId, directoryId, dekVersion, newEncName); - } catch (e) { - if (e instanceof IntegrityError) { - if (e.message === "Directory not found") { - error(404, "Invalid directory id"); - } else if (e.message === "Invalid DEK version") { - error(400, "Invalid DEK version"); - } - } - throw e; - } -}; - -export const createDirectory = async (params: NewDirectory) => { - const oneMinuteAgo = new Date(Date.now() - 60 * 1000); - const oneMinuteLater = new Date(Date.now() + 60 * 1000); - if (params.dekVersion <= oneMinuteAgo || params.dekVersion >= oneMinuteLater) { - error(400, "Invalid DEK version"); - } - - try { - await registerDirectory(params); - } catch (e) { - if (e instanceof IntegrityError && e.message === "Inactive MEK version") { - error(400, "Invalid MEK version"); - } - throw e; - } -}; diff --git a/src/lib/server/services/file.ts b/src/lib/server/services/file.ts index ab98dbf..9032ffb 100644 --- a/src/lib/server/services/file.ts +++ b/src/lib/server/services/file.ts @@ -1,72 +1,17 @@ import { error } from "@sveltejs/kit"; import { createHash } from "crypto"; import { createReadStream, createWriteStream } from "fs"; -import { mkdir, stat, unlink } from "fs/promises"; +import { mkdir, stat } from "fs/promises"; import { dirname } from "path"; import { Readable } from "stream"; import { pipeline } from "stream/promises"; import { v4 as uuidv4 } from "uuid"; -import { IntegrityError } from "$lib/server/db/error"; -import { - registerFile, - getAllFileIds, - getAllFileIdsByContentHmac, - getFile, - setFileEncName, - unregisterFile, - getAllFileCategories, - type NewFile, -} from "$lib/server/db/file"; -import { - updateFileThumbnail, - getFileThumbnail, - getMissingFileThumbnails, -} from "$lib/server/db/media"; -import type { Ciphertext } from "$lib/server/db/schema"; +import { FileRepo, MediaRepo, IntegrityError } from "$lib/server/db"; import env from "$lib/server/loadenv"; - -export const getFileInformation = async (userId: number, fileId: number) => { - const file = await getFile(userId, fileId); - if (!file) { - error(404, "Invalid file id"); - } - - const categories = await getAllFileCategories(fileId); - return { - parentId: file.parentId ?? ("root" as const), - mekVersion: file.mekVersion, - encDek: file.encDek, - dekVersion: file.dekVersion, - contentType: file.contentType, - encContentIv: file.encContentIv, - encName: file.encName, - encCreatedAt: file.encCreatedAt, - encLastModifiedAt: file.encLastModifiedAt, - categories: categories.map(({ id }) => id), - }; -}; - -const safeUnlink = async (path: string | null) => { - if (path) { - await unlink(path).catch(console.error); - } -}; - -export const deleteFile = async (userId: number, fileId: number) => { - try { - const { path, thumbnailPath } = await unregisterFile(userId, fileId); - safeUnlink(path); // Intended - safeUnlink(thumbnailPath); // Intended - } catch (e) { - if (e instanceof IntegrityError && e.message === "File not found") { - error(404, "Invalid file id"); - } - throw e; - } -}; +import { safeUnlink } from "$lib/server/modules/filesystem"; export const getFileStream = async (userId: number, fileId: number) => { - const file = await getFile(userId, fileId); + const file = await FileRepo.getFile(userId, fileId); if (!file) { error(404, "Invalid file id"); } @@ -78,37 +23,8 @@ export const getFileStream = async (userId: number, fileId: number) => { }; }; -export const renameFile = async ( - userId: number, - fileId: number, - dekVersion: Date, - newEncName: Ciphertext, -) => { - try { - await setFileEncName(userId, fileId, dekVersion, newEncName); - } catch (e) { - if (e instanceof IntegrityError) { - if (e.message === "File not found") { - error(404, "Invalid file id"); - } else if (e.message === "Invalid DEK version") { - error(400, "Invalid DEK version"); - } - } - throw e; - } -}; - -export const getFileThumbnailInformation = async (userId: number, fileId: number) => { - const thumbnail = await getFileThumbnail(userId, fileId); - if (!thumbnail) { - error(404, "File or its thumbnail not found"); - } - - return { updatedAt: thumbnail.updatedAt, encContentIv: thumbnail.encContentIv }; -}; - export const getFileThumbnailStream = async (userId: number, fileId: number) => { - const thumbnail = await getFileThumbnail(userId, fileId); + const thumbnail = await MediaRepo.getFileThumbnail(userId, fileId); if (!thumbnail) { error(404, "File or its thumbnail not found"); } @@ -133,7 +49,13 @@ export const uploadFileThumbnail = async ( try { await pipeline(encContentStream, createWriteStream(path, { flags: "wx", mode: 0o600 })); - const oldPath = await updateFileThumbnail(userId, fileId, dekVersion, path, encContentIv); + const oldPath = await MediaRepo.updateFileThumbnail( + userId, + fileId, + dekVersion, + path, + encContentIv, + ); safeUnlink(oldPath); // Intended } catch (e) { await safeUnlink(path); @@ -149,27 +71,8 @@ export const uploadFileThumbnail = async ( } }; -export const getFileList = async (userId: number) => { - const fileIds = await getAllFileIds(userId); - return { files: fileIds }; -}; - -export const scanDuplicateFiles = async ( - userId: number, - hskVersion: number, - contentHmac: string, -) => { - const fileIds = await getAllFileIdsByContentHmac(userId, hskVersion, contentHmac); - return { files: fileIds }; -}; - -export const scanMissingFileThumbnails = async (userId: number) => { - const fileIds = await getMissingFileThumbnails(userId); - return { files: fileIds }; -}; - export const uploadFile = async ( - params: Omit, + params: Omit, encContentStream: Readable, encContentHash: Promise, ) => { @@ -201,7 +104,7 @@ export const uploadFile = async ( throw new Error("Invalid checksum"); } - const { id: fileId } = await registerFile({ + const { id: fileId } = await FileRepo.registerFile({ ...params, path, encContentHash: hash, diff --git a/src/lib/server/services/hsk.ts b/src/lib/server/services/hsk.ts deleted file mode 100644 index c381c51..0000000 --- a/src/lib/server/services/hsk.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { error } from "@sveltejs/kit"; -import { IntegrityError } from "$lib/server/db/error"; -import { registerInitialHsk, getAllValidHsks } from "$lib/server/db/hsk"; - -export const getHskList = async (userId: number) => { - const hsks = await getAllValidHsks(userId); - return { - encHsks: hsks.map(({ version, state, mekVersion, encHsk }) => ({ - version, - state, - mekVersion, - encHsk, - })), - }; -}; - -export const registerInitialActiveHsk = async ( - userId: number, - createdBy: number, - mekVersion: number, - encHsk: string, -) => { - try { - await registerInitialHsk(userId, createdBy, mekVersion, encHsk); - } catch (e) { - if (e instanceof IntegrityError && e.message === "HSK already registered") { - error(409, "Initial HSK already registered"); - } - throw e; - } -}; diff --git a/src/lib/server/services/mek.ts b/src/lib/server/services/mek.ts deleted file mode 100644 index 097906a..0000000 --- a/src/lib/server/services/mek.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { error } from "@sveltejs/kit"; -import { setUserClientStateToActive } from "$lib/server/db/client"; -import { IntegrityError } from "$lib/server/db/error"; -import { registerInitialMek, getAllValidClientMeks } from "$lib/server/db/mek"; -import { verifyClientEncMekSig } from "$lib/server/modules/mek"; - -export const getClientMekList = async (userId: number, clientId: number) => { - const clientMeks = await getAllValidClientMeks(userId, clientId); - return { - encMeks: clientMeks.map(({ version, state, encMek, encMekSig }) => ({ - version, - state, - encMek, - encMekSig, - })), - }; -}; - -export const registerInitialActiveMek = async ( - userId: number, - createdBy: number, - encMek: string, - encMekSig: string, -) => { - if (!(await verifyClientEncMekSig(userId, createdBy, 1, encMek, encMekSig))) { - error(400, "Invalid signature"); - } - - try { - await registerInitialMek(userId, createdBy, encMek, encMekSig); - await setUserClientStateToActive(userId, createdBy); - } catch (e) { - if (e instanceof IntegrityError && e.message === "MEK already registered") { - error(409, "Initial MEK already registered"); - } - throw e; - } -}; diff --git a/src/lib/server/services/user.ts b/src/lib/server/services/user.ts deleted file mode 100644 index 5c06458..0000000 --- a/src/lib/server/services/user.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { error } from "@sveltejs/kit"; -import { getUser, setUserNickname } from "$lib/server/db/user"; - -export const getUserInformation = async (userId: number) => { - const user = await getUser(userId); - if (!user) { - error(500, "Invalid session id"); - } - - return { email: user.email, nickname: user.nickname }; -}; - -export const changeNickname = async (userId: number, nickname: string) => { - await setUserNickname(userId, nickname); -}; diff --git a/src/lib/services/auth.ts b/src/lib/services/auth.ts index d1975f4..56d67eb 100644 --- a/src/lib/services/auth.ts +++ b/src/lib/services/auth.ts @@ -1,10 +1,6 @@ -import { callPostApi } from "$lib/hooks"; +import { TRPCClientError } from "@trpc/client"; import { encodeToBase64, decryptChallenge, signMessageRSA } from "$lib/modules/crypto"; -import type { - SessionUpgradeRequest, - SessionUpgradeResponse, - SessionUpgradeVerifyRequest, -} from "$lib/server/schemas"; +import { trpc } from "$trpc/client"; export const requestSessionUpgrade = async ( encryptKeyBase64: string, @@ -13,27 +9,43 @@ export const requestSessionUpgrade = async ( signKey: CryptoKey, force = false, ) => { - let res = await callPostApi("/api/auth/upgradeSession", { - encPubKey: encryptKeyBase64, - sigPubKey: verifyKeyBase64, - }); - if (res.status === 403) return [false, "Unregistered client"] as const; - else if (!res.ok) return [false] as const; - - const { id, challenge }: SessionUpgradeResponse = await res.json(); + let id, challenge; + try { + ({ id, challenge } = await trpc().auth.upgrade.mutate({ + encPubKey: encryptKeyBase64, + sigPubKey: verifyKeyBase64, + })); + } catch (e) { + if (e instanceof TRPCClientError && e.data?.code === "FORBIDDEN") { + return [false, "Unregistered client"] as const; + } + return [false] as const; + } const answer = await decryptChallenge(challenge, decryptKey); const answerSig = await signMessageRSA(answer, signKey); - res = await callPostApi("/api/auth/upgradeSession/verify", { - id, - answerSig: encodeToBase64(answerSig), - force, - }); - if (res.status === 409) return [false, "Already logged in"] as const; - else return [res.ok] as const; + try { + await trpc().auth.verifyUpgrade.mutate({ + id, + answerSig: encodeToBase64(answerSig), + force, + }); + } catch (e) { + if (e instanceof TRPCClientError && e.data?.code === "CONFLICT") { + return [false, "Already logged in"] as const; + } + return [false] as const; + } + + return [true] as const; }; export const requestLogout = async () => { - const res = await callPostApi("/api/auth/logout"); - return res.ok; + try { + await trpc().auth.logout.mutate(); + return true; + } catch { + // TODO: Error Handling + return false; + } }; diff --git a/src/lib/services/category.ts b/src/lib/services/category.ts index 587df3f..c53a6f2 100644 --- a/src/lib/services/category.ts +++ b/src/lib/services/category.ts @@ -1,7 +1,6 @@ -import { callPostApi } from "$lib/hooks"; import { generateDataKey, wrapDataKey, encryptString } from "$lib/modules/crypto"; -import type { CategoryCreateRequest, CategoryFileRemoveRequest } from "$lib/server/schemas"; import type { MasterKey } from "$lib/stores"; +import { trpc } from "$trpc/client"; export const requestCategoryCreation = async ( name: string, @@ -11,21 +10,28 @@ export const requestCategoryCreation = async ( const { dataKey, dataKeyVersion } = await generateDataKey(); const nameEncrypted = await encryptString(name, dataKey); - const res = await callPostApi("/api/category/create", { - parent: parentId, - mekVersion: masterKey.version, - dek: await wrapDataKey(dataKey, masterKey.key), - dekVersion: dataKeyVersion.toISOString(), - name: nameEncrypted.ciphertext, - nameIv: nameEncrypted.iv, - }); - return res.ok; + try { + await trpc().category.create.mutate({ + parent: parentId, + mekVersion: masterKey.version, + dek: await wrapDataKey(dataKey, masterKey.key), + dekVersion: dataKeyVersion, + name: nameEncrypted.ciphertext, + nameIv: nameEncrypted.iv, + }); + return true; + } catch { + // TODO: Error Handling + return false; + } }; export const requestFileRemovalFromCategory = async (fileId: number, categoryId: number) => { - const res = await callPostApi( - `/api/category/${categoryId}/file/remove`, - { file: fileId }, - ); - return res.ok; + try { + await trpc().category.removeFile.mutate({ id: categoryId, file: fileId }); + return true; + } catch { + // TODO: Error Handling + return false; + } }; diff --git a/src/lib/services/file.ts b/src/lib/services/file.ts index 11742c8..da05824 100644 --- a/src/lib/services/file.ts +++ b/src/lib/services/file.ts @@ -1,4 +1,3 @@ -import { callGetApi } from "$lib/hooks"; import { getAllFileInfos } from "$lib/indexedDB/filesystem"; import { decryptData } from "$lib/modules/crypto"; import { @@ -11,11 +10,8 @@ import { downloadFile, } from "$lib/modules/file"; import { getThumbnailUrl } from "$lib/modules/thumbnail"; -import type { - FileThumbnailInfoResponse, - FileThumbnailUploadRequest, - FileListResponse, -} from "$lib/server/schemas"; +import type { FileThumbnailUploadRequest } from "$lib/server/schemas"; +import { trpc } from "$trpc/client"; export const requestFileDownload = async ( fileId: number, @@ -48,16 +44,20 @@ export const requestFileThumbnailUpload = async ( return await fetch(`/api/file/${fileId}/thumbnail/upload`, { method: "POST", body: form }); }; -export const requestFileThumbnailDownload = async (fileId: number, dataKey: CryptoKey) => { +export const requestFileThumbnailDownload = async (fileId: number, dataKey?: CryptoKey) => { const cache = await getFileThumbnailCache(fileId); - if (cache) return cache; + if (cache || !dataKey) return cache; - let res = await callGetApi(`/api/file/${fileId}/thumbnail`); - if (!res.ok) return null; + let thumbnailInfo; + try { + thumbnailInfo = await trpc().file.thumbnail.query({ id: fileId }); + } catch { + // TODO: Error Handling + return null; + } + const { contentIv: thumbnailEncryptedIv } = thumbnailInfo; - const { contentIv: thumbnailEncryptedIv }: FileThumbnailInfoResponse = await res.json(); - - res = await callGetApi(`/api/file/${fileId}/thumbnail/download`); + const res = await fetch(`/api/file/${fileId}/thumbnail/download`); if (!res.ok) return null; const thumbnailEncrypted = await res.arrayBuffer(); @@ -68,10 +68,14 @@ export const requestFileThumbnailDownload = async (fileId: number, dataKey: Cryp }; export const requestDeletedFilesCleanup = async () => { - const res = await callGetApi("/api/file/list"); - if (!res.ok) return; + let liveFiles; + try { + liveFiles = await trpc().file.list.query(); + } catch { + // TODO: Error Handling + return; + } - const { files: liveFiles }: FileListResponse = await res.json(); const liveFilesSet = new Set(liveFiles); const maybeCachedFiles = await getAllFileInfos(); diff --git a/src/lib/services/key.ts b/src/lib/services/key.ts index cecd241..fd89f74 100644 --- a/src/lib/services/key.ts +++ b/src/lib/services/key.ts @@ -1,4 +1,4 @@ -import { callGetApi, callPostApi } from "$lib/hooks"; +import { TRPCClientError } from "@trpc/client"; import { storeMasterKeys } from "$lib/indexedDB"; import { encodeToBase64, @@ -9,16 +9,9 @@ import { signMasterKeyWrapped, verifyMasterKeyWrapped, } from "$lib/modules/crypto"; -import type { - ClientRegisterRequest, - ClientRegisterResponse, - ClientRegisterVerifyRequest, - InitialHmacSecretRegisterRequest, - MasterKeyListResponse, - InitialMasterKeyRegisterRequest, -} from "$lib/server/schemas"; import { requestSessionUpgrade } from "$lib/services/auth"; import { masterKeyStore, type ClientKeys } from "$lib/stores"; +import { trpc } from "$trpc/client"; export const requestClientRegistration = async ( encryptKeyBase64: string, @@ -26,21 +19,22 @@ export const requestClientRegistration = async ( verifyKeyBase64: string, signKey: CryptoKey, ) => { - let res = await callPostApi("/api/client/register", { - encPubKey: encryptKeyBase64, - sigPubKey: verifyKeyBase64, - }); - if (!res.ok) return false; - - const { id, challenge }: ClientRegisterResponse = await res.json(); - const answer = await decryptChallenge(challenge, decryptKey); - const answerSig = await signMessageRSA(answer, signKey); - - res = await callPostApi("/api/client/register/verify", { - id, - answerSig: encodeToBase64(answerSig), - }); - return res.ok; + try { + const { id, challenge } = await trpc().client.register.mutate({ + encPubKey: encryptKeyBase64, + sigPubKey: verifyKeyBase64, + }); + const answer = await decryptChallenge(challenge, decryptKey); + const answerSig = await signMessageRSA(answer, signKey); + await trpc().client.verify.mutate({ + id, + answerSig: encodeToBase64(answerSig), + }); + return true; + } catch { + // TODO: Error Handling + return false; + } }; export const requestClientRegistrationAndSessionUpgrade = async ( @@ -73,10 +67,14 @@ export const requestClientRegistrationAndSessionUpgrade = async ( }; export const requestMasterKeyDownload = async (decryptKey: CryptoKey, verifyKey: CryptoKey) => { - const res = await callGetApi("/api/mek/list"); - if (!res.ok) return false; + let masterKeysWrapped; + try { + masterKeysWrapped = await trpc().mek.list.query(); + } catch { + // TODO: Error Handling + return false; + } - const { meks: masterKeysWrapped }: MasterKeyListResponse = await res.json(); const masterKeys = await Promise.all( masterKeysWrapped.map( async ({ version, state, mek: masterKeyWrapped, mekSig: masterKeyWrappedSig }) => { @@ -108,17 +106,30 @@ export const requestInitialMasterKeyAndHmacSecretRegistration = async ( hmacSecretWrapped: string, signKey: CryptoKey, ) => { - let res = await callPostApi("/api/mek/register/initial", { - mek: masterKeyWrapped, - mekSig: await signMasterKeyWrapped(masterKeyWrapped, 1, signKey), - }); - if (!res.ok) { - return res.status === 403 || res.status === 409; + try { + await trpc().mek.registerInitial.mutate({ + mek: masterKeyWrapped, + mekSig: await signMasterKeyWrapped(masterKeyWrapped, 1, signKey), + }); + } catch (e) { + if ( + e instanceof TRPCClientError && + (e.data?.code === "FORBIDDEN" || e.data?.code === "CONFLICT") + ) { + return true; + } + // TODO: Error Handling + return false; } - res = await callPostApi("/api/hsk/register/initial", { - mekVersion: 1, - hsk: hmacSecretWrapped, - }); - return res.ok; + try { + await trpc().hsk.registerInitial.mutate({ + mekVersion: 1, + hsk: hmacSecretWrapped, + }); + return true; + } catch { + // TODO: Error Handling + return false; + } }; diff --git a/src/lib/modules/util.ts b/src/lib/utils/format.ts similarity index 64% rename from src/lib/modules/util.ts rename to src/lib/utils/format.ts index 3fff89d..ce3b35c 100644 --- a/src/lib/modules/util.ts +++ b/src/lib/utils/format.ts @@ -7,6 +7,13 @@ export const formatDate = (date: Date) => { return `${year}. ${month}. ${day}.`; }; +export const formatDateSortable = (date: Date) => { + const year = date.getFullYear(); + const month = pad2(date.getMonth() + 1); + const day = pad2(date.getDate()); + return `${year}${month}${day}`; +}; + export const formatDateTime = (date: Date) => { const dateFormatted = formatDate(date); const hours = date.getHours(); @@ -32,32 +39,3 @@ export const truncateString = (str: string, maxLength = 20) => { if (str.length <= maxLength) return str; return `${str.slice(0, maxLength)}...`; }; - -export enum SortBy { - NAME_ASC, - NAME_DESC, -} - -type SortFunc = (a?: string, b?: string) => number; - -const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }); - -const sortByNameAsc: SortFunc = (a, b) => { - if (a && b) return collator.compare(a, b); - if (a) return -1; - if (b) return 1; - return 0; -}; - -const sortByNameDesc: SortFunc = (a, b) => -sortByNameAsc(a, b); - -export const sortEntries = (entries: T[], sortBy: SortBy) => { - let sortFunc: SortFunc; - if (sortBy === SortBy.NAME_ASC) { - sortFunc = sortByNameAsc; - } else { - sortFunc = sortByNameDesc; - } - - entries.sort((a, b) => sortFunc(a.name, b.name)); -}; diff --git a/src/lib/hooks/gotoStateful.ts b/src/lib/utils/gotoStateful.ts similarity index 100% rename from src/lib/hooks/gotoStateful.ts rename to src/lib/utils/gotoStateful.ts diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts new file mode 100644 index 0000000..1db9577 --- /dev/null +++ b/src/lib/utils/index.ts @@ -0,0 +1,3 @@ +export * from "./format"; +export * from "./gotoStateful"; +export * from "./sort"; diff --git a/src/lib/utils/sort.ts b/src/lib/utils/sort.ts new file mode 100644 index 0000000..2385e55 --- /dev/null +++ b/src/lib/utils/sort.ts @@ -0,0 +1,57 @@ +interface SortEntry { + name?: string; + date?: Date; +} + +export enum SortBy { + NAME_ASC, + NAME_DESC, + DATE_ASC, + DATE_DESC, +} + +type SortFunc = (a: SortEntry, b: SortEntry) => number; + +const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }); + +const sortByNameAsc: SortFunc = ({ name: a }, { name: b }) => { + if (a && b) return collator.compare(a, b); + if (a) return -1; + if (b) return 1; + return 0; +}; + +const sortByNameDesc: SortFunc = (a, b) => -sortByNameAsc(a, b); + +const sortByDateAsc: SortFunc = ({ date: a }, { date: b }) => { + if (a && b) return a.getTime() - b.getTime(); + if (a) return -1; + if (b) return 1; + return 0; +}; + +const sortByDateDesc: SortFunc = (a, b) => -sortByDateAsc(a, b); + +export const sortEntries = (entries: T[], sortBy: SortBy) => { + let sortFunc: SortFunc; + + switch (sortBy) { + case SortBy.NAME_ASC: + sortFunc = sortByNameAsc; + break; + case SortBy.NAME_DESC: + sortFunc = sortByNameDesc; + break; + case SortBy.DATE_ASC: + sortFunc = sortByDateAsc; + break; + case SortBy.DATE_DESC: + sortFunc = sortByDateDesc; + break; + default: + const exhaustive: never = sortBy; + sortFunc = exhaustive; + } + + entries.sort(sortFunc); +}; diff --git a/src/routes/(fullscreen)/auth/changePassword/service.ts b/src/routes/(fullscreen)/auth/changePassword/service.ts index 37380a4..4673611 100644 --- a/src/routes/(fullscreen)/auth/changePassword/service.ts +++ b/src/routes/(fullscreen)/auth/changePassword/service.ts @@ -1,10 +1,11 @@ -import { callPostApi } from "$lib/hooks"; -import type { PasswordChangeRequest } from "$lib/server/schemas"; +import { trpc } from "$trpc/client"; export const requestPasswordChange = async (oldPassword: string, newPassword: string) => { - const res = await callPostApi("/api/auth/changePassword", { - oldPassword, - newPassword, - }); - return res.ok; + try { + await trpc().auth.changePassword.mutate({ oldPassword, newPassword }); + return true; + } catch { + // TODO: Error Handling + return false; + } }; diff --git a/src/routes/(fullscreen)/auth/login/service.ts b/src/routes/(fullscreen)/auth/login/service.ts index 88613f1..5c8219a 100644 --- a/src/routes/(fullscreen)/auth/login/service.ts +++ b/src/routes/(fullscreen)/auth/login/service.ts @@ -1,5 +1,4 @@ -import { callPostApi } from "$lib/hooks"; -import type { LoginRequest } from "$lib/server/schemas"; +import { trpc } from "$trpc/client"; export { requestLogout } from "$lib/services/auth"; export { requestDeletedFilesCleanup } from "$lib/services/file"; @@ -9,6 +8,11 @@ export { } from "$lib/services/key"; export const requestLogin = async (email: string, password: string) => { - const res = await callPostApi("/api/auth/login", { email, password }); - return res.ok; + try { + await trpc().auth.login.mutate({ email, password }); + return true; + } catch { + // TODO: Error Handling + return false; + } }; diff --git a/src/routes/(fullscreen)/file/[id]/+page.svelte b/src/routes/(fullscreen)/file/[id]/+page.svelte index 4047e7c..3249bf2 100644 --- a/src/routes/(fullscreen)/file/[id]/+page.svelte +++ b/src/routes/(fullscreen)/file/[id]/+page.svelte @@ -3,6 +3,7 @@ import { untrack } from "svelte"; import { get, type Writable } from "svelte/store"; import { goto } from "$app/navigation"; + import { page } from "$app/state"; import { FullscreenDiv } from "$lib/components/atoms"; import { Categories, IconEntryButton, TopBar } from "$lib/components/molecules"; import { @@ -21,7 +22,9 @@ requestThumbnailUpload, requestFileAdditionToCategory, } from "./service"; + import TopBarMenu from "./TopBarMenu.svelte"; + import IconMoreVert from "~icons/material-symbols/more-vert"; import IconCamera from "~icons/material-symbols/camera"; import IconClose from "~icons/material-symbols/close"; import IconAddCircle from "~icons/material-symbols/add-circle"; @@ -31,6 +34,7 @@ let info: Writable | undefined = $state(); let categories: Writable[] = $state([]); + let isMenuOpen = $state(false); let isAddToCategoryBottomSheetOpen = $state(false); let downloadStatus = $derived( @@ -42,30 +46,26 @@ let isDownloadRequested = $state(false); let viewerType: "image" | "video" | undefined = $state(); + let fileBlob: Blob | undefined = $state(); let fileBlobUrl: string | undefined = $state(); - let heicBlob: Blob | undefined = $state(); let videoElement: HTMLVideoElement | undefined = $state(); const updateViewer = async (buffer: ArrayBuffer, contentType: string) => { - const fileBlob = new Blob([buffer], { type: contentType }); - if (viewerType) { - fileBlobUrl = URL.createObjectURL(fileBlob); - heicBlob = contentType === "image/heic" ? fileBlob : undefined; - } + fileBlob = new Blob([buffer], { type: contentType }); + fileBlobUrl = URL.createObjectURL(fileBlob); return fileBlob; }; const convertHeicToJpeg = async () => { - if (!heicBlob) return; + if (fileBlob?.type !== "image/heic") return; URL.revokeObjectURL(fileBlobUrl!); fileBlobUrl = undefined; const { default: heic2any } = await import("heic2any"); fileBlobUrl = URL.createObjectURL( - (await heic2any({ blob: heicBlob, toType: "image/jpeg" })) as Blob, + (await heic2any({ blob: fileBlob, toType: "image/jpeg" })) as Blob, ); - heicBlob = undefined; }; const updateThumbnail = async (dataKey: CryptoKey, dataKeyVersion: Date) => { @@ -133,7 +133,24 @@ 파일 - + + + +
e.stopPropagation()}> + + +
+
diff --git a/src/routes/(fullscreen)/file/[id]/DownloadStatus.svelte b/src/routes/(fullscreen)/file/[id]/DownloadStatus.svelte index 21774cd..150669e 100644 --- a/src/routes/(fullscreen)/file/[id]/DownloadStatus.svelte +++ b/src/routes/(fullscreen)/file/[id]/DownloadStatus.svelte @@ -1,7 +1,7 @@ + + (isOpen = false)} /> + +{#if isOpen && (directoryId || fileBlob)} +
+

더보기

+
+ {#snippet menuButton( + Icon: Component, + text: string, + onclick: () => void, + )} + + {/snippet} + + {#if directoryId} + {@render menuButton(IconFolderOpen, "폴더에서 보기", () => + goto( + directoryId === "root" ? "/directory?from=file" : `/directory/${directoryId}?from=file`, + ), + )} + {/if} + {#if fileBlob} + {@render menuButton(IconCloudDownload, "다운로드", () => { + FileSaver.saveAs(fileBlob, filename); + })} + {/if} +
+
+{/if} diff --git a/src/routes/(fullscreen)/file/[id]/service.ts b/src/routes/(fullscreen)/file/[id]/service.ts index 00614d6..09ec86f 100644 --- a/src/routes/(fullscreen)/file/[id]/service.ts +++ b/src/routes/(fullscreen)/file/[id]/service.ts @@ -1,8 +1,7 @@ -import { callPostApi } from "$lib/hooks"; import { encryptData } from "$lib/modules/crypto"; import { storeFileThumbnailCache } from "$lib/modules/file"; -import type { CategoryFileAddRequest } from "$lib/server/schemas"; import { requestFileThumbnailUpload } from "$lib/services/file"; +import { trpc } from "$trpc/client"; export { requestCategoryCreation, requestFileRemovalFromCategory } from "$lib/services/category"; export { requestFileDownload } from "$lib/services/file"; @@ -23,8 +22,11 @@ export const requestThumbnailUpload = async ( }; export const requestFileAdditionToCategory = async (fileId: number, categoryId: number) => { - const res = await callPostApi(`/api/category/${categoryId}/file/add`, { - file: fileId, - }); - return res.ok; + try { + await trpc().category.addFile.mutate({ id: categoryId, file: fileId }); + return true; + } catch { + // TODO: Error Handling + return false; + } }; diff --git a/src/routes/(fullscreen)/file/downloads/File.svelte b/src/routes/(fullscreen)/file/downloads/File.svelte index 56ee319..3bfe292 100644 --- a/src/routes/(fullscreen)/file/downloads/File.svelte +++ b/src/routes/(fullscreen)/file/downloads/File.svelte @@ -1,8 +1,8 @@ + + + 사진 및 동영상 + + + + + goto(`/file/${id}`)} /> + diff --git a/src/routes/(fullscreen)/gallery/+page.ts b/src/routes/(fullscreen)/gallery/+page.ts new file mode 100644 index 0000000..1a241c5 --- /dev/null +++ b/src/routes/(fullscreen)/gallery/+page.ts @@ -0,0 +1,7 @@ +import { trpc } from "$trpc/client"; +import type { PageLoad } from "./$types"; + +export const load: PageLoad = async ({ fetch }) => { + const files = await trpc(fetch).file.list.query(); + return { files }; +}; diff --git a/src/routes/(fullscreen)/key/export/+page.ts b/src/routes/(fullscreen)/key/export/+page.ts index a64ea53..fc25a3e 100644 --- a/src/routes/(fullscreen)/key/export/+page.ts +++ b/src/routes/(fullscreen)/key/export/+page.ts @@ -1,5 +1,5 @@ import { error } from "@sveltejs/kit"; -import { keyExportState } from "$lib/hooks/gotoStateful"; +import { keyExportState } from "$lib/utils"; import type { PageLoad } from "./$types"; export const load: PageLoad = async () => { diff --git a/src/routes/(fullscreen)/key/generate/+page.svelte b/src/routes/(fullscreen)/key/generate/+page.svelte index 6f7609c..7292d78 100644 --- a/src/routes/(fullscreen)/key/generate/+page.svelte +++ b/src/routes/(fullscreen)/key/generate/+page.svelte @@ -4,9 +4,9 @@ import { BottomDiv, Button, FullscreenDiv, TextButton } from "$lib/components/atoms"; import { TitledDiv } from "$lib/components/molecules"; import { ForceLoginModal } from "$lib/components/organisms"; - import { gotoStateful } from "$lib/hooks"; import { storeClientKeys } from "$lib/modules/key"; import { clientKeyStore } from "$lib/stores"; + import { gotoStateful } from "$lib/utils"; import Order from "./Order.svelte"; import { generateClientKeys, diff --git a/src/routes/(fullscreen)/settings/cache/+page.svelte b/src/routes/(fullscreen)/settings/cache/+page.svelte index af375c2..cf8192d 100644 --- a/src/routes/(fullscreen)/settings/cache/+page.svelte +++ b/src/routes/(fullscreen)/settings/cache/+page.svelte @@ -6,8 +6,8 @@ import type { FileCacheIndex } from "$lib/indexedDB"; import { getFileCacheIndex, deleteFileCache as doDeleteFileCache } from "$lib/modules/file"; import { getFileInfo, type FileInfo } from "$lib/modules/filesystem"; - import { formatFileSize } from "$lib/modules/util"; import { masterKeyStore } from "$lib/stores"; + import { formatFileSize } from "$lib/utils"; import File from "./File.svelte"; interface FileCache { diff --git a/src/routes/(fullscreen)/settings/cache/File.svelte b/src/routes/(fullscreen)/settings/cache/File.svelte index f21445b..581d144 100644 --- a/src/routes/(fullscreen)/settings/cache/File.svelte +++ b/src/routes/(fullscreen)/settings/cache/File.svelte @@ -2,7 +2,7 @@ import type { Writable } from "svelte/store"; import type { FileCacheIndex } from "$lib/indexedDB"; import type { FileInfo } from "$lib/modules/filesystem"; - import { formatDate, formatFileSize } from "$lib/modules/util"; + import { formatDate, formatFileSize } from "$lib/utils"; import IconDraft from "~icons/material-symbols/draft"; import IconScanDelete from "~icons/material-symbols/scan-delete"; diff --git a/src/routes/(fullscreen)/settings/thumbnail/+page.ts b/src/routes/(fullscreen)/settings/thumbnail/+page.ts index a16cb8e..4d5520c 100644 --- a/src/routes/(fullscreen)/settings/thumbnail/+page.ts +++ b/src/routes/(fullscreen)/settings/thumbnail/+page.ts @@ -1,14 +1,7 @@ -import { error } from "@sveltejs/kit"; -import { callPostApi } from "$lib/hooks"; -import type { MissingThumbnailFileScanResponse } from "$lib/server/schemas"; +import { trpc } from "$trpc/client"; import type { PageLoad } from "./$types"; export const load: PageLoad = async ({ fetch }) => { - const res = await callPostApi("/api/file/scanMissingThumbnails", undefined, fetch); - if (!res.ok) { - error(500, "Internal server error"); - } - - const { files }: MissingThumbnailFileScanResponse = await res.json(); + const files = await trpc(fetch).file.listWithoutThumbnail.query(); return { files }; }; diff --git a/src/routes/(fullscreen)/settings/thumbnail/File.svelte b/src/routes/(fullscreen)/settings/thumbnail/File.svelte index 8977fc7..93c23ad 100644 --- a/src/routes/(fullscreen)/settings/thumbnail/File.svelte +++ b/src/routes/(fullscreen)/settings/thumbnail/File.svelte @@ -14,7 +14,7 @@ import { ActionEntryButton } from "$lib/components/atoms"; import { DirectoryEntryLabel } from "$lib/components/molecules"; import type { FileInfo } from "$lib/modules/filesystem"; - import { formatDateTime } from "$lib/modules/util"; + import { formatDateTime } from "$lib/utils"; import type { GenerationStatus } from "./service.svelte"; import IconCamera from "~icons/material-symbols/camera"; diff --git a/src/routes/(main)/BottomBar.svelte b/src/routes/(main)/BottomBar.svelte index 60c2b24..e1008df 100644 --- a/src/routes/(main)/BottomBar.svelte +++ b/src/routes/(main)/BottomBar.svelte @@ -22,7 +22,7 @@ {#each pages as { path, label, icon: Icon }}