From 7613374e1fb4d0af24e1acd32f3137f079460a97 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 30 Jul 2025 08:15:21 +0200 Subject: [PATCH 001/274] feat: Configuration de base du projet Nuxt.js avec DaisyUI - Initialisation du projet Nuxt.js - Configuration de DaisyUI pour le design system - Fichiers de configuration (package.json, nuxt.config.ts, tsconfig.json) - Structure des dossiers publics et assets - Documentation README et variables d'environnement --- .gitignore | 24 + README.md | 75 + env.example | 24 + nuxt.config.ts | 17 + package-lock.json | 15571 +++++++++++++++++++++++++++++++++++++++++++ package.json | 23 + public/favicon.ico | Bin 0 -> 4286 bytes public/robots.txt | 2 + tsconfig.json | 18 + 9 files changed, 15754 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 env.example create mode 100644 nuxt.config.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/favicon.ico create mode 100644 public/robots.txt create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a7f73a --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example diff --git a/README.md b/README.md new file mode 100644 index 0000000..25b5821 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +# Nuxt Minimal Starter + +Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. + +## Setup + +Make sure to install dependencies: + +```bash +# npm +npm install + +# pnpm +pnpm install + +# yarn +yarn install + +# bun +bun install +``` + +## Development Server + +Start the development server on `http://localhost:3000`: + +```bash +# npm +npm run dev + +# pnpm +pnpm dev + +# yarn +yarn dev + +# bun +bun run dev +``` + +## Production + +Build the application for production: + +```bash +# npm +npm run build + +# pnpm +pnpm build + +# yarn +yarn build + +# bun +bun run build +``` + +Locally preview production build: + +```bash +# npm +npm run preview + +# pnpm +pnpm preview + +# yarn +yarn preview + +# bun +bun run preview +``` + +Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. diff --git a/env.example b/env.example new file mode 100644 index 0000000..3956c74 --- /dev/null +++ b/env.example @@ -0,0 +1,24 @@ +# Configuration de l'API backend +NUXT_PUBLIC_API_BASE_URL=http://localhost:3000/api + +# Configuration du serveur de développement +NUXT_PUBLIC_APP_URL=http://localhost:3001 +NUXT_PUBLIC_APP_NAME="Inventory Management System" + +# Configuration de l'environnement +NODE_ENV=development +NUXT_APP_ENV=development + +# Configuration des fonctionnalités +NUXT_PUBLIC_ENABLE_DEBUG=true +NUXT_PUBLIC_ENABLE_ANALYTICS=false + +# Configuration de sécurité (optionnel) +NUXT_PUBLIC_CSRF_TOKEN=your-csrf-token-here + +# Configuration des logs +NUXT_PUBLIC_LOG_LEVEL=debug + +# Configuration des timeouts +NUXT_PUBLIC_API_TIMEOUT=30000 +NUXT_PUBLIC_REQUEST_TIMEOUT=10000 \ No newline at end of file diff --git a/nuxt.config.ts b/nuxt.config.ts new file mode 100644 index 0000000..1b3f21a --- /dev/null +++ b/nuxt.config.ts @@ -0,0 +1,17 @@ +import tailwindcss from "@tailwindcss/vite"; +export default defineNuxtConfig({ + compatibilityDate: '2025-07-15', + devtools: { enabled: true }, + vite: { + plugins: [tailwindcss()], + }, + css: ["~/assets/app.css"], + router: { + options: { + strict: false + } + }, + experimental: { + payloadExtraction: false + } +}) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..77fe210 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,15571 @@ +{ + "name": "nuxt-app", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nuxt-app", + "hasInstallScript": true, + "dependencies": { + "@nuxtjs/tailwindcss": "^6.14.0", + "@tailwindcss/vite": "^4.1.11", + "daisyui": "^5.0.48", + "nuxt": "^4.0.1", + "tailwindcss": "^4.1.11", + "vue": "^3.5.17", + "vue-router": "^4.5.1" + }, + "devDependencies": { + "cypress": "^14.5.3" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", + "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.6", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", + "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.27.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", + "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", + "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.0.tgz", + "integrity": "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "mime": "^3.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@cloudflare/kv-asset-handler/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@csstools/selector-resolve-nested": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz", + "integrity": "sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@cypress/request": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.9.tgz", + "integrity": "sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~4.0.4", + "http-signature": "~1.4.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "6.14.0", + "safe-buffer": "^5.1.2", + "tough-cookie": "^5.0.0", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/request/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@cypress/request/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@cypress/request/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "license": "MIT", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "node_modules/@dependents/detective-less": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@dependents/detective-less/-/detective-less-5.0.1.tgz", + "integrity": "sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ==", + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@emnapi/core": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", + "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.4", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", + "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", + "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", + "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", + "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", + "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", + "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", + "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", + "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", + "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", + "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", + "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", + "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", + "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", + "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", + "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", + "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", + "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", + "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", + "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", + "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", + "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", + "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", + "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", + "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", + "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", + "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", + "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", + "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fastify/busboy": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz", + "integrity": "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==", + "license": "MIT" + }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz", + "integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@koa/router": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@koa/router/-/router-12.0.2.tgz", + "integrity": "sha512-sYcHglGKTxGF+hQ6x67xDfkE9o+NhVlRHBqq6gLywaMc6CojK/5vFZByphdonKinYlMLkEkacm+HEse9HzwgTA==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "http-errors": "^2.0.0", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "^6.3.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "license": "MIT" + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.0.tgz", + "integrity": "sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==", + "license": "BSD-3-Clause", + "dependencies": { + "consola": "^3.2.3", + "detect-libc": "^2.0.0", + "https-proxy-agent": "^7.0.5", + "node-fetch": "^2.6.7", + "nopt": "^8.0.0", + "semver": "^7.5.3", + "tar": "^7.4.0" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.1.tgz", + "integrity": "sha512-KVlQ/jgywZpixGCKMNwxStmmbYEMyokZpCf2YuIChhfJA2uqfAKNEM8INz7zzTo55iEXfBhIIs3VqYyqzDLj8g==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.5", + "@emnapi/runtime": "^1.4.5", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@netlify/binary-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@netlify/binary-info/-/binary-info-1.0.0.tgz", + "integrity": "sha512-4wMPu9iN3/HL97QblBsBay3E1etIciR84izI3U+4iALY+JHCrI+a2jO0qbAZ/nxKoegypYEaiiqWXylm+/zfrw==", + "license": "Apache 2" + }, + "node_modules/@netlify/blobs": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@netlify/blobs/-/blobs-9.1.2.tgz", + "integrity": "sha512-7dMjExSH4zj4ShvLem49mE3mf0K171Tx2pV4WDWhJbRUWW3SJIR2qntz0LvUGS97N5HO1SmnzrgWUhEXCsApiw==", + "license": "MIT", + "dependencies": { + "@netlify/dev-utils": "2.2.0", + "@netlify/runtime-utils": "1.3.1" + }, + "engines": { + "node": "^14.16.0 || >=16.0.0" + } + }, + "node_modules/@netlify/dev-utils": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@netlify/dev-utils/-/dev-utils-2.2.0.tgz", + "integrity": "sha512-5XUvZuffe3KetyhbWwd4n2ktd7wraocCYw10tlM+/u/95iAz29GjNiuNxbCD1T6Bn1MyGc4QLVNKOWhzJkVFAw==", + "license": "MIT", + "dependencies": { + "@whatwg-node/server": "^0.9.60", + "chokidar": "^4.0.1", + "decache": "^4.6.2", + "dot-prop": "9.0.0", + "env-paths": "^3.0.0", + "find-up": "7.0.0", + "lodash.debounce": "^4.0.8", + "netlify": "^13.3.5", + "parse-gitignore": "^2.0.0", + "uuid": "^11.1.0", + "write-file-atomic": "^6.0.0" + }, + "engines": { + "node": "^14.16.0 || >=16.0.0" + } + }, + "node_modules/@netlify/functions": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-3.1.10.tgz", + "integrity": "sha512-sI93kcJ2cUoMgDRPnrEm0lZhuiDVDqM6ngS/UbHTApIH3+eg3yZM5p/0SDFQQq9Bad0/srFmgBmTdXushzY5kg==", + "license": "MIT", + "dependencies": { + "@netlify/blobs": "9.1.2", + "@netlify/dev-utils": "2.2.0", + "@netlify/serverless-functions-api": "1.41.2", + "@netlify/zip-it-and-ship-it": "^12.1.0", + "cron-parser": "^4.9.0", + "decache": "^4.6.2", + "extract-zip": "^2.0.1", + "is-stream": "^4.0.1", + "jwt-decode": "^4.0.0", + "lambda-local": "^2.2.0", + "read-package-up": "^11.0.0", + "source-map-support": "^0.5.21" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@netlify/functions/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@netlify/open-api": { + "version": "2.37.0", + "resolved": "https://registry.npmjs.org/@netlify/open-api/-/open-api-2.37.0.tgz", + "integrity": "sha512-zXnRFkxgNsalSgU8/vwTWnav3R+8KG8SsqHxqaoJdjjJtnZR7wo3f+qqu4z+WtZ/4V7fly91HFUwZ6Uz2OdW7w==", + "license": "MIT", + "engines": { + "node": ">=14.8.0" + } + }, + "node_modules/@netlify/runtime-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@netlify/runtime-utils/-/runtime-utils-1.3.1.tgz", + "integrity": "sha512-7/vIJlMYrPJPlEW84V2yeRuG3QBu66dmlv9neTmZ5nXzwylhBEOhy11ai+34A8mHCSZI4mKns25w3HM9kaDdJg==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@netlify/serverless-functions-api": { + "version": "1.41.2", + "resolved": "https://registry.npmjs.org/@netlify/serverless-functions-api/-/serverless-functions-api-1.41.2.tgz", + "integrity": "sha512-pfCkH50JV06SGMNsNPjn8t17hOcId4fA881HeYQgMBOrewjsw4csaYgHEnCxCEu24Y5x75E2ULbFpqm9CvRCqw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@netlify/zip-it-and-ship-it": { + "version": "12.2.1", + "resolved": "https://registry.npmjs.org/@netlify/zip-it-and-ship-it/-/zip-it-and-ship-it-12.2.1.tgz", + "integrity": "sha512-zAr+8Tg80y/sUbhdUkZsq4Uy1IMzkSB6H/sKRMrDQ2NJx4uPgf5X5jMdg9g2FljNcxzpfJwc1Gg4OXQrjD0Z4A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.22.5", + "@babel/types": "7.28.0", + "@netlify/binary-info": "^1.0.0", + "@netlify/serverless-functions-api": "^2.1.3", + "@vercel/nft": "0.29.4", + "archiver": "^7.0.0", + "common-path-prefix": "^3.0.0", + "copy-file": "^11.0.0", + "es-module-lexer": "^1.0.0", + "esbuild": "0.25.5", + "execa": "^8.0.0", + "fast-glob": "^3.3.3", + "filter-obj": "^6.0.0", + "find-up": "^7.0.0", + "is-builtin-module": "^3.1.0", + "is-path-inside": "^4.0.0", + "junk": "^4.0.0", + "locate-path": "^7.0.0", + "merge-options": "^3.0.4", + "minimatch": "^9.0.0", + "normalize-path": "^3.0.0", + "p-map": "^7.0.0", + "path-exists": "^5.0.0", + "precinct": "^12.0.0", + "require-package-name": "^2.0.1", + "resolve": "^2.0.0-next.1", + "semver": "^7.3.8", + "tmp-promise": "^3.0.2", + "toml": "^3.0.0", + "unixify": "^1.0.0", + "urlpattern-polyfill": "8.0.2", + "yargs": "^17.0.0", + "zod": "^3.23.8" + }, + "bin": { + "zip-it-and-ship-it": "bin.js" + }, + "engines": { + "node": ">=18.14.0" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@babel/types": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.0.tgz", + "integrity": "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/android-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/android-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/android-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/darwin-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/linux-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/linux-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/linux-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/linux-loong64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/linux-s390x": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/linux-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/sunos-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/win32-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/win32-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@esbuild/win32-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/@netlify/serverless-functions-api": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@netlify/serverless-functions-api/-/serverless-functions-api-2.1.3.tgz", + "integrity": "sha512-bNlN/hpND8xFQzpjyKxm6vJayD+bPBlOvs4lWihE7WULrphuH1UuFsoVE5386bNNGH8Rs1IH01AFsl7ALQgOlQ==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nuxt/cli": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/@nuxt/cli/-/cli-3.27.0.tgz", + "integrity": "sha512-lOdzEvEbGaV06ebKKYgpumLLzbOZMFQzZfT4ZE7foa8/8aXG+GR3g8w9RX2IUyomTdSfapa3UcHDC8srQKRIEw==", + "license": "MIT", + "dependencies": { + "c12": "^3.1.0", + "citty": "^0.1.6", + "clipboardy": "^4.0.0", + "confbox": "^0.2.2", + "consola": "^3.4.2", + "defu": "^6.1.4", + "exsolve": "^1.0.7", + "fuse.js": "^7.1.0", + "get-port-please": "^3.2.0", + "giget": "^2.0.0", + "h3": "^1.15.3", + "httpxy": "^0.1.7", + "jiti": "^2.4.2", + "listhen": "^1.9.0", + "nypm": "^0.6.0", + "ofetch": "^1.4.1", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.2.0", + "scule": "^1.3.0", + "semver": "^7.7.2", + "std-env": "^3.9.0", + "tinyexec": "^1.0.1", + "ufo": "^1.6.1", + "youch": "^4.1.0-beta.10" + }, + "bin": { + "nuxi": "bin/nuxi.mjs", + "nuxi-ng": "bin/nuxi.mjs", + "nuxt": "bin/nuxi.mjs", + "nuxt-cli": "bin/nuxi.mjs" + }, + "engines": { + "node": "^16.10.0 || >=18.0.0" + } + }, + "node_modules/@nuxt/devalue": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nuxt/devalue/-/devalue-2.0.2.tgz", + "integrity": "sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==", + "license": "MIT" + }, + "node_modules/@nuxt/devtools": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@nuxt/devtools/-/devtools-2.6.2.tgz", + "integrity": "sha512-pqcSDPv1I+8fxa6FvhAxVrfcN/sXYLOBe9scTLbRQOVLTO0pHzryayho678qNKiwWGgj/rcjEDr6IZCgwqOCfA==", + "license": "MIT", + "dependencies": { + "@nuxt/devtools-kit": "2.6.2", + "@nuxt/devtools-wizard": "2.6.2", + "@nuxt/kit": "^3.17.6", + "@vue/devtools-core": "^7.7.7", + "@vue/devtools-kit": "^7.7.7", + "birpc": "^2.4.0", + "consola": "^3.4.2", + "destr": "^2.0.5", + "error-stack-parser-es": "^1.0.5", + "execa": "^8.0.1", + "fast-npm-meta": "^0.4.4", + "get-port-please": "^3.1.2", + "hookable": "^5.5.3", + "image-meta": "^0.2.1", + "is-installed-globally": "^1.0.0", + "launch-editor": "^2.10.0", + "local-pkg": "^1.1.1", + "magicast": "^0.3.5", + "nypm": "^0.6.0", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.2.0", + "semver": "^7.7.2", + "simple-git": "^3.28.0", + "sirv": "^3.0.1", + "structured-clone-es": "^1.0.0", + "tinyglobby": "^0.2.14", + "vite-plugin-inspect": "^11.3.0", + "vite-plugin-vue-tracer": "^1.0.0", + "which": "^5.0.0", + "ws": "^8.18.3" + }, + "bin": { + "devtools": "cli.mjs" + }, + "peerDependencies": { + "vite": ">=6.0" + } + }, + "node_modules/@nuxt/devtools-kit": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@nuxt/devtools-kit/-/devtools-kit-2.6.2.tgz", + "integrity": "sha512-esErdMQ0u3wXXogKQ3IE2m0fxv52w6CzPsfsXF4o5ZVrUQrQaH58ygupDAQTYdlGTgtqmEA6KkHTGG5cM6yxeg==", + "license": "MIT", + "dependencies": { + "@nuxt/kit": "^3.17.6", + "execa": "^8.0.1" + }, + "peerDependencies": { + "vite": ">=6.0" + } + }, + "node_modules/@nuxt/devtools-kit/node_modules/@nuxt/kit": { + "version": "3.17.7", + "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.17.7.tgz", + "integrity": "sha512-JLno3ur7Pix2o/StxIMlEHRkMawA6h7uzjZBDgxdeKXRWTYY8ID9YekSkN4PBlEFGXBfCBOcPd5+YqcyBUAMkw==", + "license": "MIT", + "dependencies": { + "c12": "^3.0.4", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "errx": "^0.1.0", + "exsolve": "^1.0.7", + "ignore": "^7.0.5", + "jiti": "^2.4.2", + "klona": "^2.0.6", + "knitwork": "^1.2.0", + "mlly": "^1.7.4", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.2.0", + "scule": "^1.3.0", + "semver": "^7.7.2", + "std-env": "^3.9.0", + "tinyglobby": "^0.2.14", + "ufo": "^1.6.1", + "unctx": "^2.4.1", + "unimport": "^5.1.0", + "untyped": "^2.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxt/devtools-wizard": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@nuxt/devtools-wizard/-/devtools-wizard-2.6.2.tgz", + "integrity": "sha512-s1eYYKi2eZu2ZUPQrf22C0SceWs5/C3c3uow/DVunD304Um/Tj062xM9E4p1B9L8yjaq8t0Gtyu/YvZdo/reyg==", + "license": "MIT", + "dependencies": { + "consola": "^3.4.2", + "diff": "^8.0.2", + "execa": "^8.0.1", + "magicast": "^0.3.5", + "pathe": "^2.0.3", + "pkg-types": "^2.2.0", + "prompts": "^2.4.2", + "semver": "^7.7.2" + }, + "bin": { + "devtools-wizard": "cli.mjs" + } + }, + "node_modules/@nuxt/devtools/node_modules/@nuxt/kit": { + "version": "3.17.7", + "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.17.7.tgz", + "integrity": "sha512-JLno3ur7Pix2o/StxIMlEHRkMawA6h7uzjZBDgxdeKXRWTYY8ID9YekSkN4PBlEFGXBfCBOcPd5+YqcyBUAMkw==", + "license": "MIT", + "dependencies": { + "c12": "^3.0.4", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "errx": "^0.1.0", + "exsolve": "^1.0.7", + "ignore": "^7.0.5", + "jiti": "^2.4.2", + "klona": "^2.0.6", + "knitwork": "^1.2.0", + "mlly": "^1.7.4", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.2.0", + "scule": "^1.3.0", + "semver": "^7.7.2", + "std-env": "^3.9.0", + "tinyglobby": "^0.2.14", + "ufo": "^1.6.1", + "unctx": "^2.4.1", + "unimport": "^5.1.0", + "untyped": "^2.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxt/kit": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-4.0.1.tgz", + "integrity": "sha512-9vYpbuK3xcVhuDq+NyoLhbAolV/bEESaozFOMutl0jhrODcNWFrJ8wQSZIt9yxcFXUgXgUa2ms31qaUEpXrykw==", + "license": "MIT", + "dependencies": { + "c12": "^3.1.0", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "errx": "^0.1.0", + "exsolve": "^1.0.7", + "ignore": "^7.0.5", + "jiti": "^2.4.2", + "klona": "^2.0.6", + "mlly": "^1.7.4", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.2.0", + "scule": "^1.3.0", + "semver": "^7.7.2", + "std-env": "^3.9.0", + "tinyglobby": "^0.2.14", + "ufo": "^1.6.1", + "unctx": "^2.4.1", + "unimport": "^5.1.0", + "untyped": "^2.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxt/schema": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nuxt/schema/-/schema-4.0.1.tgz", + "integrity": "sha512-/e/avVyJ/pLydTQL9iGlpvyGiJ0Y6+TKLXlUFR0zPTJv6asHzCqHKbiL84+wSAQmTw6Hl+z0yZv8uEx21+JoHw==", + "license": "MIT", + "dependencies": { + "@vue/shared": "^3.5.17", + "consola": "^3.4.2", + "defu": "^6.1.4", + "pathe": "^2.0.3", + "std-env": "^3.9.0" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/@nuxt/telemetry": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/@nuxt/telemetry/-/telemetry-2.6.6.tgz", + "integrity": "sha512-Zh4HJLjzvm3Cq9w6sfzIFyH9ozK5ePYVfCUzzUQNiZojFsI2k1QkSBrVI9BGc6ArKXj/O6rkI6w7qQ+ouL8Cag==", + "license": "MIT", + "dependencies": { + "@nuxt/kit": "^3.15.4", + "citty": "^0.1.6", + "consola": "^3.4.2", + "destr": "^2.0.3", + "dotenv": "^16.4.7", + "git-url-parse": "^16.0.1", + "is-docker": "^3.0.0", + "ofetch": "^1.4.1", + "package-manager-detector": "^1.1.0", + "pathe": "^2.0.3", + "rc9": "^2.1.2", + "std-env": "^3.8.1" + }, + "bin": { + "nuxt-telemetry": "bin/nuxt-telemetry.mjs" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxt/telemetry/node_modules/@nuxt/kit": { + "version": "3.17.7", + "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.17.7.tgz", + "integrity": "sha512-JLno3ur7Pix2o/StxIMlEHRkMawA6h7uzjZBDgxdeKXRWTYY8ID9YekSkN4PBlEFGXBfCBOcPd5+YqcyBUAMkw==", + "license": "MIT", + "dependencies": { + "c12": "^3.0.4", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "errx": "^0.1.0", + "exsolve": "^1.0.7", + "ignore": "^7.0.5", + "jiti": "^2.4.2", + "klona": "^2.0.6", + "knitwork": "^1.2.0", + "mlly": "^1.7.4", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.2.0", + "scule": "^1.3.0", + "semver": "^7.7.2", + "std-env": "^3.9.0", + "tinyglobby": "^0.2.14", + "ufo": "^1.6.1", + "unctx": "^2.4.1", + "unimport": "^5.1.0", + "untyped": "^2.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxt/vite-builder": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nuxt/vite-builder/-/vite-builder-4.0.1.tgz", + "integrity": "sha512-+ScfRxpCCHkJgkBYRXkvQHLsF/vxyFkwQzTBDL6+8sg9+BcTYkxOjVHDZ1l0qzeVORXzoq4G+oPfKsob64vODA==", + "license": "MIT", + "dependencies": { + "@nuxt/kit": "4.0.1", + "@rollup/plugin-replace": "^6.0.2", + "@vitejs/plugin-vue": "^6.0.0", + "@vitejs/plugin-vue-jsx": "^5.0.1", + "autoprefixer": "^10.4.21", + "consola": "^3.4.2", + "cssnano": "^7.1.0", + "defu": "^6.1.4", + "esbuild": "^0.25.8", + "escape-string-regexp": "^5.0.0", + "exsolve": "^1.0.7", + "get-port-please": "^3.2.0", + "h3": "^1.15.3", + "jiti": "^2.4.2", + "knitwork": "^1.2.0", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "mocked-exports": "^0.1.1", + "pathe": "^2.0.3", + "pkg-types": "^2.2.0", + "postcss": "^8.5.6", + "rollup-plugin-visualizer": "^6.0.3", + "std-env": "^3.9.0", + "ufo": "^1.6.1", + "unenv": "^2.0.0-rc.18", + "vite": "^7.0.5", + "vite-node": "^3.2.4", + "vite-plugin-checker": "^0.10.0", + "vue-bundle-renderer": "^2.1.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vue": "^3.3.4" + } + }, + "node_modules/@nuxtjs/tailwindcss": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@nuxtjs/tailwindcss/-/tailwindcss-6.14.0.tgz", + "integrity": "sha512-30RyDK++LrUVRgc2A85MktGWIZoRQgeQKjE4CjjD64OXNozyl+4ScHnnYgqVToMM6Ch2ZG2W4wV2J0EN6F0zkQ==", + "license": "MIT", + "dependencies": { + "@nuxt/kit": "^3.16.0", + "autoprefixer": "^10.4.20", + "c12": "^3.0.2", + "consola": "^3.4.0", + "defu": "^6.1.4", + "h3": "^1.15.1", + "klona": "^2.0.6", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.1.0", + "postcss": "^8.5.3", + "postcss-nesting": "^13.0.1", + "tailwind-config-viewer": "^2.0.4", + "tailwindcss": "~3.4.17", + "ufo": "^1.5.4", + "unctx": "^2.4.1" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/@nuxt/kit": { + "version": "3.17.7", + "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.17.7.tgz", + "integrity": "sha512-JLno3ur7Pix2o/StxIMlEHRkMawA6h7uzjZBDgxdeKXRWTYY8ID9YekSkN4PBlEFGXBfCBOcPd5+YqcyBUAMkw==", + "license": "MIT", + "dependencies": { + "c12": "^3.0.4", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "errx": "^0.1.0", + "exsolve": "^1.0.7", + "ignore": "^7.0.5", + "jiti": "^2.4.2", + "klona": "^2.0.6", + "knitwork": "^1.2.0", + "mlly": "^1.7.4", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.2.0", + "scule": "^1.3.0", + "semver": "^7.7.2", + "std-env": "^3.9.0", + "tinyglobby": "^0.2.14", + "ufo": "^1.6.1", + "unctx": "^2.4.1", + "unimport": "^5.1.0", + "untyped": "^2.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/tailwind-config-viewer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/tailwind-config-viewer/-/tailwind-config-viewer-2.0.4.tgz", + "integrity": "sha512-icvcmdMmt9dphvas8wL40qttrHwAnW3QEN4ExJ2zICjwRsPj7gowd1cOceaWG3IfTuM/cTNGQcx+bsjMtmV+cw==", + "license": "MIT", + "dependencies": { + "@koa/router": "^12.0.1", + "commander": "^6.0.0", + "fs-extra": "^9.0.1", + "koa": "^2.14.2", + "koa-static": "^5.0.0", + "open": "^7.0.4", + "portfinder": "^1.0.26", + "replace-in-file": "^6.1.0" + }, + "bin": { + "tailwind-config-viewer": "cli/index.js", + "tailwindcss-config-viewer": "cli/index.js" + }, + "engines": { + "node": ">=13" + }, + "peerDependencies": { + "tailwindcss": "1 || 2 || 2.0.1-compat || 3" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@nuxtjs/tailwindcss/node_modules/tailwindcss/node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/@oxc-minify/binding-android-arm64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-android-arm64/-/binding-android-arm64-0.77.3.tgz", + "integrity": "sha512-9bGiDHSkPr6eaP4+/2DQerG+V69Ut4mezL1JtBTk54Iyc6tNsoHa9s+3wJSUHesXEgiHd/IxwuSXRtD9yC3VhQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-darwin-arm64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-darwin-arm64/-/binding-darwin-arm64-0.77.3.tgz", + "integrity": "sha512-DcRuFK/W3VqIlS8Wvb9bwd5yX+QTlr2ds2f5HW52OPx4odFwyF3+dD6nj3kyxvxITtf6U3jjqyaZEkq+LSQ5RQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-darwin-x64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-darwin-x64/-/binding-darwin-x64-0.77.3.tgz", + "integrity": "sha512-ZOKwC0nRNKpDKZq+sbFTbzJbrGR+drhIx3jhaTzSFpTWyzs3m5PW0yB+bKhhrqnk1Y26jtNixykBNiyhuPhCxQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-freebsd-x64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-freebsd-x64/-/binding-freebsd-x64-0.77.3.tgz", + "integrity": "sha512-z2LgrCT0YjxNIZRTOBFY5/FnqGX9S5QvkC/yoYqfDDuest8T6feTN68xXWg6D8+vFJPukvKEGY1xGikybc33xA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-linux-arm-gnueabihf": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.77.3.tgz", + "integrity": "sha512-VdpPQk9Xuu6C+p2DprWAEhIyELBrZLAzipMxoRnmox/HlFigs+FIeEfklCMls3yMSLCu6wKTdMdWeRu+dLXEHg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-linux-arm-musleabihf": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.77.3.tgz", + "integrity": "sha512-bhiPBIQKIxKtOSHgxYQiVeJ7CrfHWDZxaNFMf6ktDBmYBeD9lE9A356wDfgBPFkVOGV+juSPrnpu7qg2si/Q7Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-linux-arm64-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.77.3.tgz", + "integrity": "sha512-PYjFgTLCMxoa4yIgxVTNOltGk9nuPWTYZpDGEZu0he+0HC4iD86ZJIEl0mW0CaNaMU2np/7gAr+Izu3W71q+FQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-linux-arm64-musl": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.77.3.tgz", + "integrity": "sha512-GWa6MyEIwrDfEruj9SmIi/eG0XyEPSSupbltCL2k/cYgb+aUl1lT3sJLbOlKZqBbTzpuouAd+CkDqz+8UH/0qA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-linux-riscv64-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.77.3.tgz", + "integrity": "sha512-Wj1h95rGfMMVu0NMBNzo56WaB+z/mBVFRF4ij4Dbf2oBy4o3qDe2Q5Doa5U5c1k/uJbsM1X/mV7vqqgkHdORBA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-linux-s390x-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.77.3.tgz", + "integrity": "sha512-xTIGeZZoOfa7c4FU+1OcZTk73W/0YD2m3Zwg4p0Wtch+0Z6VRyu/7CENjBXpCRkWF4C8sgvl6d8ZKOzF5wU+Dw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-linux-x64-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.77.3.tgz", + "integrity": "sha512-YkgfAVmdtPMqJO/elfYBstnwGjD2P0SJwAs02c84/1JKRemrjSKqSewg3ETFIpo43c6b0g9OtoWj47Wwpnka7A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-linux-x64-musl": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-x64-musl/-/binding-linux-x64-musl-0.77.3.tgz", + "integrity": "sha512-//A5mBFmxvV+JzqI2/94SFpEF+nev0I/urXwhYPe8qzCYTlnzwxodH0Yb6js+BgebqiPdYs6YEp5Q2C/6OgsbA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-wasm32-wasi": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-wasm32-wasi/-/binding-wasm32-wasi-0.77.3.tgz", + "integrity": "sha512-4RCG1ZZyEyKIaZE2vXyFnVocDF1jIbfE/f5qbb1l0Wql2s4K5m1QDkKqPAVPuCmYiJ6+X2HyWus5QGqgnUKrXA==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-win32-arm64-msvc": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.77.3.tgz", + "integrity": "sha512-ppyKF8Y3iASeIBnPDL0mwDxnlq/nnKFEZpZ9dy2hDma/JDD9qmOheP3CGYZyUnkS9r0LvEtrtR5/FjKXF2VQOw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-minify/binding-win32-x64-msvc": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-minify/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.77.3.tgz", + "integrity": "sha512-8IY7xgdZjBDFyQCF0s7EB7YzVB+C4+p8AKDbPfKLYhSlntIfIqTYvSXc3dZQb83OH6kDLAs1GpdWgb8ByDu4kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-parser/binding-android-arm64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.77.3.tgz", + "integrity": "sha512-Tr9pldnu+Csd5dQm2/fLKJyBloxiBC/Xl3c3Ki1ZGQewndsFyfFOklFpigZCCqlt75o+HtwtoLiCx3y4i8cdjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-darwin-arm64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.77.3.tgz", + "integrity": "sha512-KL91O6OpfVUTOhTW8cQWQ44z4VhyqBAsRfTm7DQCczBZkArygp2Sg+uaYLXNLWlGPWs4CoyZPCvu4FC6p1Q+nA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-darwin-x64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.77.3.tgz", + "integrity": "sha512-BTWnX9ymZFdkJONuL20Y63ODjDo1hpRHcqa0Z9pqcLANFgS+sDltcu0DXkJpNuJoZQJ+/44FVSWFmbYGG+862g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-freebsd-x64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.77.3.tgz", + "integrity": "sha512-YGp4lA0deJXrqrQC1PZwfQSPuY+TPZJOr5pqB+GLekRVZDlq2++Wr3lZfsESp1inVZHGFZS0x55/MadABG23rg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.77.3.tgz", + "integrity": "sha512-C05V3gAtSM1j2gsybF4Z+vlA5wsuNJ+Ciklc0K9y1SNbObz2JDv/Q7PTYMUz9EFk7Y00aCzjy5sXEdCI191Htw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.77.3.tgz", + "integrity": "sha512-g4bbjZ/fDm1rQbfEhqXCtK4eLmmm6U+W37zsl5Lpy7c24RJYhR25keI+RWfwH5f31Sn5ytuwfxwgXeCby6AiVA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm64-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.77.3.tgz", + "integrity": "sha512-c2Ak73vOeGnSQhsaZpqVyGYXtmQ8TR4L3uX34LNavXTnzrXm20bk6i80Nxnksz3B+5ohYRiYhb+UVk1zk1Gl1A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm64-musl": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.77.3.tgz", + "integrity": "sha512-1DNLBoJ6fsEdymD8Q4bo5zXkK0gw3ZMkEZ+F5w+7OrJOiQqzp8JzCQ6HRmSsJgjvaXzBvy95nCH2RegoeSN9JQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.77.3.tgz", + "integrity": "sha512-Lv0RQCHRKezkDzNPXoPuB7KTnK7ktw3OgyuZmNJKFGmZRFjlm8w+sEhAiE8XaCGqoOA6ivNIRSheUYeFNpAANA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-linux-s390x-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.77.3.tgz", + "integrity": "sha512-Q0sOdRzyhhUaATgtSR7lG23SvalRI9/7oVAWArU/8fEXCU9NsfKnpeuXsgT/N5lG4mgcbhUrnGzKaOzYcaatdQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-linux-x64-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.77.3.tgz", + "integrity": "sha512-ckcntxRTyPE+4nnCDnc9t4kiO1CSs5jOR7Qe7KLStkU9SPQkUZyjNP2aSaHre+iQha5xXABag9pamqb0dOY/PQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-linux-x64-musl": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.77.3.tgz", + "integrity": "sha512-jrKtGQrjcocnWpUIxJ3qzb0WpLGcDZoQTen/CZ5QtuwFA5EudM5rAJMt+SQpYYL4UPK0CPm8G5ZWJXqernLe1A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-wasm32-wasi": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.77.3.tgz", + "integrity": "sha512-76f53rr4Dz7A/FdUaM1NegHsQqT2w8CDBnRCptzapVA8humKA/tlJ24XfLvvr76JeT/OSKXorPyJ5xyGCa+yQg==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-parser/binding-win32-arm64-msvc": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.77.3.tgz", + "integrity": "sha512-YiUlN4yS5U7ntU1eVsaSiKD5PzW3zaW1tSB6RIp/eaDg10xORAPXEpoCXYlo35tAOV3IklOrX8ClhSJxF99AEQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-parser/binding-win32-x64-msvc": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.77.3.tgz", + "integrity": "sha512-d4JRqTtkpyB7QrGQk65xhiSOIwK2WZiTW5aBjyoQ+SicrvnHtviAY1U1Mnl2AyldUZ6MkUvaR6k8tCm9FMhawg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.77.3.tgz", + "integrity": "sha512-5Vh+neJhhxuF0lYCjZXbxjqm2EO6YJ1jG+KuHntrd6VY67OMpYhWq2cZhUhy+xL9qLJVJRaeII7Xj9fciA6v7A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@oxc-transform/binding-android-arm64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-android-arm64/-/binding-android-arm64-0.77.3.tgz", + "integrity": "sha512-HZdfhSsaqBCwl/HtsRVNh7binRz0N3IdwlTc5emEqYWMMZ94RkhPheNnbhRCzdvnzRKrpGirf3Rsk1X2oqSlxg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-darwin-arm64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-darwin-arm64/-/binding-darwin-arm64-0.77.3.tgz", + "integrity": "sha512-5sMgT6Ie7S5UqqZCdssAGBVU5PouZKIIfUf10SM4dY7J/1M0Sb4E1E7O+p2VUkECJ2j2RFRykK5rdKz71na8hg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-darwin-x64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-darwin-x64/-/binding-darwin-x64-0.77.3.tgz", + "integrity": "sha512-k99EStA6V4jOoFwN0pblhWuOFTKnaMasTpJIq30227U/Cg1J+rttK8loONSvgrw6FUKLJSymUA2Ydwpdvn5+sg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-freebsd-x64": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-freebsd-x64/-/binding-freebsd-x64-0.77.3.tgz", + "integrity": "sha512-pxtPtFdJcI0xkUKWMaHV/fXy9MY5ugocA/gLoXIjTDKZC1OMVjr6Srrtk0CoUIU7l7DMePbcJIAtwrpHwRiwpQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-linux-arm-gnueabihf": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.77.3.tgz", + "integrity": "sha512-zXsbUE/5tU7OJwyhhKUfl559W9w7QJp8USKA3WyW7BzHrBe0V0U6Lw+tM18tgyEvvwvXn5Wg0Jj/RWZwhO9BAA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-linux-arm-musleabihf": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.77.3.tgz", + "integrity": "sha512-D3o/POM0GUno8x0zKgFKmlO5shpB/j0FdNiOXhv8nilNGQgUXwkEHC/SDjmYJNGZy1HTcXyB7P+yRX9dTUUaAg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-linux-arm64-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.77.3.tgz", + "integrity": "sha512-LgY4sT+bnt01l3Dxq3Zv19gMAsJ5kI7sdVvL3CNCtAj47h/Zdfxg7WlD+L+FJZ3sfTQ5n2SJ0WDiZm380isBxg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-linux-arm64-musl": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.77.3.tgz", + "integrity": "sha512-Fq72ARLt8iriotueGp7zaWjFpfYBpRS5WElmAtpZLIy/p1dNwBEDhVUIjAl+sU14y0odp+yaTRHM7ULnMYGZhQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-linux-riscv64-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.77.3.tgz", + "integrity": "sha512-jtq6JREdyZ6xdTFJGM5Gm068WCkoMwh3Fkm08rZ2TAu4qjISdkJvTQ1wiEDDz2F8sqAdmASDqxnE/2DJ6Z6Clg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-linux-s390x-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.77.3.tgz", + "integrity": "sha512-HQz++ZmT9xWU9KS24DE+8oVTeUPd/JQkbjL2uvr0+SWY3loPnLG3kFAOLE/xXgYG/0D24mZylbZUwhzYND4snw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-linux-x64-gnu": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.77.3.tgz", + "integrity": "sha512-GcuFDJf/pxrfd2hq+gBytlnr/hiPn36JxuPXP0nToNG4SNa1gHT8K0bDxZuN2UjmZlWmIC8ELDdpVcNeZON+lQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-linux-x64-musl": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-x64-musl/-/binding-linux-x64-musl-0.77.3.tgz", + "integrity": "sha512-unhkqVg/jb/kghmiMCto8AGKm3uBwH2P5/GwR8jZkBjSFX7ekNu6/8P5IuIs5KDiZXzcjww84vCzQVBlql6WkA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-wasm32-wasi": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-wasm32-wasi/-/binding-wasm32-wasi-0.77.3.tgz", + "integrity": "sha512-FOGQzHLYpf1Yx0KpaqRz9cuXwvlTu8RprjL1NLpuUKT/D7O3SThm+qhFX3El9RFj67jrSCcHhlElYCJB2p794g==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-win32-arm64-msvc": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.77.3.tgz", + "integrity": "sha512-o4EmaPBrdYv/mb4uU/ZzAZ6KGczcPnDwA3lZbVEuFMDPwczqL581gpJHFFlfXUwxToCosiHot8y4ELV+mKkZjw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-transform/binding-win32-x64-msvc": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/@oxc-transform/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.77.3.tgz", + "integrity": "sha512-l/J/T6jAL6QnsvdjzS7EcxwwToaGx9GPqXNGPU2sqbo8o/4ATB9Ky1/8oG/Mb+mPHgiULPBtFpJtDiDSI9fBIA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-wasm": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-wasm/-/watcher-wasm-2.5.1.tgz", + "integrity": "sha512-RJxlQQLkaMMIuWRozy+z2vEqbaQlCuaCgVZIUCzQLYggY22LZbP5Y1+ia+FD724Ids9e+XIyOLXLrLgQSHIthw==", + "bundleDependencies": [ + "napi-wasm" + ], + "license": "MIT", + "dependencies": { + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "napi-wasm": "^1.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-wasm/node_modules/napi-wasm": { + "version": "1.1.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "license": "MIT" + }, + "node_modules/@poppinss/colors": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.5.tgz", + "integrity": "sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw==", + "license": "MIT", + "dependencies": { + "kleur": "^4.1.5" + } + }, + "node_modules/@poppinss/colors/node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@poppinss/dumper": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.4.tgz", + "integrity": "sha512-iG0TIdqv8xJ3Lt9O8DrPRxw1MRLjNpoqiSGU03P/wNLP/s0ra0udPJ1J2Tx5M0J3H/cVyEgpbn8xUKRY9j59kQ==", + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@sindresorhus/is": "^7.0.2", + "supports-color": "^10.0.0" + } + }, + "node_modules/@poppinss/exception": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.2.tgz", + "integrity": "sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==", + "license": "MIT" + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.19", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz", + "integrity": "sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==", + "license": "MIT" + }, + "node_modules/@rollup/plugin-alias": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.1.tgz", + "integrity": "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "28.0.6", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.6.tgz", + "integrity": "sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/plugin-inject": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", + "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-inject/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/plugin-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.1.tgz", + "integrity": "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve/node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-6.0.2.tgz", + "integrity": "sha512-7QaYCf8bqF04dOy7w/eHmJeNExxTYwvKAmlSAH/EaWWUzbT0h5sbF6bktFoX/0F/0qwng5/dWFMyf3gzaM8DsQ==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", + "integrity": "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.0.tgz", + "integrity": "sha512-9f3nSTFI2ivfxc7/tHBHcJ8pRnp8ROrELvsVprlQPVvcZ+j5zztYd+PTJGpyIOAdTvNwNrpCXswKSeoQcyGjMQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.0.tgz", + "integrity": "sha512-tFZSEhqJ8Yrpe50TzOdeoYi72gi/jsnT7y8Qrozf3cNu28WX+s6I3XzEPUAqoaT9SAS8Xz9AzGTFlxxCH/w20w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.0.tgz", + "integrity": "sha512-+DikIIs+p6yU2hF51UaWG8BnHbq90X0QIOt5zqSKSZxY+G3qqdLih214e9InJal21af2PuuxkDectetGfbVPJw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.0.tgz", + "integrity": "sha512-5a+NofhdEB/WimSlFMskbFQn1vqz1FWryYpA99trmZGO6qEmiS0IsX6w4B3d91U878Q2ZQdiaFF1gxX4P147og==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.0.tgz", + "integrity": "sha512-igr/RlKPS3OCy4jD3XBmAmo3UAcNZkJSubRsw1JeM8bAbwf15k/3eMZXD91bnjheijJiOJcga3kfCLKjV8IXNg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.0.tgz", + "integrity": "sha512-MdigWzPSHlQzB1xZ+MdFDWTAH+kcn7UxjEBoOKuaso7z1DRlnAnrknB1mTtNOQ+GdPI8xgExAGwHeqQjntR0Cg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.0.tgz", + "integrity": "sha512-dmZseE0ZwA/4yy1+BwFrDqFTjjNg24GO9xSrb1weVbt6AFkhp5pz1gVS7IMtfIvoWy8yp6q/zN0bKnefRUImvQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.0.tgz", + "integrity": "sha512-fzhfn6p9Cfm3W8UrWKIa4l7Wfjs/KGdgaswMBBE3KY3Ta43jg2XsPrAtfezHpsRk0Nx+TFuS3hZk/To2N5kFPQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.0.tgz", + "integrity": "sha512-vVDD+iPDPmJQ5nAQ5Tifq3ywdv60FartglFI8VOCK+hcU9aoG0qlQTsDJP97O5yiTaTqlneZWoARMcVC5nyUoQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.0.tgz", + "integrity": "sha512-0d0jx08fzDHCzXqrtCMEEyxKU0SvJrWmUjUDE2/KDQ2UDJql0tfiwYvEx1oHELClKO8CNdE+AGJj+RqXscZpdQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.0.tgz", + "integrity": "sha512-XBYu9oW9eKJadWn8M7hkTZsD4yG+RrsTrVEgyKwb4L72cpJjRbRboTG9Lg9fec8MxJp/cfTHAocg4mnismQR8A==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.0.tgz", + "integrity": "sha512-wJaRvcT17PoOK6Ggcfo3nouFlybHvARBS4jzT0PC/lg17fIJHcDS2fZz3sD+iA4nRlho2zE6OGbU0HvwATdokQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.0.tgz", + "integrity": "sha512-GZ5bkMFteAGkcmh8x0Ok4LSa+L62Ez0tMsHPX6JtR0wl4Xc3bQcrFHDiR5DGLEDFtGrXih4Nd/UDaFqs968/wA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.0.tgz", + "integrity": "sha512-7CjPw6FflFsVOUfWOrVrREiV3IYXG4RzZ1ZQUaT3BtSK8YXN6x286o+sruPZJESIaPebYuFowmg54ZdrkVBYog==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.0.tgz", + "integrity": "sha512-nmvnl0ZiuysltcB/cKjUh40Rx4FbSyueERDsl2FLvLYr6pCgSsvGr3SocUT84svSpmloS7f1DRWqtRha74Gi1w==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.0.tgz", + "integrity": "sha512-Cv+moII5C8RM6gZbR3cb21o6rquVDZrN2o81maROg1LFzBz2dZUwIQSxFA8GtGZ/F2KtsqQ2z3eFPBb6akvQNg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.0.tgz", + "integrity": "sha512-PHcMG8DZTM9RCIjp8QIfN0VYtX0TtBPnWOTRurFhoCDoi9zptUZL2k7pCs+5rgut7JAiUsYy+huyhVKPcmxoog==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.0.tgz", + "integrity": "sha512-1SI/Rd47e8aQJeFWMDg16ET+fjvCcD/CzeaRmIEPmb05hx+3cCcwIF4ebUag4yTt/D1peE+Mgp0+Po3M358cAA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.0.tgz", + "integrity": "sha512-JwOCYxmumFDfDhx4kNyz6kTVK3gWzBIvVdMNzQMRDubcoGRDniOOmo6DDNP42qwZx3Bp9/6vWJ+kNzNqXoHmeA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.0.tgz", + "integrity": "sha512-IPMIfrfkG1GaEXi+JSsQEx8x9b4b+hRZXO7KYc2pKio3zO2/VDXDs6B9Ts/nnO+25Fk1tdAVtUn60HKKPPzDig==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sindresorhus/is": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.0.2.tgz", + "integrity": "sha512-d9xRovfKNz1SKieM0qJdO+PQonjnnIfSNWfHYnBSJ9hkjm0ZPw6HlxscDXYstp3z+7V2GOFHc+J0CYrYTjqCJw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@speed-highlight/core": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.7.tgz", + "integrity": "sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==", + "license": "CC0-1.0" + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", + "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.11" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", + "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.11", + "@tailwindcss/oxide-darwin-arm64": "4.1.11", + "@tailwindcss/oxide-darwin-x64": "4.1.11", + "@tailwindcss/oxide-freebsd-x64": "4.1.11", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", + "@tailwindcss/oxide-linux-x64-musl": "4.1.11", + "@tailwindcss/oxide-wasm32-wasi": "4.1.11", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", + "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", + "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", + "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", + "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", + "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", + "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", + "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", + "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", + "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", + "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@emnapi/wasi-threads": "^1.0.2", + "@napi-rs/wasm-runtime": "^0.2.11", + "@tybys/wasm-util": "^0.9.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", + "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", + "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.11.tgz", + "integrity": "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.11", + "@tailwindcss/oxide": "4.1.11", + "tailwindcss": "4.1.11" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", + "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz", + "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==", + "license": "MIT", + "optional": true, + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "license": "MIT" + }, + "node_modules/@types/parse-path": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/parse-path/-/parse-path-7.0.3.tgz", + "integrity": "sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg==", + "license": "MIT" + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "license": "MIT" + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/sizzle": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz", + "integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", + "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.38.0", + "@typescript-eslint/types": "^8.38.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", + "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", + "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", + "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.38.0", + "@typescript-eslint/tsconfig-utils": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", + "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.38.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@unhead/vue": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-2.0.12.tgz", + "integrity": "sha512-WFaiCVbBd39FK6Bx3GQskhgT9s45Vjx6dRQegYheVwU1AnF+FAfJVgWbrl21p6fRJcLAFp0xDz6wE18JYBM0eQ==", + "license": "MIT", + "dependencies": { + "hookable": "^5.5.3", + "unhead": "2.0.12" + }, + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + }, + "peerDependencies": { + "vue": ">=3.5.13" + } + }, + "node_modules/@vercel/nft": { + "version": "0.29.4", + "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.29.4.tgz", + "integrity": "sha512-6lLqMNX3TuycBPABycx7A9F1bHQR7kiQln6abjFbPrf5C/05qHM9M5E4PeTE59c7z8g6vHnx1Ioihb2AQl7BTA==", + "license": "MIT", + "dependencies": { + "@mapbox/node-pre-gyp": "^2.0.0", + "@rollup/pluginutils": "^5.1.3", + "acorn": "^8.6.0", + "acorn-import-attributes": "^1.9.5", + "async-sema": "^3.1.1", + "bindings": "^1.4.0", + "estree-walker": "2.0.2", + "glob": "^10.4.5", + "graceful-fs": "^4.2.9", + "node-gyp-build": "^4.2.2", + "picomatch": "^4.0.2", + "resolve-from": "^5.0.0" + }, + "bin": { + "nft": "out/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@vercel/nft/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.0.tgz", + "integrity": "sha512-iAliE72WsdhjzTOp2DtvKThq1VBC4REhwRcaA+zPAAph6I+OQhUXv+Xu2KS7ElxYtb7Zc/3R30Hwv1DxEo7NXQ==", + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-beta.19" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vitejs/plugin-vue-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-5.0.1.tgz", + "integrity": "sha512-X7qmQMXbdDh+sfHUttXokPD0cjPkMFoae7SgbkF9vi3idGUKmxLcnU2Ug49FHwiKXebfzQRIm5yK3sfCJzNBbg==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.7", + "@babel/plugin-transform-typescript": "^7.27.1", + "@rolldown/pluginutils": "^1.0.0-beta.21", + "@vue/babel-plugin-jsx": "^1.4.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", + "vue": "^3.0.0" + } + }, + "node_modules/@vitejs/plugin-vue-jsx/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.29.tgz", + "integrity": "sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==", + "license": "MIT" + }, + "node_modules/@vue-macros/common": { + "version": "3.0.0-beta.15", + "resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-3.0.0-beta.15.tgz", + "integrity": "sha512-DMgq/rIh1H20WYNWU7krIbEfJRYDDhy7ix64GlT4AVUJZZWCZ5pxiYVJR3A3GmWQPkn7Pg7i3oIiGqu4JGC65w==", + "license": "MIT", + "dependencies": { + "@vue/compiler-sfc": "^3.5.17", + "ast-kit": "^2.1.0", + "local-pkg": "^1.1.1", + "magic-string-ast": "^1.0.0", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=20.18.0" + }, + "funding": { + "url": "https://github.com/sponsors/vue-macros" + }, + "peerDependencies": { + "vue": "^2.7.0 || ^3.2.25" + }, + "peerDependenciesMeta": { + "vue": { + "optional": true + } + } + }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.4.0.tgz", + "integrity": "sha512-mCokbouEQ/ocRce/FpKCRItGo+013tHg7tixg3DUNS+6bmIchPt66012kBMm476vyEIJPafrvOf4E5OYj3shSw==", + "license": "MIT" + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.4.0.tgz", + "integrity": "sha512-9zAHmwgMWlaN6qRKdrg1uKsBKHvnUU+Py+MOCTuYZBoZsopa90Di10QRjB+YPnVss0BZbG/H5XFwJY1fTxJWhA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.9", + "@babel/types": "^7.26.9", + "@vue/babel-helper-vue-transform-on": "1.4.0", + "@vue/babel-plugin-resolve-type": "1.4.0", + "@vue/shared": "^3.5.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + } + } + }, + "node_modules/@vue/babel-plugin-resolve-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.4.0.tgz", + "integrity": "sha512-4xqDRRbQQEWHQyjlYSgZsWj44KfiF6D+ktCuXyZ8EnVDYV3pztmXJDf1HveAjUAXxAnR8daCQT51RneWWxtTyQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/parser": "^7.26.9", + "@vue/compiler-sfc": "^3.5.13" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.18.tgz", + "integrity": "sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@vue/shared": "3.5.18", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-core/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.18.tgz", + "integrity": "sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.18", + "@vue/shared": "3.5.18" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.18.tgz", + "integrity": "sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@vue/compiler-core": "3.5.18", + "@vue/compiler-dom": "3.5.18", + "@vue/compiler-ssr": "3.5.18", + "@vue/shared": "3.5.18", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.17", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.18.tgz", + "integrity": "sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.18", + "@vue/shared": "3.5.18" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/@vue/devtools-core": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.7.7.tgz", + "integrity": "sha512-9z9TLbfC+AjAi1PQyWX+OErjIaJmdFlbDHcD+cAMYKY6Bh5VlsAtCeGyRMrXwIlMEQPukvnWt3gZBLwTAIMKzQ==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.7", + "@vue/devtools-shared": "^7.7.7", + "mitt": "^3.0.1", + "nanoid": "^5.1.0", + "pathe": "^2.0.3", + "vite-hot-client": "^2.0.4" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz", + "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.7.7", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz", + "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.18.tgz", + "integrity": "sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.18" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.18.tgz", + "integrity": "sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.18", + "@vue/shared": "3.5.18" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.18.tgz", + "integrity": "sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.18", + "@vue/runtime-core": "3.5.18", + "@vue/shared": "3.5.18", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.18.tgz", + "integrity": "sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.18", + "@vue/shared": "3.5.18" + }, + "peerDependencies": { + "vue": "3.5.18" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.18.tgz", + "integrity": "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==", + "license": "MIT" + }, + "node_modules/@whatwg-node/disposablestack": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/disposablestack/-/disposablestack-0.0.6.tgz", + "integrity": "sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==", + "license": "MIT", + "dependencies": { + "@whatwg-node/promise-helpers": "^1.0.0", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@whatwg-node/fetch": { + "version": "0.10.9", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.9.tgz", + "integrity": "sha512-2TaXKmjy53cybNtaAtzbPOzwIPkjXbzvZcimnaJxQwYXKSC8iYnWoZOyT4+CFt8w0KDieg5J5dIMNzUrW/UZ5g==", + "license": "MIT", + "dependencies": { + "@whatwg-node/node-fetch": "^0.7.22", + "urlpattern-polyfill": "^10.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@whatwg-node/fetch/node_modules/urlpattern-polyfill": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz", + "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", + "license": "MIT" + }, + "node_modules/@whatwg-node/node-fetch": { + "version": "0.7.22", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.22.tgz", + "integrity": "sha512-h4GGjGF2vH3kGJ/fEOeg9Xfu4ncoyRwFcjGIxr/5dTBgZNVwq888byIsZ+XXRDJnNnRlzVVVQDcqrZpY2yctGA==", + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^3.1.1", + "@whatwg-node/disposablestack": "^0.0.6", + "@whatwg-node/promise-helpers": "^1.3.2", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@whatwg-node/promise-helpers": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@whatwg-node/promise-helpers/-/promise-helpers-1.3.2.tgz", + "integrity": "sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@whatwg-node/server": { + "version": "0.9.71", + "resolved": "https://registry.npmjs.org/@whatwg-node/server/-/server-0.9.71.tgz", + "integrity": "sha512-ueFCcIPaMgtuYDS9u0qlUoEvj6GiSsKrwnOLPp9SshqjtcRaR1IEHRjoReq3sXNydsF5i0ZnmuYgXq9dV53t0g==", + "license": "MIT", + "dependencies": { + "@whatwg-node/disposablestack": "^0.0.6", + "@whatwg-node/fetch": "^0.10.5", + "@whatwg-node/promise-helpers": "^1.2.2", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/abbrev": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", + "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansis": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.1.0.tgz", + "integrity": "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==", + "license": "ISC", + "engines": { + "node": ">=14" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", + "license": "MIT", + "dependencies": { + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ast-kit": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.1.1.tgz", + "integrity": "sha512-mfh6a7gKXE8pDlxTvqIc/syH/P3RkzbOF6LeHdcKztLEzYe6IMsRCL7N8vI7hqTGWNxpkCuuRTpT21xNWqhRtQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.7", + "pathe": "^2.0.3" + }, + "engines": { + "node": ">=20.18.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/ast-module-types": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-6.0.1.tgz", + "integrity": "sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/ast-walker-scope": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/ast-walker-scope/-/ast-walker-scope-0.8.1.tgz", + "integrity": "sha512-72XOdbzQCMKERvFrxAykatn2pu7osPNq/sNUzwcHdWzwPvOsNpPqkawfDXVvQbA2RT+ivtsMNjYdojTUZitt1A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.2", + "ast-kit": "^2.0.0" + }, + "engines": { + "node": ">=20.18.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/async-sema": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", + "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "license": "Apache-2.0" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.6.0.tgz", + "integrity": "sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/birpc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.5.0.tgz", + "integrity": "sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c12": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/c12/-/c12-3.1.0.tgz", + "integrity": "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==", + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.3", + "confbox": "^0.2.2", + "defu": "^6.1.4", + "dotenv": "^16.6.1", + "exsolve": "^1.0.7", + "giget": "^2.0.0", + "jiti": "^2.4.2", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.2.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.5" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "license": "MIT", + "dependencies": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/cache-content-type/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cache-content-type/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==", + "engines": { + "node": "*" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/ci-info": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", + "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", + "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "colors": "1.4.0" + } + }, + "node_modules/cli-table3/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clipboardy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-4.0.0.tgz", + "integrity": "sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==", + "license": "MIT", + "dependencies": { + "execa": "^8.0.1", + "is-wsl": "^3.1.0", + "is64bit": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-convert/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "license": "MIT", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "license": "ISC" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "license": "MIT" + }, + "node_modules/compatx": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/compatx/-/compatx-0.2.0.tgz", + "integrity": "sha512-6gLRNt4ygsi5NyMVhceOCFv14CIdDFN7fQjX1U4+47qVE/+kjPoXMK65KWK+dWxmFzMTuKazoQ9sch6pM0p5oA==", + "license": "MIT" + }, + "node_modules/compress-commons": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/compress-commons/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cookie-es": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-2.0.0.tgz", + "integrity": "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==", + "license": "MIT" + }, + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-file": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-file/-/copy-file-11.0.0.tgz", + "integrity": "sha512-mFsNh/DIANLqFt5VHZoGirdg7bK5+oTWlhnGu6tgRhzBlnEKWaPX2xrFaLltii/6rmhqFMJqffUgknuRdpYlHw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.11", + "p-event": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "license": "MIT", + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/croner": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/croner/-/croner-9.1.0.tgz", + "integrity": "sha512-p9nwwR4qyT5W996vBZhdvBCnMhicY5ytZkR4D1Xj0wuTDEiMnjwR57Q3RXYY/s0EpX6Ay3vgIcfaR+ewGHsi+g==", + "license": "MIT", + "engines": { + "node": ">=18.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crossws": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", + "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "license": "ISC", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.1.0.tgz", + "integrity": "sha512-Pu3rlKkd0ZtlCUzBrKL1Z4YmhKppjC1H9jo7u1o4qaKqyhvixFgu5qLyNIAOjSTg9DjVPtUqdROq2EfpVMEe+w==", + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^7.0.8", + "lilconfig": "^3.1.3" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/cssnano-preset-default": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.8.tgz", + "integrity": "sha512-d+3R2qwrUV3g4LEMOjnndognKirBZISylDZAF/TPeCWVjEwlXS2e4eN4ICkoobRe7pD3H6lltinKVyS1AJhdjQ==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.1", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^5.0.1", + "postcss-calc": "^10.1.1", + "postcss-colormin": "^7.0.4", + "postcss-convert-values": "^7.0.6", + "postcss-discard-comments": "^7.0.4", + "postcss-discard-duplicates": "^7.0.2", + "postcss-discard-empty": "^7.0.1", + "postcss-discard-overridden": "^7.0.1", + "postcss-merge-longhand": "^7.0.5", + "postcss-merge-rules": "^7.0.6", + "postcss-minify-font-values": "^7.0.1", + "postcss-minify-gradients": "^7.0.1", + "postcss-minify-params": "^7.0.4", + "postcss-minify-selectors": "^7.0.5", + "postcss-normalize-charset": "^7.0.1", + "postcss-normalize-display-values": "^7.0.1", + "postcss-normalize-positions": "^7.0.1", + "postcss-normalize-repeat-style": "^7.0.1", + "postcss-normalize-string": "^7.0.1", + "postcss-normalize-timing-functions": "^7.0.1", + "postcss-normalize-unicode": "^7.0.4", + "postcss-normalize-url": "^7.0.1", + "postcss-normalize-whitespace": "^7.0.1", + "postcss-ordered-values": "^7.0.2", + "postcss-reduce-initial": "^7.0.4", + "postcss-reduce-transforms": "^7.0.1", + "postcss-svgo": "^7.1.0", + "postcss-unique-selectors": "^7.0.4" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/cssnano-utils": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.1.tgz", + "integrity": "sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg==", + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/cypress": { + "version": "14.5.3", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-14.5.3.tgz", + "integrity": "sha512-syLwKjDeMg77FRRx68bytLdlqHXDT4yBVh0/PPkcgesChYDjUZbwxLqMXuryYKzAyJsPsQHUDW1YU74/IYEUIA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@cypress/request": "^3.0.9", + "@cypress/xvfb": "^1.2.4", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.7.1", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "ci-info": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-table3": "0.6.1", + "commander": "^6.2.1", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.4", + "enquirer": "^2.3.6", + "eventemitter2": "6.4.7", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "hasha": "5.2.2", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.8", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "process": "^0.11.10", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.7.1", + "supports-color": "^8.1.1", + "tmp": "~0.2.3", + "tree-kill": "1.2.2", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + } + }, + "node_modules/cypress/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/cypress/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cypress/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/cypress/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/cypress/node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cypress/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/cypress/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cypress/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/daisyui": { + "version": "5.0.48", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.0.48.tgz", + "integrity": "sha512-t2nvzKENuhbjkKmxhIoDgV/nzAnNLbswK9MBlOMnEO6hxfgNLlt7jVrHYWw6ts492JdQ0Mmf6iX3aO/u+1zXAw==", + "license": "MIT", + "funding": { + "url": "https://github.com/saadeghi/daisyui?sponsor=1" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/db0": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/db0/-/db0-0.3.2.tgz", + "integrity": "sha512-xzWNQ6jk/+NtdfLyXEipbX55dmDSeteLFt/ayF+wZUU5bzKgmrDOxmInUTbyVRp46YwnJdkDA1KhB7WIXFofJw==", + "license": "MIT", + "peerDependencies": { + "@electric-sql/pglite": "*", + "@libsql/client": "*", + "better-sqlite3": "*", + "drizzle-orm": "*", + "mysql2": "*", + "sqlite3": "*" + }, + "peerDependenciesMeta": { + "@electric-sql/pglite": { + "optional": true + }, + "@libsql/client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "drizzle-orm": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "sqlite3": { + "optional": true + } + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decache": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/decache/-/decache-4.6.2.tgz", + "integrity": "sha512-2LPqkLeu8XWHU8qNCS3kcF6sCcb5zIzvWaAHYSvPfwhdd7mHuah29NssMzrTYyHN4F5oFy2ko9OBYxegtU0FEw==", + "license": "MIT", + "dependencies": { + "callsite": "^1.0.0" + } + }, + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT" + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "license": "MIT" + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/detective-amd": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-6.0.1.tgz", + "integrity": "sha512-TtyZ3OhwUoEEIhTFoc1C9IyJIud3y+xYkSRjmvCt65+ycQuc3VcBrPRTMWoO/AnuCyOB8T5gky+xf7Igxtjd3g==", + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "escodegen": "^2.1.0", + "get-amd-module-type": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "bin": { + "detective-amd": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-cjs": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-6.0.1.tgz", + "integrity": "sha512-tLTQsWvd2WMcmn/60T2inEJNhJoi7a//PQ7DwRKEj1yEeiQs4mrONgsUtEJKnZmrGWBBmE0kJ1vqOG/NAxwaJw==", + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-es6": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-5.0.1.tgz", + "integrity": "sha512-XusTPuewnSUdoxRSx8OOI6xIA/uld/wMQwYsouvFN2LAg7HgP06NF1lHRV3x6BZxyL2Kkoih4ewcq8hcbGtwew==", + "license": "MIT", + "dependencies": { + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-postcss": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-7.0.1.tgz", + "integrity": "sha512-bEOVpHU9picRZux5XnwGsmCN4+8oZo7vSW0O0/Enq/TO5R2pIAP2279NsszpJR7ocnQt4WXU0+nnh/0JuK4KHQ==", + "license": "MIT", + "dependencies": { + "is-url": "^1.2.4", + "postcss-values-parser": "^6.0.2" + }, + "engines": { + "node": "^14.0.0 || >=16.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.47" + } + }, + "node_modules/detective-sass": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-6.0.1.tgz", + "integrity": "sha512-jSGPO8QDy7K7pztUmGC6aiHkexBQT4GIH+mBAL9ZyBmnUIOFbkfZnO8wPRRJFP/QP83irObgsZHCoDHZ173tRw==", + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-scss": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-5.0.1.tgz", + "integrity": "sha512-MAyPYRgS6DCiS6n6AoSBJXLGVOydsr9huwXORUlJ37K3YLyiN0vYHpzs3AdJOgHobBfispokoqrEon9rbmKacg==", + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-stylus": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-5.0.1.tgz", + "integrity": "sha512-Dgn0bUqdGbE3oZJ+WCKf8Dmu7VWLcmRJGc6RCzBgG31DLIyai9WAoEhYRgIHpt/BCRMrnXLbGWGPQuBUrnF0TA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-typescript": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-14.0.0.tgz", + "integrity": "sha512-pgN43/80MmWVSEi5LUuiVvO/0a9ss5V7fwVfrJ4QzAQRd3cwqU1SfWGXJFcNKUqoD5cS+uIovhw5t/0rSeC5Mw==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "^8.23.0", + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "typescript": "^5.4.4" + } + }, + "node_modules/detective-vue2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/detective-vue2/-/detective-vue2-2.2.0.tgz", + "integrity": "sha512-sVg/t6O2z1zna8a/UIV6xL5KUa2cMTQbdTIIvqNM0NIPswp52fe43Nwmbahzj3ww4D844u/vC2PYfiGLvD3zFA==", + "license": "MIT", + "dependencies": { + "@dependents/detective-less": "^5.0.1", + "@vue/compiler-sfc": "^3.5.13", + "detective-es6": "^5.0.1", + "detective-sass": "^6.0.1", + "detective-scss": "^5.0.1", + "detective-stylus": "^5.0.1", + "detective-typescript": "^14.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "typescript": "^5.4.4" + } + }, + "node_modules/devalue": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", + "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==", + "license": "MIT" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "license": "Apache-2.0" + }, + "node_modules/diff": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", + "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz", + "integrity": "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^4.18.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.191", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.191.tgz", + "integrity": "sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/enquirer/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/enquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/error-stack-parser-es": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", + "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/errx": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/errx/-/errx-0.1.0.tgz", + "integrity": "sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", + "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.8", + "@esbuild/android-arm": "0.25.8", + "@esbuild/android-arm64": "0.25.8", + "@esbuild/android-x64": "0.25.8", + "@esbuild/darwin-arm64": "0.25.8", + "@esbuild/darwin-x64": "0.25.8", + "@esbuild/freebsd-arm64": "0.25.8", + "@esbuild/freebsd-x64": "0.25.8", + "@esbuild/linux-arm": "0.25.8", + "@esbuild/linux-arm64": "0.25.8", + "@esbuild/linux-ia32": "0.25.8", + "@esbuild/linux-loong64": "0.25.8", + "@esbuild/linux-mips64el": "0.25.8", + "@esbuild/linux-ppc64": "0.25.8", + "@esbuild/linux-riscv64": "0.25.8", + "@esbuild/linux-s390x": "0.25.8", + "@esbuild/linux-x64": "0.25.8", + "@esbuild/netbsd-arm64": "0.25.8", + "@esbuild/netbsd-x64": "0.25.8", + "@esbuild/openbsd-arm64": "0.25.8", + "@esbuild/openbsd-x64": "0.25.8", + "@esbuild/openharmony-arm64": "0.25.8", + "@esbuild/sunos-x64": "0.25.8", + "@esbuild/win32-arm64": "0.25.8", + "@esbuild/win32-ia32": "0.25.8", + "@esbuild/win32-x64": "0.25.8" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/exsolve": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", + "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-npm-meta": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/fast-npm-meta/-/fast-npm-meta-0.4.4.tgz", + "integrity": "sha512-cq8EVW3jpX1U3dO1AYanz2BJ6n9ITQgCwE1xjNwI5jO2a9erE369OZNO8Wt/Wbw8YHhCD/dimH9BxRsY+6DinA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "license": "MIT" + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/filter-obj": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-6.1.0.tgz", + "integrity": "sha512-xdMtCAODmPloU9qtmPcdBV9Kd27NtMse+4ayThxqIHUES5Z2S6bGpap5PpdmNM56ub7y3i1eyr+vJJIIgWGKmA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "license": "MIT", + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", + "license": "MIT" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fuse.js": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz", + "integrity": "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-amd-module-type": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-6.0.1.tgz", + "integrity": "sha512-MtjsmYiCXcYDDrGqtNbeIYdAl85n+5mSv2r3FbzER/YV3ZILw4HNNIw34HuV5pyl0jzs6GFYU1VHVEefhgcNHQ==", + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port-please": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port-please/-/get-port-please-3.2.0.tgz", + "integrity": "sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==", + "license": "MIT" + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/giget": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", + "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.6", + "nypm": "^0.6.0", + "pathe": "^2.0.3" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/git-up": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-8.1.1.tgz", + "integrity": "sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==", + "license": "MIT", + "dependencies": { + "is-ssh": "^1.4.0", + "parse-url": "^9.2.0" + } + }, + "node_modules/git-url-parse": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-16.1.0.tgz", + "integrity": "sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==", + "license": "MIT", + "dependencies": { + "git-up": "^8.1.0" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/gzip-size": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-7.0.0.tgz", + "integrity": "sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==", + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/h3": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.3.tgz", + "integrity": "sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": "^0.3.4", + "defu": "^6.1.4", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.0", + "radix3": "^1.1.2", + "ufo": "^1.6.1", + "uncrypto": "^0.1.3" + } + }, + "node_modules/h3/node_modules/cookie-es": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", + "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "license": "MIT" + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", + "license": "MIT", + "dependencies": { + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-assert/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-assert/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-assert/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-shutdown": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/http-shutdown/-/http-shutdown-1.2.2.tgz", + "integrity": "sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==", + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/http-signature": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", + "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.18.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/httpxy": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/httpxy/-/httpxy-0.1.7.tgz", + "integrity": "sha512-pXNx8gnANKAndgga5ahefxc++tJvNL87CXoRwxn1cJE2ZkWEojF3tNfQIEhZX/vfpt+wzeAzpUI4qkediX1MLQ==", + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-meta": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/image-meta/-/image-meta-0.2.1.tgz", + "integrity": "sha512-K6acvFaelNxx8wc2VjbIzXKDVB0Khs0QT35U6NkGfTdCmjLNcO2945m7RFNR9/RPVFm48hq7QPzK8uGH18HCGw==", + "license": "MIT" + }, + "node_modules/impound": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/impound/-/impound-1.0.0.tgz", + "integrity": "sha512-8lAJ+1Arw2sMaZ9HE2ZmL5zOcMnt18s6+7Xqgq2aUVy4P1nlzAyPtzCDxsk51KVFwHEEdc6OWvUyqwHwhRYaug==", + "license": "MIT", + "dependencies": { + "exsolve": "^1.0.5", + "mocked-exports": "^0.1.1", + "pathe": "^2.0.3", + "unplugin": "^2.3.2", + "unplugin-utils": "^0.2.4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/index-to-position": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.1.0.tgz", + "integrity": "sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ioredis": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.6.1.tgz", + "integrity": "sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==", + "license": "MIT", + "dependencies": { + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "license": "MIT", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-installed-globally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-1.0.0.tgz", + "integrity": "sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==", + "license": "MIT", + "dependencies": { + "global-directory": "^4.0.1", + "is-path-inside": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "license": "MIT" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ssh": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", + "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", + "license": "MIT", + "dependencies": { + "protocols": "^2.0.1" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "license": "MIT" + }, + "node_modules/is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is64bit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is64bit/-/is64bit-2.0.0.tgz", + "integrity": "sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==", + "license": "MIT", + "dependencies": { + "system-architecture": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true, + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/junk": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", + "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "license": "MIT", + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/knitwork": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/knitwork/-/knitwork-1.2.0.tgz", + "integrity": "sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==", + "license": "MIT" + }, + "node_modules/koa": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.16.1.tgz", + "integrity": "sha512-umfX9d3iuSxTQP4pnzLOz0HKnPg0FaUUIKcye2lOiz3KPu1Y3M3xlz76dISdFPQs37P9eJz1wUpcTS6KDPn9fA==", + "license": "MIT", + "dependencies": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.9.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "engines": { + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" + } + }, + "node_modules/koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "license": "MIT" + }, + "node_modules/koa-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", + "license": "MIT", + "dependencies": { + "co": "^4.6.0", + "koa-compose": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/koa-send": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz", + "integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "resolve-path": "^1.4.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/koa-send/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa-send/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa-send/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa-static": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz", + "integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==", + "license": "MIT", + "dependencies": { + "debug": "^3.1.0", + "koa-send": "^5.0.0" + }, + "engines": { + "node": ">= 7.6.0" + } + }, + "node_modules/koa-static/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/koa/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/koa/node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "license": "MIT" + }, + "node_modules/lambda-local": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/lambda-local/-/lambda-local-2.2.0.tgz", + "integrity": "sha512-bPcgpIXbHnVGfI/omZIlgucDqlf4LrsunwoKue5JdZeGybt8L6KyJz2Zu19ffuZwIwLj2NAI2ZyaqNT6/cetcg==", + "license": "MIT", + "dependencies": { + "commander": "^10.0.1", + "dotenv": "^16.3.1", + "winston": "^3.10.0" + }, + "bin": { + "lambda-local": "build/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/launch-editor": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.10.0.tgz", + "integrity": "sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==", + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "> 0.8" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss/node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/listhen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/listhen/-/listhen-1.9.0.tgz", + "integrity": "sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==", + "license": "MIT", + "dependencies": { + "@parcel/watcher": "^2.4.1", + "@parcel/watcher-wasm": "^2.4.1", + "citty": "^0.1.6", + "clipboardy": "^4.0.0", + "consola": "^3.2.3", + "crossws": ">=0.2.0 <0.4.0", + "defu": "^6.1.4", + "get-port-please": "^3.1.2", + "h3": "^1.12.0", + "http-shutdown": "^1.2.2", + "jiti": "^2.1.2", + "mlly": "^1.7.1", + "node-forge": "^1.3.1", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "ufo": "^1.5.4", + "untun": "^0.1.3", + "uqr": "^0.1.2" + }, + "bin": { + "listen": "bin/listhen.mjs", + "listhen": "bin/listhen.mjs" + } + }, + "node_modules/listhen/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/local-pkg": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "license": "MIT", + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.0.1", + "quansync": "^0.2.8" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "license": "MIT" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/logform": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", + "license": "MIT", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/luxon": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.1.tgz", + "integrity": "sha512-RkRWjA926cTvz5rAb1BqyWkKbbjzCGchDUIKMCUvNi17j6f6j8uHGDV82Aqcqtzd+icoYpELmG3ksgGiFNNcNg==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-regexp": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/magic-regexp/-/magic-regexp-0.10.0.tgz", + "integrity": "sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==", + "license": "MIT", + "dependencies": { + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12", + "mlly": "^1.7.2", + "regexp-tree": "^0.1.27", + "type-level-regexp": "~0.1.17", + "ufo": "^1.5.4", + "unplugin": "^2.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/magic-string-ast": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/magic-string-ast/-/magic-string-ast-1.0.0.tgz", + "integrity": "sha512-8rbuNizut2gW94kv7pqgt0dvk+AHLPVIm0iJtpSgQJ9dx21eWx5SBel8z3jp1xtC0j6/iyK3AWGhAR1H61s7LA==", + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17" + }, + "engines": { + "node": ">=20.18.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "license": "MIT", + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micro-api-client": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/micro-api-client/-/micro-api-client-3.3.0.tgz", + "integrity": "sha512-y0y6CUB9RLVsy3kfgayU28746QrNMpSm9O/AYGNsBgOkJr/X/Jk0VLGoO8Ude7Bpa8adywzF+MzXNZRFRsNPhg==", + "license": "ISC" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.7.tgz", + "integrity": "sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ==", + "funding": [ + "https://github.com/sponsors/broofa" + ], + "license": "MIT", + "bin": { + "mime": "bin/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/mocked-exports": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/mocked-exports/-/mocked-exports-0.1.1.tgz", + "integrity": "sha512-aF7yRQr/Q0O2/4pIXm6PZ5G+jAd7QS4Yu8m+WEeEHGnbo+7mE36CbLSDQiXYV8bVL3NfmdeqPJct0tUlnjVSnA==", + "license": "MIT" + }, + "node_modules/module-definition": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-6.0.1.tgz", + "integrity": "sha512-FeVc50FTfVVQnolk/WQT8MX+2WVcDnTGiq6Wo+/+lJ2ET1bRVi3HG3YlJUfqagNMc/kUlFSoR96AJkxGpKz13g==", + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "bin": { + "module-definition": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz", + "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/nanotar": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nanotar/-/nanotar-0.2.0.tgz", + "integrity": "sha512-9ca1h0Xjvo9bEkE4UOxgAzLV0jHKe6LMaxo37ND2DAhhAtd0j8pR1Wxz+/goMrZO8AEZTWCmyaOsFI/W5AdpCQ==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/netlify": { + "version": "13.3.5", + "resolved": "https://registry.npmjs.org/netlify/-/netlify-13.3.5.tgz", + "integrity": "sha512-Nc3loyVASW59W+8fLDZT1lncpG7llffyZ2o0UQLx/Fr20i7P8oP+lE7+TEcFvXj9IUWU6LjB9P3BH+iFGyp+mg==", + "license": "MIT", + "dependencies": { + "@netlify/open-api": "^2.37.0", + "lodash-es": "^4.17.21", + "micro-api-client": "^3.3.0", + "node-fetch": "^3.0.0", + "p-wait-for": "^5.0.0", + "qs": "^6.9.6" + }, + "engines": { + "node": "^14.16.0 || >=16.0.0" + } + }, + "node_modules/netlify/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/nitropack": { + "version": "2.12.4", + "resolved": "https://registry.npmjs.org/nitropack/-/nitropack-2.12.4.tgz", + "integrity": "sha512-MPmPRJWTeH03f/NmpN4q3iI3Woik4uaaWIoX34W3gMJiW06Vm1te/lPzuu5EXpXOK7Q2m3FymGMPXcExqih96Q==", + "license": "MIT", + "dependencies": { + "@cloudflare/kv-asset-handler": "^0.4.0", + "@netlify/functions": "^3.1.10", + "@rollup/plugin-alias": "^5.1.1", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-inject": "^5.0.5", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.1", + "@rollup/plugin-replace": "^6.0.2", + "@rollup/plugin-terser": "^0.4.4", + "@vercel/nft": "^0.29.4", + "archiver": "^7.0.1", + "c12": "^3.1.0", + "chokidar": "^4.0.3", + "citty": "^0.1.6", + "compatx": "^0.2.0", + "confbox": "^0.2.2", + "consola": "^3.4.2", + "cookie-es": "^2.0.0", + "croner": "^9.1.0", + "crossws": "^0.3.5", + "db0": "^0.3.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "dot-prop": "^9.0.0", + "esbuild": "^0.25.6", + "escape-string-regexp": "^5.0.0", + "etag": "^1.8.1", + "exsolve": "^1.0.7", + "globby": "^14.1.0", + "gzip-size": "^7.0.0", + "h3": "^1.15.3", + "hookable": "^5.5.3", + "httpxy": "^0.1.7", + "ioredis": "^5.6.1", + "jiti": "^2.4.2", + "klona": "^2.0.6", + "knitwork": "^1.2.0", + "listhen": "^1.9.0", + "magic-string": "^0.30.17", + "magicast": "^0.3.5", + "mime": "^4.0.7", + "mlly": "^1.7.4", + "node-fetch-native": "^1.6.6", + "node-mock-http": "^1.0.1", + "ofetch": "^1.4.1", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.2.0", + "pretty-bytes": "^6.1.1", + "radix3": "^1.1.2", + "rollup": "^4.45.0", + "rollup-plugin-visualizer": "^6.0.3", + "scule": "^1.3.0", + "semver": "^7.7.2", + "serve-placeholder": "^2.0.2", + "serve-static": "^2.2.0", + "source-map": "^0.7.4", + "std-env": "^3.9.0", + "ufo": "^1.6.1", + "ultrahtml": "^1.6.0", + "uncrypto": "^0.1.3", + "unctx": "^2.4.1", + "unenv": "^2.0.0-rc.18", + "unimport": "^5.1.0", + "unplugin-utils": "^0.2.4", + "unstorage": "^1.16.1", + "untyped": "^2.0.0", + "unwasm": "^0.3.9", + "youch": "4.1.0-beta.8", + "youch-core": "^0.3.3" + }, + "bin": { + "nitro": "dist/cli/index.mjs", + "nitropack": "dist/cli/index.mjs" + }, + "engines": { + "node": "^16.11.0 || >=17.0.0" + }, + "peerDependencies": { + "xml2js": "^0.6.2" + }, + "peerDependenciesMeta": { + "xml2js": { + "optional": true + } + } + }, + "node_modules/nitropack/node_modules/youch": { + "version": "4.1.0-beta.8", + "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.8.tgz", + "integrity": "sha512-rY2A2lSF7zC+l7HH9Mq+83D1dLlsPnEvy8jTouzaptDZM6geqZ3aJe/b7ULCwRURPtWV3vbDjA2DDMdoBol0HQ==", + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.4", + "@poppinss/dumper": "^0.6.3", + "@speed-highlight/core": "^1.2.7", + "cookie": "^1.0.2", + "youch-core": "^0.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT" + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.6.tgz", + "integrity": "sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==", + "license": "MIT" + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-mock-http": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.1.tgz", + "integrity": "sha512-0gJJgENizp4ghds/Ywu2FCmcRsgBTmRQzYPZm61wy+Em2sBarSka0OhQS5huLBg6od1zkNpnWMCZloQDFVvOMQ==", + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "license": "MIT" + }, + "node_modules/node-source-walk": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-7.0.1.tgz", + "integrity": "sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.7" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/nopt": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", + "license": "ISC", + "dependencies": { + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nuxt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nuxt/-/nuxt-4.0.1.tgz", + "integrity": "sha512-1WbtiX127640PXUJ2Mb32ck0A0/hzBk6+oPQ0YvJnS/HZK3A/oJEW7sYCRPYyEBwUyIQk12QRCBHxmr6LLeXZQ==", + "license": "MIT", + "dependencies": { + "@nuxt/cli": "^3.26.4", + "@nuxt/devalue": "^2.0.2", + "@nuxt/devtools": "^2.6.2", + "@nuxt/kit": "4.0.1", + "@nuxt/schema": "4.0.1", + "@nuxt/telemetry": "^2.6.6", + "@nuxt/vite-builder": "4.0.1", + "@unhead/vue": "^2.0.12", + "@vue/shared": "^3.5.17", + "c12": "^3.1.0", + "chokidar": "^4.0.3", + "compatx": "^0.2.0", + "consola": "^3.4.2", + "cookie-es": "^2.0.0", + "defu": "^6.1.4", + "destr": "^2.0.5", + "devalue": "^5.1.1", + "errx": "^0.1.0", + "esbuild": "^0.25.8", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "exsolve": "^1.0.7", + "h3": "^1.15.3", + "hookable": "^5.5.3", + "ignore": "^7.0.5", + "impound": "^1.0.0", + "jiti": "^2.4.2", + "klona": "^2.0.6", + "knitwork": "^1.2.0", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "mocked-exports": "^0.1.1", + "nanotar": "^0.2.0", + "nitropack": "^2.12.3", + "nypm": "^0.6.0", + "ofetch": "^1.4.1", + "ohash": "^2.0.11", + "on-change": "^5.0.1", + "oxc-minify": "^0.77.3", + "oxc-parser": "^0.77.3", + "oxc-transform": "^0.77.3", + "oxc-walker": "^0.4.0", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.2.0", + "radix3": "^1.1.2", + "scule": "^1.3.0", + "semver": "^7.7.2", + "std-env": "^3.9.0", + "strip-literal": "^3.0.0", + "tinyglobby": "0.2.14", + "ufo": "^1.6.1", + "ultrahtml": "^1.6.0", + "uncrypto": "^0.1.3", + "unctx": "^2.4.1", + "unimport": "^5.1.0", + "unplugin": "^2.3.5", + "unplugin-vue-router": "^0.14.0", + "unstorage": "^1.16.1", + "untyped": "^2.0.0", + "vue": "^3.5.17", + "vue-bundle-renderer": "^2.1.1", + "vue-devtools-stub": "^0.1.0", + "vue-router": "^4.5.1" + }, + "bin": { + "nuxi": "bin/nuxt.mjs", + "nuxt": "bin/nuxt.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@parcel/watcher": "^2.1.0", + "@types/node": ">=18.12.0" + }, + "peerDependenciesMeta": { + "@parcel/watcher": { + "optional": true + }, + "@types/node": { + "optional": true + } + } + }, + "node_modules/nypm": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.0.tgz", + "integrity": "sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg==", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "pathe": "^2.0.3", + "pkg-types": "^2.0.0", + "tinyexec": "^0.3.2" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": "^14.16.0 || >=16.10.0" + } + }, + "node_modules/nypm/node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ofetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.4.1.tgz", + "integrity": "sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==", + "license": "MIT", + "dependencies": { + "destr": "^2.0.3", + "node-fetch-native": "^1.6.4", + "ufo": "^1.5.4" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, + "node_modules/on-change": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/on-change/-/on-change-5.0.1.tgz", + "integrity": "sha512-n7THCP7RkyReRSLkJb8kUWoNsxUIBxTkIp3JKno+sEz6o/9AJ3w3P9fzQkITEkMwyTKJjZciF3v/pVoouxZZMg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/on-change?sponsor=1" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "license": "MIT", + "dependencies": { + "fn.name": "1.x.x" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==" + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true, + "license": "MIT" + }, + "node_modules/oxc-minify": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/oxc-minify/-/oxc-minify-0.77.3.tgz", + "integrity": "sha512-fYCSYazHno31eATVyHNyP2MEEMrVLaKVglac7bIoJC/qlb3x+Vqhv4eUViseOkoGM46rb9k8ZdDwhsEMtFUQhA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxc-minify/binding-android-arm64": "0.77.3", + "@oxc-minify/binding-darwin-arm64": "0.77.3", + "@oxc-minify/binding-darwin-x64": "0.77.3", + "@oxc-minify/binding-freebsd-x64": "0.77.3", + "@oxc-minify/binding-linux-arm-gnueabihf": "0.77.3", + "@oxc-minify/binding-linux-arm-musleabihf": "0.77.3", + "@oxc-minify/binding-linux-arm64-gnu": "0.77.3", + "@oxc-minify/binding-linux-arm64-musl": "0.77.3", + "@oxc-minify/binding-linux-riscv64-gnu": "0.77.3", + "@oxc-minify/binding-linux-s390x-gnu": "0.77.3", + "@oxc-minify/binding-linux-x64-gnu": "0.77.3", + "@oxc-minify/binding-linux-x64-musl": "0.77.3", + "@oxc-minify/binding-wasm32-wasi": "0.77.3", + "@oxc-minify/binding-win32-arm64-msvc": "0.77.3", + "@oxc-minify/binding-win32-x64-msvc": "0.77.3" + } + }, + "node_modules/oxc-parser": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.77.3.tgz", + "integrity": "sha512-1h7nXjL0IGRT539tReIadfIjgrPPuuD6HmQGsgKdOxMEZGzfMeBk19bfg+sXMQi462cCnu5s5IGTEhOOlcVt1w==", + "license": "MIT", + "dependencies": { + "@oxc-project/types": "^0.77.3" + }, + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxc-parser/binding-android-arm64": "0.77.3", + "@oxc-parser/binding-darwin-arm64": "0.77.3", + "@oxc-parser/binding-darwin-x64": "0.77.3", + "@oxc-parser/binding-freebsd-x64": "0.77.3", + "@oxc-parser/binding-linux-arm-gnueabihf": "0.77.3", + "@oxc-parser/binding-linux-arm-musleabihf": "0.77.3", + "@oxc-parser/binding-linux-arm64-gnu": "0.77.3", + "@oxc-parser/binding-linux-arm64-musl": "0.77.3", + "@oxc-parser/binding-linux-riscv64-gnu": "0.77.3", + "@oxc-parser/binding-linux-s390x-gnu": "0.77.3", + "@oxc-parser/binding-linux-x64-gnu": "0.77.3", + "@oxc-parser/binding-linux-x64-musl": "0.77.3", + "@oxc-parser/binding-wasm32-wasi": "0.77.3", + "@oxc-parser/binding-win32-arm64-msvc": "0.77.3", + "@oxc-parser/binding-win32-x64-msvc": "0.77.3" + } + }, + "node_modules/oxc-transform": { + "version": "0.77.3", + "resolved": "https://registry.npmjs.org/oxc-transform/-/oxc-transform-0.77.3.tgz", + "integrity": "sha512-cFiyrki2/Tgs9i0GUe8zmnJNZsGrHtNoDcyo1zTHQl/Ak0/04PIBHzurX7ibMadxfRNIn0XG0tpNrrkGDJ3k6g==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxc-transform/binding-android-arm64": "0.77.3", + "@oxc-transform/binding-darwin-arm64": "0.77.3", + "@oxc-transform/binding-darwin-x64": "0.77.3", + "@oxc-transform/binding-freebsd-x64": "0.77.3", + "@oxc-transform/binding-linux-arm-gnueabihf": "0.77.3", + "@oxc-transform/binding-linux-arm-musleabihf": "0.77.3", + "@oxc-transform/binding-linux-arm64-gnu": "0.77.3", + "@oxc-transform/binding-linux-arm64-musl": "0.77.3", + "@oxc-transform/binding-linux-riscv64-gnu": "0.77.3", + "@oxc-transform/binding-linux-s390x-gnu": "0.77.3", + "@oxc-transform/binding-linux-x64-gnu": "0.77.3", + "@oxc-transform/binding-linux-x64-musl": "0.77.3", + "@oxc-transform/binding-wasm32-wasi": "0.77.3", + "@oxc-transform/binding-win32-arm64-msvc": "0.77.3", + "@oxc-transform/binding-win32-x64-msvc": "0.77.3" + } + }, + "node_modules/oxc-walker": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/oxc-walker/-/oxc-walker-0.4.0.tgz", + "integrity": "sha512-x5TJAZQD3kRnRBGZ+8uryMZUwkTYddwzBftkqyJIcmpBOXmoK/fwriRKATjZroR2d+aS7+2w1B0oz189bBTwfw==", + "license": "MIT", + "dependencies": { + "estree-walker": "^3.0.3", + "magic-regexp": "^0.10.0" + }, + "peerDependencies": { + "oxc-parser": ">=0.72.0" + } + }, + "node_modules/p-event": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-6.0.1.tgz", + "integrity": "sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==", + "license": "MIT", + "dependencies": { + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-wait-for": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-5.0.2.tgz", + "integrity": "sha512-lwx6u1CotQYPVju77R+D0vFomni/AqRfqLmqQ8hekklqZ6gAY9rONh7lBQ0uxWMkC2AuX9b2DVAl8To0NyP1JA==", + "license": "MIT", + "dependencies": { + "p-timeout": "^6.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/package-manager-detector": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz", + "integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==", + "license": "MIT" + }, + "node_modules/parse-gitignore": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-gitignore/-/parse-gitignore-2.0.0.tgz", + "integrity": "sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-path": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", + "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", + "license": "MIT", + "dependencies": { + "protocols": "^2.0.0" + } + }, + "node_modules/parse-url": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-9.2.0.tgz", + "integrity": "sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==", + "license": "MIT", + "dependencies": { + "@types/parse-path": "^7.0.0", + "parse-path": "^7.0.0" + }, + "engines": { + "node": ">=14.13.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "license": "MIT" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.2.0.tgz", + "integrity": "sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/portfinder": { + "version": "1.0.37", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.37.tgz", + "integrity": "sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==", + "license": "MIT", + "dependencies": { + "async": "^3.2.6", + "debug": "^4.3.6" + }, + "engines": { + "node": ">= 10.12" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.1.1.tgz", + "integrity": "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12 || ^20.9 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.38" + } + }, + "node_modules/postcss-colormin": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.4.tgz", + "integrity": "sha512-ziQuVzQZBROpKpfeDwmrG+Vvlr0YWmY/ZAk99XD+mGEBuEojoFekL41NCsdhyNUtZI7DPOoIWIR7vQQK9xwluw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.1", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-convert-values": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.6.tgz", + "integrity": "sha512-MD/eb39Mr60hvgrqpXsgbiqluawYg/8K4nKsqRsuDX9f+xN1j6awZCUv/5tLH8ak3vYp/EMXwdcnXvfZYiejCQ==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-discard-comments": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.4.tgz", + "integrity": "sha512-6tCUoql/ipWwKtVP/xYiFf1U9QgJ0PUvxN7pTcsQ8Ns3Fnwq1pU5D5s1MhT/XySeLq6GXNvn37U46Ded0TckWg==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.1.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.2.tgz", + "integrity": "sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w==", + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-discard-empty": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.1.tgz", + "integrity": "sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg==", + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.1.tgz", + "integrity": "sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg==", + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-import/node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-merge-longhand": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.5.tgz", + "integrity": "sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^7.0.5" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-merge-rules": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.6.tgz", + "integrity": "sha512-2jIPT4Tzs8K87tvgCpSukRQ2jjd+hH6Bb8rEEOUDmmhOeTcqDg5fEFK8uKIu+Pvc3//sm3Uu6FRqfyv7YF7+BQ==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.1", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^5.0.1", + "postcss-selector-parser": "^7.1.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.1.tgz", + "integrity": "sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.1.tgz", + "integrity": "sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A==", + "license": "MIT", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^5.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-minify-params": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.4.tgz", + "integrity": "sha512-3OqqUddfH8c2e7M35W6zIwv7jssM/3miF9cbCSb1iJiWvtguQjlxZGIHK9JRmc8XAKmE2PFGtHSM7g/VcW97sw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.1", + "cssnano-utils": "^5.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.0.5.tgz", + "integrity": "sha512-x2/IvofHcdIrAm9Q+p06ZD1h6FPcQ32WtCRVodJLDR+WMn8EVHI1kvLxZuGKz/9EY5nAmI6lIQIrpo4tBy5+ug==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "postcss-selector-parser": "^7.1.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-nesting": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.2.tgz", + "integrity": "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-resolve-nested": "^3.1.0", + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.1.tgz", + "integrity": "sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ==", + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.1.tgz", + "integrity": "sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.1.tgz", + "integrity": "sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.1.tgz", + "integrity": "sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-string": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.1.tgz", + "integrity": "sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.1.tgz", + "integrity": "sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.4.tgz", + "integrity": "sha512-LvIURTi1sQoZqj8mEIE8R15yvM+OhbR1avynMtI9bUzj5gGKR/gfZFd8O7VMj0QgJaIFzxDwxGl/ASMYAkqO8g==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-url": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.1.tgz", + "integrity": "sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.1.tgz", + "integrity": "sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-ordered-values": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.2.tgz", + "integrity": "sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw==", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^5.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.4.tgz", + "integrity": "sha512-rdIC9IlMBn7zJo6puim58Xd++0HdbvHeHaPgXsimMfG1ijC5A9ULvNLSE0rUKVJOvNMcwewW4Ga21ngyJjY/+Q==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.1", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.1.tgz", + "integrity": "sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.1.0.tgz", + "integrity": "sha512-KnAlfmhtoLz6IuU3Sij2ycusNs4jPW+QoFE5kuuUOK8awR6tMxZQrs5Ey3BUz7nFCzT3eqyFgqkyrHiaU2xx3w==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^4.0.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.4.tgz", + "integrity": "sha512-pmlZjsmEAG7cHd7uK3ZiNSW6otSZ13RHuZ/4cDN/bVglS5EpF2r2oxY99SuOHa8m7AWoBCelTS3JPpzsIs8skQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.1.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/postcss-values-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-6.0.2.tgz", + "integrity": "sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==", + "license": "MPL-2.0", + "dependencies": { + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "quote-unquote": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "postcss": "^8.2.9" + } + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/precinct": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-12.2.0.tgz", + "integrity": "sha512-NFBMuwIfaJ4SocE9YXPU/n4AcNSoFMVFjP72nvl3cx69j/ke61/hPOWFREVxLkFhhEGnA8ZuVfTqJBa+PK3b5w==", + "license": "MIT", + "dependencies": { + "@dependents/detective-less": "^5.0.1", + "commander": "^12.1.0", + "detective-amd": "^6.0.1", + "detective-cjs": "^6.0.1", + "detective-es6": "^5.0.1", + "detective-postcss": "^7.0.1", + "detective-sass": "^6.0.1", + "detective-scss": "^5.0.1", + "detective-stylus": "^5.0.1", + "detective-typescript": "^14.0.0", + "detective-vue2": "^2.2.0", + "module-definition": "^6.0.1", + "node-source-walk": "^7.0.1", + "postcss": "^8.5.1", + "typescript": "^5.7.3" + }, + "bin": { + "precinct": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/precinct/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "license": "MIT", + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/protocols": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", + "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/quansync": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", + "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quote-unquote": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quote-unquote/-/quote-unquote-1.0.0.tgz", + "integrity": "sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==", + "license": "MIT" + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc9": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", + "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/read-package-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", + "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", + "license": "MIT", + "dependencies": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "license": "MIT", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "license": "MIT", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "license": "ISC" + }, + "node_modules/replace-in-file": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-6.3.5.tgz", + "integrity": "sha512-arB9d3ENdKva2fxRnSjwBEXfK1npgyci7ZZuwysgAp7ORjHSyxz6oqIjTEv8R0Ydl4Ll7uOAZXL4vbkhGIizCg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "glob": "^7.2.0", + "yargs": "^17.2.1" + }, + "bin": { + "replace-in-file": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/replace-in-file/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/replace-in-file/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/replace-in-file/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-package-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz", + "integrity": "sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-path": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", + "integrity": "sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==", + "license": "MIT", + "dependencies": { + "http-errors": "~1.6.2", + "path-is-absolute": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/resolve-path/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" + }, + "node_modules/resolve-path/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "license": "ISC" + }, + "node_modules/resolve-path/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.0.tgz", + "integrity": "sha512-ONmkT3Ud3IfW15nl7l4qAZko5/2iZ5ALVBDh02ZSZ5IGVLJSYkRcRa3iB58VyEIyoofs9m2xdVrm+lTi97+3pw==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.46.0", + "@rollup/rollup-android-arm64": "4.46.0", + "@rollup/rollup-darwin-arm64": "4.46.0", + "@rollup/rollup-darwin-x64": "4.46.0", + "@rollup/rollup-freebsd-arm64": "4.46.0", + "@rollup/rollup-freebsd-x64": "4.46.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.46.0", + "@rollup/rollup-linux-arm-musleabihf": "4.46.0", + "@rollup/rollup-linux-arm64-gnu": "4.46.0", + "@rollup/rollup-linux-arm64-musl": "4.46.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.46.0", + "@rollup/rollup-linux-ppc64-gnu": "4.46.0", + "@rollup/rollup-linux-riscv64-gnu": "4.46.0", + "@rollup/rollup-linux-riscv64-musl": "4.46.0", + "@rollup/rollup-linux-s390x-gnu": "4.46.0", + "@rollup/rollup-linux-x64-gnu": "4.46.0", + "@rollup/rollup-linux-x64-musl": "4.46.0", + "@rollup/rollup-win32-arm64-msvc": "4.46.0", + "@rollup/rollup-win32-ia32-msvc": "4.46.0", + "@rollup/rollup-win32-x64-msvc": "4.46.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-visualizer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-6.0.3.tgz", + "integrity": "sha512-ZU41GwrkDcCpVoffviuM9Clwjy5fcUxlz0oMoTXTYsK+tcIFzbdacnrr2n8TXcHxbGKKXtOdjxM2HUS4HjkwIw==", + "license": "MIT", + "dependencies": { + "open": "^8.0.0", + "picomatch": "^4.0.2", + "source-map": "^0.7.4", + "yargs": "^17.5.1" + }, + "bin": { + "rollup-plugin-visualizer": "dist/bin/cli.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "rolldown": "1.x || ^1.0.0-beta", + "rollup": "2.x || 3.x || 4.x" + }, + "peerDependenciesMeta": { + "rolldown": { + "optional": true + }, + "rollup": { + "optional": true + } + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" + }, + "node_modules/scule": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz", + "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-placeholder": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/serve-placeholder/-/serve-placeholder-2.0.2.tgz", + "integrity": "sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==", + "license": "MIT", + "dependencies": { + "defu": "^6.1.4" + } + }, + "node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-git": { + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.28.0.tgz", + "integrity": "sha512-Rs/vQRwsn1ILH1oBUy8NucJlXmnnLeLCfcvbSehkPzbv3wwoFWIdtfd6Ndo6ZPhlPsCZ60CPI4rxurnwAa+a2w==", + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/sirv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz", + "integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==", + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "license": "CC0-1.0" + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "license": "MIT" + }, + "node_modules/streamx": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz", + "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==", + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "license": "MIT" + }, + "node_modules/structured-clone-es": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/structured-clone-es/-/structured-clone-es-1.0.0.tgz", + "integrity": "sha512-FL8EeKFFyNQv5cMnXI31CIMCsFarSVI2bF0U0ImeNE3g/F1IvJQyqzOXxPBRXiwQfyBTlbNe88jh1jFW0O/jiQ==", + "license": "ISC" + }, + "node_modules/stylehacks": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.6.tgz", + "integrity": "sha512-iitguKivmsueOmTO0wmxURXBP8uqOO+zikLGZ7Mm9e/94R4w5T999Js2taS/KBOnQ/wdC3jN3vNSrkGDrlnqQg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.1", + "postcss-selector-parser": "^7.1.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.32" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/superjson": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", + "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/supports-color": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.0.0.tgz", + "integrity": "sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svgo": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", + "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.4.1" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/system-architecture": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/system-architecture/-/system-architecture-0.1.0.tgz", + "integrity": "sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", + "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/terser": { + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/throttleit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", + "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", + "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "license": "MIT", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "license": "MIT" + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "license": "MIT", + "engines": { + "node": ">=0.6.x" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true, + "license": "Unlicense" + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-level-regexp": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/type-level-regexp/-/type-level-regexp-0.1.17.tgz", + "integrity": "sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==", + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz", + "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, + "node_modules/unctx": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/unctx/-/unctx-2.4.1.tgz", + "integrity": "sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17", + "unplugin": "^2.1.0" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "license": "MIT", + "optional": true + }, + "node_modules/unenv": { + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.19.tgz", + "integrity": "sha512-t/OMHBNAkknVCI7bVB9OWjUUAwhVv9vsPIAGnNUxnu3FxPQN11rjh0sksLMzc3g7IlTgvHmOTl4JM7JHpcv5wA==", + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "exsolve": "^1.0.7", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "ufo": "^1.6.1" + } + }, + "node_modules/unhead": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/unhead/-/unhead-2.0.12.tgz", + "integrity": "sha512-5oo0lwz81XDXCmrHGzgmbaNOxM8R9MZ3FkEs2ROHeW8e16xsrv7qXykENlISrcxr3RLPHQEsD1b6js9P2Oj/Ow==", + "license": "MIT", + "dependencies": { + "hookable": "^5.5.3" + }, + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unimport": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/unimport/-/unimport-5.2.0.tgz", + "integrity": "sha512-bTuAMMOOqIAyjV4i4UH7P07pO+EsVxmhOzQ2YJ290J6mkLUdozNhb5I/YoOEheeNADC03ent3Qj07X0fWfUpmw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "pkg-types": "^2.2.0", + "scule": "^1.3.0", + "strip-literal": "^3.0.0", + "tinyglobby": "^0.2.14", + "unplugin": "^2.3.5", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unixify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", + "integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==", + "license": "MIT", + "dependencies": { + "normalize-path": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unixify/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "license": "MIT", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unplugin": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.5.tgz", + "integrity": "sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.1", + "picomatch": "^4.0.2", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin-utils": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.2.4.tgz", + "integrity": "sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==", + "license": "MIT", + "dependencies": { + "pathe": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/unplugin-vue-router": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/unplugin-vue-router/-/unplugin-vue-router-0.14.0.tgz", + "integrity": "sha512-ipjunvS5e2aFHBAUFuLbHl2aHKbXXXBhTxGT9wZx66fNVPdEQzVVitF8nODr1plANhTTa3UZ+DQu9uyLngMzoQ==", + "license": "MIT", + "dependencies": { + "@vue-macros/common": "3.0.0-beta.15", + "ast-walker-scope": "^0.8.1", + "chokidar": "^4.0.3", + "fast-glob": "^3.3.3", + "json5": "^2.2.3", + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "scule": "^1.3.0", + "unplugin": "^2.3.5", + "unplugin-utils": "^0.2.4", + "yaml": "^2.8.0" + }, + "peerDependencies": { + "@vue/compiler-sfc": "^3.5.17", + "vue-router": "^4.5.1" + }, + "peerDependenciesMeta": { + "vue-router": { + "optional": true + } + } + }, + "node_modules/unstorage": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.16.1.tgz", + "integrity": "sha512-gdpZ3guLDhz+zWIlYP1UwQ259tG5T5vYRzDaHMkQ1bBY1SQPutvZnrRjTFaWUUpseErJIgAZS51h6NOcZVZiqQ==", + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^4.0.3", + "destr": "^2.0.5", + "h3": "^1.15.3", + "lru-cache": "^10.4.3", + "node-fetch-native": "^1.6.6", + "ofetch": "^1.4.1", + "ufo": "^1.6.1" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.6.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6.0.3 || ^7.0.0", + "@deno/kv": ">=0.9.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.1", + "@vercel/kv": "^1.0.1", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/unstorage/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/untun": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/untun/-/untun-0.1.3.tgz", + "integrity": "sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==", + "license": "MIT", + "dependencies": { + "citty": "^0.1.5", + "consola": "^3.2.3", + "pathe": "^1.1.1" + }, + "bin": { + "untun": "bin/untun.mjs" + } + }, + "node_modules/untun/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, + "node_modules/untyped": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/untyped/-/untyped-2.0.0.tgz", + "integrity": "sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "defu": "^6.1.4", + "jiti": "^2.4.2", + "knitwork": "^1.2.0", + "scule": "^1.3.0" + }, + "bin": { + "untyped": "dist/cli.mjs" + } + }, + "node_modules/unwasm": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/unwasm/-/unwasm-0.3.9.tgz", + "integrity": "sha512-LDxTx/2DkFURUd+BU1vUsF/moj0JsoTvl+2tcg2AUOiEzVturhGGx17/IMgGvKUYdZwr33EJHtChCJuhu9Ouvg==", + "license": "MIT", + "dependencies": { + "knitwork": "^1.0.0", + "magic-string": "^0.30.8", + "mlly": "^1.6.1", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "unplugin": "^1.10.0" + } + }, + "node_modules/unwasm/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/unwasm/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, + "node_modules/unwasm/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/unwasm/node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/unwasm/node_modules/unplugin": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", + "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uqr": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/uqr/-/uqr-0.1.2.tgz", + "integrity": "sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==", + "license": "MIT" + }, + "node_modules/urlpattern-polyfill": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", + "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.6.tgz", + "integrity": "sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.6", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.40.0", + "tinyglobby": "^0.2.14" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-dev-rpc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vite-dev-rpc/-/vite-dev-rpc-1.1.0.tgz", + "integrity": "sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==", + "license": "MIT", + "dependencies": { + "birpc": "^2.4.0", + "vite-hot-client": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0" + } + }, + "node_modules/vite-hot-client": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-2.1.0.tgz", + "integrity": "sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-plugin-checker": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.10.1.tgz", + "integrity": "sha512-imiBsmYTPdjQHIZiEi5BhJ7K8Z/kCjTFMn+Qa4+5ao/a4Yql4yWFcf81FDJqlMiM57iY4Q3Z7PdoEe4KydULYQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "chokidar": "^4.0.3", + "npm-run-path": "^6.0.0", + "picocolors": "^1.1.1", + "picomatch": "^4.0.2", + "strip-ansi": "^7.1.0", + "tiny-invariant": "^1.3.3", + "tinyglobby": "^0.2.14", + "vscode-uri": "^3.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "peerDependencies": { + "@biomejs/biome": ">=1.7", + "eslint": ">=7", + "meow": "^13.2.0", + "optionator": "^0.9.4", + "stylelint": ">=16", + "typescript": "*", + "vite": ">=2.0.0", + "vls": "*", + "vti": "*", + "vue-tsc": "~2.2.10 || ^3.0.0" + }, + "peerDependenciesMeta": { + "@biomejs/biome": { + "optional": true + }, + "eslint": { + "optional": true + }, + "meow": { + "optional": true + }, + "optionator": { + "optional": true + }, + "stylelint": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vls": { + "optional": true + }, + "vti": { + "optional": true + }, + "vue-tsc": { + "optional": true + } + } + }, + "node_modules/vite-plugin-checker/node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vite-plugin-checker/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vite-plugin-checker/node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vite-plugin-inspect": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-11.3.2.tgz", + "integrity": "sha512-nzwvyFQg58XSMAmKVLr2uekAxNYvAbz1lyPmCAFVIBncCgN9S/HPM+2UM9Q9cvc4JEbC5ZBgwLAdaE2onmQuKg==", + "license": "MIT", + "dependencies": { + "ansis": "^4.1.0", + "debug": "^4.4.1", + "error-stack-parser-es": "^1.0.5", + "ohash": "^2.0.11", + "open": "^10.2.0", + "perfect-debounce": "^1.0.0", + "sirv": "^3.0.1", + "unplugin-utils": "^0.2.4", + "vite-dev-rpc": "^1.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/vite-plugin-inspect/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vite-plugin-inspect/node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vite-plugin-vue-tracer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vite-plugin-vue-tracer/-/vite-plugin-vue-tracer-1.0.0.tgz", + "integrity": "sha512-a+UB9IwGx5uwS4uG/a9kM6fCMnxONDkOTbgCUbhFpiGhqfxrrC1+9BibV7sWwUnwj1Dg6MnRxG0trLgUZslDXA==", + "license": "MIT", + "dependencies": { + "estree-walker": "^3.0.3", + "exsolve": "^1.0.7", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "source-map-js": "^1.2.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0", + "vue": "^3.5.0" + } + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.18.tgz", + "integrity": "sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.18", + "@vue/compiler-sfc": "3.5.18", + "@vue/runtime-dom": "3.5.18", + "@vue/server-renderer": "3.5.18", + "@vue/shared": "3.5.18" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-bundle-renderer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/vue-bundle-renderer/-/vue-bundle-renderer-2.1.1.tgz", + "integrity": "sha512-+qALLI5cQncuetYOXp4yScwYvqh8c6SMXee3B+M7oTZxOgtESP0l4j/fXdEJoZ+EdMxkGWIj+aSEyjXkOdmd7g==", + "license": "MIT", + "dependencies": { + "ufo": "^1.5.4" + } + }, + "node_modules/vue-devtools-stub": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/vue-devtools-stub/-/vue-devtools-stub-0.1.0.tgz", + "integrity": "sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==", + "license": "MIT" + }, + "node_modules/vue-router": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", + "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "license": "MIT" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/winston": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "license": "MIT", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.7.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.9.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "license": "MIT", + "dependencies": { + "logform": "^2.7.0", + "readable-stream": "^3.6.2", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/winston/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/winston/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-6.0.0.tgz", + "integrity": "sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yauzl/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/ylru": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.4.0.tgz", + "integrity": "sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", + "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/youch": { + "version": "4.1.0-beta.10", + "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", + "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@poppinss/dumper": "^0.6.4", + "@speed-highlight/core": "^1.2.7", + "cookie": "^1.0.2", + "youch-core": "^0.3.3" + } + }, + "node_modules/youch-core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", + "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", + "license": "MIT", + "dependencies": { + "@poppinss/exception": "^1.2.2", + "error-stack-parser-es": "^1.0.5" + } + }, + "node_modules/zip-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..5ea96c2 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "nuxt-app", + "private": true, + "type": "module", + "scripts": { + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "@nuxtjs/tailwindcss": "^6.14.0", + "@tailwindcss/vite": "^4.1.11", + "daisyui": "^5.0.48", + "nuxt": "^4.0.1", + "tailwindcss": "^4.1.11", + "vue": "^3.5.17", + "vue-router": "^4.5.1" + }, + "devDependencies": { + } +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..18993ad91cfd43e03b074dd0b5cc3f37ab38e49c GIT binary patch literal 4286 zcmeHLOKuuL5PjK%MHWVi6lD zOGiREbCw`xmFozJ^aNatJY>w+g ze6a2@u~m#^BZm@8wco9#Crlli0uLb^3E$t2-WIc^#(?t)*@`UpuofJ(Uyh@F>b3Ph z$D^m8Xq~pTkGJ4Q`Q2)te3mgkWYZ^Ijq|hkiP^9`De={bQQ%heZC$QU2UpP(-tbl8 zPWD2abEew;oat@w`uP3J^YpsgT%~jT(Dk%oU}sa$7|n6hBjDj`+I;RX(>)%lm_7N{+B7Mu%H?422lE%MBJH!!YTN2oT7xr>>N-8OF$C&qU^ z>vLsa{$0X%q1fjOe3P1mCv#lN{xQ4_*HCSAZjTb1`}mlc+9rl8$B3OP%VT@mch_~G z7Y+4b{r>9e=M+7vSI;BgB?ryZDY4m>&wcHSn81VH1N~`0gvwH{ z8dv#hG|OK`>1;j7tM#B)Z7zDN?{6=dUal}$e Date: Wed, 30 Jul 2025 08:15:35 +0200 Subject: [PATCH 002/274] =?UTF-8?q?feat:=20Composables=20pour=20la=20gesti?= =?UTF-8?q?on=20des=20donn=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - useApi.js : Service API générique avec gestion d'erreurs - useSites.js : Gestion des sites industriels - useMachines.js : Gestion des machines et création depuis types - useMachineTypes.js : Gestion des types de machines - useMachineTypesApi.js : API pour les types de machines - useComposants.js : Gestion des composants hiérarchiques - usePieces.js : Gestion des pièces de machines - useCustomFields.js : Gestion des champs personnalisés - useToast.js : Système de notifications toast --- app/composables/useApi.js | 75 +++ app/composables/useComposants.js | 134 ++++++ app/composables/useCustomFields.js | 97 ++++ app/composables/useMachineTypes.js | 654 ++++++++++++++++++++++++++ app/composables/useMachineTypesApi.js | 117 +++++ app/composables/useMachines.js | 123 +++++ app/composables/usePieces.js | 134 ++++++ app/composables/useSites.js | 100 ++++ app/composables/useToast.js | 66 +++ 9 files changed, 1500 insertions(+) create mode 100644 app/composables/useApi.js create mode 100644 app/composables/useComposants.js create mode 100644 app/composables/useCustomFields.js create mode 100644 app/composables/useMachineTypes.js create mode 100644 app/composables/useMachineTypesApi.js create mode 100644 app/composables/useMachines.js create mode 100644 app/composables/usePieces.js create mode 100644 app/composables/useSites.js create mode 100644 app/composables/useToast.js diff --git a/app/composables/useApi.js b/app/composables/useApi.js new file mode 100644 index 0000000..232c416 --- /dev/null +++ b/app/composables/useApi.js @@ -0,0 +1,75 @@ +import { useToast } from './useToast' + +export function useApi() { + const { showSuccess, showError, showInfo } = useToast() + const API_BASE_URL = process.env.NUXT_PUBLIC_API_BASE_URL || 'http://localhost:3000/api' + const API_TIMEOUT = parseInt(process.env.NUXT_PUBLIC_API_TIMEOUT || '30000') + + const apiCall = async (endpoint, options = {}) => { + const url = `${API_BASE_URL}${endpoint}` + const defaultOptions = { + headers: { + 'Content-Type': 'application/json', + }, + } + + // Ajouter un timeout à la requête + const controller = new AbortController() + const timeoutId = setTimeout(() => controller.abort(), API_TIMEOUT) + + try { + const response = await fetch(url, { + ...defaultOptions, + ...options, + signal: controller.signal + }) + + clearTimeout(timeoutId) + + if (response.ok) { + const data = await response.json() + return { success: true, data } + } else { + const errorData = await response.json().catch(() => ({})) + const errorMessage = errorData.message || `Erreur ${response.status}: ${response.statusText}` + showError(errorMessage) + return { success: false, error: errorMessage, status: response.status } + } + } catch (error) { + clearTimeout(timeoutId) + const errorMessage = error.name === 'AbortError' ? 'Timeout de la requête' : error.message || 'Erreur réseau' + showError(`Erreur réseau: ${errorMessage}`) + return { success: false, error: errorMessage } + } + } + + const get = async (endpoint) => { + return apiCall(endpoint, { method: 'GET' }) + } + + const post = async (endpoint, data) => { + return apiCall(endpoint, { + method: 'POST', + body: JSON.stringify(data) + }) + } + + const patch = async (endpoint, data) => { + return apiCall(endpoint, { + method: 'PATCH', + body: JSON.stringify(data) + }) + } + + const del = async (endpoint) => { + return apiCall(endpoint, { method: 'DELETE' }) + } + + return { + apiCall, + get, + post, + patch, + delete: del + } +} \ No newline at end of file diff --git a/app/composables/useComposants.js b/app/composables/useComposants.js new file mode 100644 index 0000000..54e3b26 --- /dev/null +++ b/app/composables/useComposants.js @@ -0,0 +1,134 @@ +import { ref } from 'vue' +import { useToast } from './useToast' +import { useApi } from './useApi' + +const composants = ref([]) +const loading = ref(false) + +export function useComposants() { + const { showSuccess, showError, showInfo } = useToast() + const { get, post, patch, delete: del } = useApi() + + const loadComposants = async () => { + loading.value = true + try { + const result = await get('/composants') + if (result.success) { + composants.value = result.data + showInfo(`Chargement de ${composants.value.length} composant(s) réussi`) + } + } catch (error) { + console.error('Erreur lors du chargement des composants:', error) + } finally { + loading.value = false + } + } + + const getComposantsByMachine = async (machineId) => { + loading.value = true + try { + const result = await get(`/composants/machine/${machineId}`) + if (result.success) { + return { success: true, data: result.data } + } + return { success: false, error: result.error } + } catch (error) { + console.error('Erreur lors du chargement des composants:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const getComposantHierarchy = async (machineId) => { + loading.value = true + try { + const result = await get(`/composants/hierarchy/${machineId}`) + if (result.success) { + return { success: true, data: result.data } + } + return { success: false, error: result.error } + } catch (error) { + console.error('Erreur lors du chargement de la hiérarchie:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const createComposant = async (composantData) => { + loading.value = true + try { + const result = await post('/composants', composantData) + if (result.success) { + composants.value.push(result.data) + showSuccess(`Composant "${composantData.name}" créé avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la création du composant:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const updateComposantData = async (id, composantData) => { + loading.value = true + try { + const result = await patch(`/composants/${id}`, composantData) + if (result.success) { + const index = composants.value.findIndex(comp => comp.id === id) + if (index !== -1) { + composants.value[index] = result.data + } + showSuccess(`Composant "${composantData.name}" mis à jour avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la mise à jour du composant:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const deleteComposant = async (id) => { + loading.value = true + try { + const result = await del(`/composants/${id}`) + if (result.success) { + const deletedComposant = composants.value.find(comp => comp.id === id) + composants.value = composants.value.filter(comp => comp.id !== id) + showSuccess(`Composant "${deletedComposant?.name || 'inconnu'}" supprimé avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la suppression du composant:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const getComposantById = (id) => { + return composants.value.find(comp => comp.id === id) + } + + const getComposants = () => composants.value + const isLoading = () => loading.value + + return { + composants, + loading, + loadComposants, + getComposantsByMachine, + getComposantHierarchy, + createComposant, + updateComposant: updateComposantData, + deleteComposant, + getComposantById, + getComposants, + isLoading + } +} \ No newline at end of file diff --git a/app/composables/useCustomFields.js b/app/composables/useCustomFields.js new file mode 100644 index 0000000..b010129 --- /dev/null +++ b/app/composables/useCustomFields.js @@ -0,0 +1,97 @@ +import { ref } from 'vue' +import { useApi } from './useApi' + +export function useCustomFields() { + const { apiCall } = useApi() + const customFieldValues = ref([]) + const loading = ref(false) + + // Créer une valeur de champ personnalisé + const createCustomFieldValue = async (customFieldValueData) => { + try { + const result = await apiCall('/custom-fields/values', { + method: 'POST', + body: JSON.stringify(customFieldValueData) + }) + return result + } catch (error) { + console.error('Erreur lors de la création de la valeur de champ personnalisé:', error) + return { success: false, error } + } + } + + // Obtenir les valeurs de champs personnalisés pour une entité + const getCustomFieldValuesByEntity = async (entityType, entityId) => { + try { + loading.value = true + const result = await apiCall(`/custom-fields/values/${entityType}/${entityId}`, { + method: 'GET' + }) + if (result.success) { + customFieldValues.value = result.data + } + return result + } catch (error) { + console.error('Erreur lors de la récupération des valeurs de champs personnalisés:', error) + return { success: false, error } + } finally { + loading.value = false + } + } + + // Mettre à jour une valeur de champ personnalisé + const updateCustomFieldValue = async (id, updateData) => { + try { + const result = await apiCall(`/custom-fields/values/${id}`, { + method: 'PATCH', + body: JSON.stringify(updateData) + }) + return result + } catch (error) { + console.error('Erreur lors de la mise à jour de la valeur de champ personnalisé:', error) + return { success: false, error } + } + } + + // Créer ou mettre à jour une valeur de champ personnalisé + const upsertCustomFieldValue = async (customFieldId, entityType, entityId, value) => { + try { + const result = await apiCall('/custom-fields/values/upsert', { + method: 'POST', + body: JSON.stringify({ + customFieldId, + entityType, + entityId, + value + }) + }) + return result + } catch (error) { + console.error('Erreur lors de la création/mise à jour de la valeur de champ personnalisé:', error) + return { success: false, error } + } + } + + // Supprimer une valeur de champ personnalisé + const deleteCustomFieldValue = async (id) => { + try { + const result = await apiCall(`/custom-fields/values/${id}`, { + method: 'DELETE' + }) + return result + } catch (error) { + console.error('Erreur lors de la suppression de la valeur de champ personnalisé:', error) + return { success: false, error } + } + } + + return { + customFieldValues, + loading, + createCustomFieldValue, + getCustomFieldValuesByEntity, + updateCustomFieldValue, + upsertCustomFieldValue, + deleteCustomFieldValue + } +} \ No newline at end of file diff --git a/app/composables/useMachineTypes.js b/app/composables/useMachineTypes.js new file mode 100644 index 0000000..d81d0e7 --- /dev/null +++ b/app/composables/useMachineTypes.js @@ -0,0 +1,654 @@ +import { ref } from 'vue' + +// Types de machines prédéfinis avec structure hiérarchique +const machineTypes = ref([ + // Machines de production + { + id: 1, + name: 'Presse hydraulique', + category: 'Production', + description: 'Machine de formage par compression hydraulique', + maintenanceFrequency: 'Mensuelle', + components: [ + { + name: 'Système hydraulique', + subComponents: [ + { + name: 'Pompe hydraulique', + subComponents: [ + { name: 'Rotor' }, + { name: 'Stator' }, + { name: 'Joint d\'étanchéité' } + ] + }, + { + name: 'Cylindre principal', + subComponents: [ + { name: 'Piston' }, + { name: 'Tige' }, + { name: 'Joint de piston' } + ] + }, + { + name: 'Soupapes de sécurité', + subComponents: [ + { name: 'Soupape de surpression' }, + { name: 'Soupape de décharge' } + ] + } + ] + }, + { + name: 'Système mécanique', + subComponents: [ + { + name: 'Banc de machine', + subComponents: [ + { name: 'Poutre supérieure' }, + { name: 'Poutre inférieure' }, + { name: 'Colonnes' } + ] + }, + { + name: 'Système de guidage', + subComponents: [ + { name: 'Rails de guidage' }, + { name: 'Patins' } + ] + } + ] + } + ], + criticalParts: ['Pompe hydraulique', 'Cylindre principal', 'Soupapes de sécurité'], + specifications: { + force: '100-5000 tonnes', + course: '100-800 mm', + vitesse: '5-50 mm/s' + } + }, + { + id: 2, + name: 'Convoyeur à bande', + category: 'Production', + description: 'Système de transport continu de matériaux', + maintenanceFrequency: 'Hebdomadaire', + components: [ + { + name: 'Système de transport', + subComponents: [ + { + name: 'Bande transporteuse', + subComponents: [ + { name: 'Carcasse' }, + { name: 'Revêtement' }, + { name: 'Armature' } + ] + }, + { + name: 'Rouleaux', + subComponents: [ + { name: 'Rouleaux porteurs' }, + { name: 'Rouleaux de retour' }, + { name: 'Rouleaux d\'impact' } + ] + } + ] + }, + { + name: 'Système d\'entraînement', + subComponents: [ + { + name: 'Moteur d\'entraînement', + subComponents: [ + { name: 'Rotor' }, + { name: 'Stator' }, + { name: 'Roulements' } + ] + }, + { + name: 'Réducteur', + subComponents: [ + { name: 'Engrenages' }, + { name: 'Arbre de sortie' } + ] + } + ] + } + ], + criticalParts: ['Bande transporteuse', 'Rouleaux', 'Moteur d\'entraînement'], + specifications: { + longueur: '5-100 m', + largeur: '400-2000 mm', + vitesse: '0.5-3 m/s' + } + }, + { + id: 3, + name: 'Robot de soudage', + category: 'Production', + description: 'Robot industriel pour opérations de soudage automatisé', + maintenanceFrequency: 'Trimestrielle', + components: [ + { + name: 'Bras robotique', + subComponents: [ + { + name: 'Base rotative', + subComponents: [ + { name: 'Moteur de rotation' }, + { name: 'Réducteur' }, + { name: 'Capteur de position' } + ] + }, + { + name: 'Bras articulé', + subComponents: [ + { name: 'Joint 1' }, + { name: 'Joint 2' }, + { name: 'Joint 3' } + ] + } + ] + }, + { + name: 'Système de soudage', + subComponents: [ + { + name: 'Torche de soudage', + subComponents: [ + { name: 'Électrode' }, + { name: 'Gainage' }, + { name: 'Conduit de gaz' } + ] + }, + { + name: 'Alimentation électrique', + subComponents: [ + { name: 'Transformateur' }, + { name: 'Régulateur de courant' } + ] + } + ] + } + ], + criticalParts: ['Bras robotique', 'Torche de soudage', 'Contrôleur'], + specifications: { + portée: '1.5-3 m', + charge: '5-200 kg', + précision: '±0.1 mm' + } + }, + + // Machines de transformation + { + id: 4, + name: 'Tour CNC', + category: 'Transformation', + description: 'Machine-outil pour usinage de pièces cylindriques', + maintenanceFrequency: 'Mensuelle', + components: [ + { + name: 'Banc de machine', + subComponents: [ + { + name: 'Banc principal', + subComponents: [ + { name: 'Poutre' }, + { name: 'Guidages' }, + { name: 'Vis à billes' } + ] + } + ] + }, + { + name: 'Système de broche', + subComponents: [ + { + name: 'Broche principale', + subComponents: [ + { name: 'Arbre de broche' }, + { name: 'Roulements' }, + { name: 'Moteur de broche' } + ] + }, + { + name: 'Contre-pointe', + subComponents: [ + { name: 'Pointe' }, + { name: 'Cylindre' } + ] + } + ] + } + ], + criticalParts: ['Banc de machine', 'Broche', 'Contre-pointe'], + specifications: { + diamètre: '200-1000 mm', + longueur: '500-3000 mm', + puissance: '5-50 kW' + } + }, + { + id: 5, + name: 'Fraiseuse', + category: 'Transformation', + description: 'Machine-outil pour usinage par enlèvement de copeaux', + maintenanceFrequency: 'Mensuelle', + components: [ + { + name: 'Table de travail', + subComponents: [ + { + name: 'Table X', + subComponents: [ + { name: 'Guidages X' }, + { name: 'Vis à billes X' }, + { name: 'Moteur X' } + ] + }, + { + name: 'Table Y', + subComponents: [ + { name: 'Guidages Y' }, + { name: 'Vis à billes Y' }, + { name: 'Moteur Y' } + ] + } + ] + }, + { + name: 'Système de broche', + subComponents: [ + { + name: 'Broche verticale', + subComponents: [ + { name: 'Arbre de broche' }, + { name: 'Roulements' }, + { name: 'Moteur de broche' } + ] + } + ] + } + ], + criticalParts: ['Table de travail', 'Broche', 'Guidages'], + specifications: { + courseX: '400-2000 mm', + courseY: '300-1500 mm', + courseZ: '200-800 mm' + } + }, + + // Machines de manutention + { + id: 6, + name: 'Pont roulant', + category: 'Manutention', + description: 'Système de levage et transport de charges lourdes', + maintenanceFrequency: 'Mensuelle', + components: [ + { + name: 'Poutre principale', + subComponents: [ + { + name: 'Poutre de roulement', + subComponents: [ + { name: 'Profilé principal' }, + { name: 'Rails de roulement' }, + { name: 'Renforts' } + ] + } + ] + }, + { + name: 'Système de palans', + subComponents: [ + { + name: 'Palans', + subComponents: [ + { name: 'Moteur de levage' }, + { name: 'Treuil' }, + { name: 'Crochet' } + ] + }, + { + name: 'Système de translation', + subComponents: [ + { name: 'Moteur de translation' }, + { name: 'Roues de roulement' } + ] + } + ] + } + ], + criticalParts: ['Poutre principale', 'Palans', 'Rails de guidage'], + specifications: { + capacité: '1-500 tonnes', + portée: '5-50 m', + hauteur: '3-20 m' + } + }, + { + id: 7, + name: 'Chariot élévateur', + category: 'Manutention', + description: 'Véhicule de manutention pour charges palettisées', + maintenanceFrequency: 'Hebdomadaire', + components: [ + { + name: 'Système de levage', + subComponents: [ + { + name: 'Mast', + subComponents: [ + { name: 'Mât extérieur' }, + { name: 'Mât intérieur' }, + { name: 'Cylindres de levage' } + ] + }, + { + name: 'Fourches', + subComponents: [ + { name: 'Fourche gauche' }, + { name: 'Fourche droite' }, + { name: 'Système de réglage' } + ] + } + ] + }, + { + name: 'Groupe motopropulseur', + subComponents: [ + { + name: 'Moteur', + subComponents: [ + { name: 'Bloc moteur' }, + { name: 'Système d\'injection' }, + { name: 'Système de refroidissement' } + ] + }, + { + name: 'Transmission', + subComponents: [ + { name: 'Boîte de vitesses' }, + { name: 'Arbre de transmission' }, + { name: 'Pont arrière' } + ] + } + ] + } + ], + criticalParts: ['Mast', 'Fourches', 'Moteur'], + specifications: { + capacité: '1-10 tonnes', + hauteur: '3-6 m', + type: 'Électrique/Diesel/Gaz' + } + }, + + // Machines de traitement + { + id: 8, + name: 'Compresseur d\'air', + category: 'Traitement', + description: 'Générateur d\'air comprimé pour applications industrielles', + maintenanceFrequency: 'Hebdomadaire', + components: [ + { + name: 'Système de compression', + subComponents: [ + { + name: 'Compresseur', + subComponents: [ + { name: 'Pistons' }, + { name: 'Cylindres' }, + { name: 'Soupapes' } + ] + }, + { + name: 'Réservoir', + subComponents: [ + { name: 'Cuve' }, + { name: 'Soupape de sécurité' }, + { name: 'Manomètre' } + ] + } + ] + }, + { + name: 'Système de filtration', + subComponents: [ + { + name: 'Filtres', + subComponents: [ + { name: 'Filtre à air' }, + { name: 'Filtre à huile' }, + { name: 'Séparateur d\'eau' } + ] + } + ] + } + ], + criticalParts: ['Compresseur', 'Réservoir', 'Filtres'], + specifications: { + débit: '100-10000 L/min', + pression: '7-10 bar', + puissance: '5-500 kW' + } + }, + { + id: 9, + name: 'Pompe hydraulique', + category: 'Traitement', + description: 'Pompe pour circuits hydrauliques industriels', + maintenanceFrequency: 'Mensuelle', + components: [ + { + name: 'Système de pompage', + subComponents: [ + { + name: 'Rotor', + subComponents: [ + { name: 'Ailettes' }, + { name: 'Arbre' } + ] + }, + { + name: 'Stator', + subComponents: [ + { name: 'Corps' }, + { name: 'Chambres' } + ] + } + ] + }, + { + name: 'Système d\'étanchéité', + subComponents: [ + { + name: 'Joint d\'étanchéité', + subComponents: [ + { name: 'Joint radial' }, + { name: 'Joint axial' } + ] + } + ] + } + ], + criticalParts: ['Rotor', 'Stator', 'Joint d\'étanchéité'], + specifications: { + débit: '10-500 L/min', + pression: '50-350 bar', + type: 'Piston/Palette/Engrenage' + } + }, + + // Machines de contrôle + { + id: 10, + name: 'Capteur de température', + category: 'Contrôle', + description: 'Instrument de mesure de température industrielle', + maintenanceFrequency: 'Annuelle', + components: [ + { + name: 'Système de mesure', + subComponents: [ + { + name: 'Élément sensible', + subComponents: [ + { name: 'Fil de platine' }, + { name: 'Isolation' } + ] + }, + { + name: 'Câblage', + subComponents: [ + { name: 'Fils de connexion' }, + { name: 'Gaine de protection' } + ] + } + ] + }, + { + name: 'Système de transmission', + subComponents: [ + { + name: 'Transmetteur', + subComponents: [ + { name: 'Circuit électronique' }, + { name: 'Affichage' } + ] + } + ] + } + ], + criticalParts: ['Élément sensible', 'Câblage', 'Transmetteur'], + specifications: { + plage: '-50 à +500°C', + précision: '±0.5°C', + type: 'PT100/PT1000/Thermocouple' + } + }, + { + id: 11, + name: 'Manomètre', + category: 'Contrôle', + description: 'Instrument de mesure de pression', + maintenanceFrequency: 'Annuelle', + components: [ + { + name: 'Système de mesure', + subComponents: [ + { + name: 'Tube de Bourdon', + subComponents: [ + { name: 'Tube' }, + { name: 'Extrémité fixe' }, + { name: 'Extrémité mobile' } + ] + }, + { + name: 'Cadran', + subComponents: [ + { name: 'Échelle' }, + { name: 'Aiguille' } + ] + } + ] + }, + { + name: 'Système de connexion', + subComponents: [ + { + name: 'Joint', + subComponents: [ + { name: 'Joint d\'étanchéité' }, + { name: 'Filetage' } + ] + } + ] + } + ], + criticalParts: ['Tube de Bourdon', 'Cadran', 'Joint'], + specifications: { + plage: '0-600 bar', + précision: '±1%', + type: 'Analogique/Numérique' + } + } +]) + +// Catégories disponibles +const categories = ref([ + 'Production', + 'Transformation', + 'Manutention', + 'Traitement', + 'Contrôle' +]) + +export function useMachineTypes() { + const getTypes = () => machineTypes.value + + const getTypeById = (id) => { + return machineTypes.value.find(type => type.id === id) + } + + const getTypesByCategory = (category) => { + return machineTypes.value.filter(type => type.category === category) + } + + const getCategories = () => categories.value + + const addType = (newType) => { + const id = Math.max(...machineTypes.value.map(t => t.id)) + 1 + machineTypes.value.push({ + id, + ...newType + }) + } + + const updateType = (id, updatedType) => { + const index = machineTypes.value.findIndex(type => type.id === id) + if (index !== -1) { + machineTypes.value[index] = { ...machineTypes.value[index], ...updatedType } + } + } + + const deleteType = (id) => { + const index = machineTypes.value.findIndex(type => type.id === id) + if (index !== -1) { + machineTypes.value.splice(index, 1) + } + } + + // Méthodes pour la hiérarchie + const flattenComponents = (components, level = 0) => { + let flat = [] + components.forEach(comp => { + flat.push({ ...comp, level }) + if (comp.subComponents && comp.subComponents.length > 0) { + flat = flat.concat(flattenComponents(comp.subComponents, level + 1)) + } + }) + return flat + } + + const getComponentHierarchy = (typeId) => { + const type = getTypeById(typeId) + if (!type || !type.components) return [] + return flattenComponents(type.components) + } + + return { + getTypes, + getTypeById, + getTypesByCategory, + getCategories, + addType, + updateType, + deleteType, + flattenComponents, + getComponentHierarchy + } +} \ No newline at end of file diff --git a/app/composables/useMachineTypesApi.js b/app/composables/useMachineTypesApi.js new file mode 100644 index 0000000..5e6a830 --- /dev/null +++ b/app/composables/useMachineTypesApi.js @@ -0,0 +1,117 @@ +import { ref } from 'vue' +import { useToast } from './useToast' +import { useApi } from './useApi' + +const machineTypes = ref([]) +const loading = ref(false) + +export function useMachineTypesApi() { + const { showSuccess, showError, showInfo } = useToast() + const { get, post, patch, delete: del } = useApi() + + const loadMachineTypes = async () => { + loading.value = true + try { + const result = await get('/types/machines') + if (result.success) { + machineTypes.value = result.data + showInfo(`Chargement de ${machineTypes.value.length} type(s) de machine réussi`) + } + } catch (error) { + console.error('Erreur lors du chargement des types de machines:', error) + } finally { + loading.value = false + } + } + + const createMachineType = async (typeData) => { + loading.value = true + try { + const result = await post('/types/machines', typeData) + if (result.success) { + machineTypes.value.push(result.data) + showSuccess(`Type de machine "${typeData.name}" créé avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la création du type de machine:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const updateMachineType = async (id, typeData) => { + loading.value = true + try { + const result = await patch(`/types/machines/${id}`, typeData) + if (result.success) { + const index = machineTypes.value.findIndex(type => type.id === id) + if (index !== -1) { + machineTypes.value[index] = result.data + } + showSuccess(`Type de machine "${typeData.name}" mis à jour avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la mise à jour du type de machine:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const deleteMachineType = async (id) => { + loading.value = true + try { + const result = await del(`/types/machines/${id}`) + if (result.success) { + const deletedType = machineTypes.value.find(type => type.id === id) + machineTypes.value = machineTypes.value.filter(type => type.id !== id) + showSuccess(`Type de machine "${deletedType?.name || 'inconnu'}" supprimé avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la suppression du type de machine:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const getMachineTypeById = async (id) => { + // D'abord chercher dans le cache local + const localType = machineTypes.value.find(type => type.id === id) + if (localType) { + return { success: true, data: localType } + } + + // Si pas trouvé localement, récupérer depuis l'API + try { + const result = await get(`/types/machines/${id}`) + if (result.success) { + // Ajouter au cache local + machineTypes.value.push(result.data) + } + return result + } catch (error) { + console.error('Erreur lors de la récupération du type de machine:', error) + return { success: false, error: error.message } + } + } + + const getMachineTypes = () => machineTypes.value + const isLoading = () => loading.value + + return { + machineTypes, + loading, + loadMachineTypes, + createMachineType, + updateMachineType, + deleteMachineType, + getMachineTypeById, + getMachineTypes, + isLoading + } +} \ No newline at end of file diff --git a/app/composables/useMachines.js b/app/composables/useMachines.js new file mode 100644 index 0000000..adfda1e --- /dev/null +++ b/app/composables/useMachines.js @@ -0,0 +1,123 @@ +import { ref } from 'vue' +import { useToast } from './useToast' +import { useApi } from './useApi' + +const machines = ref([]) +const loading = ref(false) + +export function useMachines() { + const { showSuccess, showError, showInfo } = useToast() + const { get, post, patch, delete: del } = useApi() + + const loadMachines = async () => { + loading.value = true + try { + const result = await get('/machines') + if (result.success) { + machines.value = result.data + showInfo(`Chargement de ${machines.value.length} machine(s) réussi`) + } + } catch (error) { + console.error('Erreur lors du chargement des machines:', error) + } finally { + loading.value = false + } + } + + const createMachine = async (machineData) => { + loading.value = true + try { + const result = await post('/machines', machineData) + if (result.success) { + machines.value.push(result.data) + showSuccess(`Machine "${machineData.name}" créée avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la création de la machine:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const createMachineFromType = async (machineData, typeMachine) => { + // Créer la machine avec la structure héritée du type + const machineWithStructure = { + ...machineData, + typeMachineId: typeMachine.id, + // La structure sera automatiquement héritée du type + // Les composants et pièces seront créés automatiquement + } + + return await createMachine(machineWithStructure) + } + + const updateMachineData = async (id, machineData) => { + loading.value = true + try { + const result = await patch(`/machines/${id}`, machineData) + if (result.success) { + const index = machines.value.findIndex(machine => machine.id === id) + if (index !== -1) { + machines.value[index] = result.data + } + showSuccess(`Machine "${machineData.name}" mise à jour avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la mise à jour de la machine:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const deleteMachine = async (id) => { + loading.value = true + try { + const result = await del(`/machines/${id}`) + if (result.success) { + const deletedMachine = machines.value.find(machine => machine.id === id) + machines.value = machines.value.filter(machine => machine.id !== id) + showSuccess(`Machine "${deletedMachine?.name || 'inconnu'}" supprimée avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la suppression de la machine:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const getMachineById = (id) => { + return machines.value.find(machine => machine.id === id) + } + + const getMachinesBySite = (siteId) => { + return machines.value.filter(machine => machine.siteId === siteId) + } + + const getMachinesByType = (typeMachineId) => { + return machines.value.filter(machine => machine.typeMachineId === typeMachineId) + } + + const getMachines = () => machines.value + const isLoading = () => loading.value + + return { + machines, + loading, + loadMachines, + createMachine, + createMachineFromType, + updateMachine: updateMachineData, + deleteMachine, + getMachineById, + getMachinesBySite, + getMachinesByType, + getMachines, + isLoading + } +} \ No newline at end of file diff --git a/app/composables/usePieces.js b/app/composables/usePieces.js new file mode 100644 index 0000000..337ec21 --- /dev/null +++ b/app/composables/usePieces.js @@ -0,0 +1,134 @@ +import { ref } from 'vue' +import { useToast } from './useToast' +import { useApi } from './useApi' + +const pieces = ref([]) +const loading = ref(false) + +export function usePieces() { + const { showSuccess, showError, showInfo } = useToast() + const { get, post, patch, delete: del } = useApi() + + const loadPieces = async () => { + loading.value = true + try { + const result = await get('/pieces') + if (result.success) { + pieces.value = result.data + showInfo(`Chargement de ${pieces.value.length} pièce(s) réussi`) + } + } catch (error) { + console.error('Erreur lors du chargement des pièces:', error) + } finally { + loading.value = false + } + } + + const getPiecesByMachine = async (machineId) => { + loading.value = true + try { + const result = await get(`/pieces/machine/${machineId}`) + if (result.success) { + return { success: true, data: result.data } + } + return { success: false, error: result.error } + } catch (error) { + console.error('Erreur lors du chargement des pièces:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const getPiecesByComposant = async (composantId) => { + loading.value = true + try { + const result = await get(`/pieces/composant/${composantId}`) + if (result.success) { + return { success: true, data: result.data } + } + return { success: false, error: result.error } + } catch (error) { + console.error('Erreur lors du chargement des pièces:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const createPiece = async (pieceData) => { + loading.value = true + try { + const result = await post('/pieces', pieceData) + if (result.success) { + pieces.value.push(result.data) + showSuccess(`Pièce "${pieceData.name}" créée avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la création de la pièce:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const updatePieceData = async (id, pieceData) => { + loading.value = true + try { + const result = await patch(`/pieces/${id}`, pieceData) + if (result.success) { + const index = pieces.value.findIndex(piece => piece.id === id) + if (index !== -1) { + pieces.value[index] = result.data + } + showSuccess(`Pièce "${pieceData.name}" mise à jour avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la mise à jour de la pièce:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const deletePiece = async (id) => { + loading.value = true + try { + const result = await del(`/pieces/${id}`) + if (result.success) { + const deletedPiece = pieces.value.find(piece => piece.id === id) + pieces.value = pieces.value.filter(piece => piece.id !== id) + showSuccess(`Pièce "${deletedPiece?.name || 'inconnu'}" supprimée avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la suppression de la pièce:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const getPieceById = (id) => { + return pieces.value.find(piece => piece.id === id) + } + + const getPieces = () => pieces.value + const isLoading = () => loading.value + + return { + pieces, + loading, + loadPieces, + getPiecesByMachine, + getPiecesByComposant, + createPiece, + updatePiece: updatePieceData, + deletePiece, + getPieceById, + getPieces, + isLoading + } +} \ No newline at end of file diff --git a/app/composables/useSites.js b/app/composables/useSites.js new file mode 100644 index 0000000..eb7b829 --- /dev/null +++ b/app/composables/useSites.js @@ -0,0 +1,100 @@ +import { ref } from 'vue' +import { useToast } from './useToast' +import { useApi } from './useApi' + +const sites = ref([]) +const loading = ref(false) + +export function useSites() { + const { showSuccess, showInfo } = useToast() + const { get, post, patch, delete: del } = useApi() + + const loadSites = async () => { + loading.value = true + try { + const result = await get('/sites') + if (result.success) { + sites.value = result.data + showInfo(`Chargement de ${sites.value.length} site(s) réussi`) + } + } catch (error) { + console.error('Erreur lors du chargement des sites:', error) + } finally { + loading.value = false + } + } + + const createSite = async (siteData) => { + loading.value = true + try { + const result = await post('/sites', siteData) + if (result.success) { + sites.value.push(result.data) + showSuccess(`Site "${siteData.name}" créé avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la création du site:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const updateSite = async (id, siteData) => { + loading.value = true + try { + const result = await patch(`/sites/${id}`, siteData) + if (result.success) { + const index = sites.value.findIndex(site => site.id === id) + if (index !== -1) { + sites.value[index] = result.data + } + showSuccess(`Site "${siteData.name}" mis à jour avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la mise à jour du site:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const deleteSite = async (id) => { + loading.value = true + try { + const result = await del(`/sites/${id}`) + if (result.success) { + const deletedSite = sites.value.find(site => site.id === id) + sites.value = sites.value.filter(site => site.id !== id) + showSuccess(`Site "${deletedSite?.name || 'inconnu'}" supprimé avec succès`) + } + return result + } catch (error) { + console.error('Erreur lors de la suppression du site:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const getSiteById = (id) => { + return sites.value.find(site => site.id === id) + } + + const getSites = () => sites.value + const isLoading = () => loading.value + + return { + sites, + loading, + loadSites, + createSite, + updateSite, + deleteSite, + getSiteById, + getSites, + isLoading + } +} \ No newline at end of file diff --git a/app/composables/useToast.js b/app/composables/useToast.js new file mode 100644 index 0000000..4a08662 --- /dev/null +++ b/app/composables/useToast.js @@ -0,0 +1,66 @@ +import { ref } from 'vue' + +const toasts = ref([]) +let nextId = 1 + +export function useToast() { + const showToast = (message, type = 'info', duration = 5000) => { + const id = nextId++ + const toast = { + id, + message, + type, + visible: true + } + + toasts.value.push(toast) + + // Auto-remove after duration + setTimeout(() => { + removeToast(id) + }, duration) + + return id + } + + const showSuccess = (message, duration = 5000) => { + return showToast(message, 'success', duration) + } + + const showError = (message, duration = 7000) => { + return showToast(message, 'error', duration) + } + + const showWarning = (message, duration = 6000) => { + return showToast(message, 'warning', duration) + } + + const showInfo = (message, duration = 5000) => { + return showToast(message, 'info', duration) + } + + const removeToast = (id) => { + const index = toasts.value.findIndex(toast => toast.id === id) + if (index !== -1) { + toasts.value[index].visible = false + setTimeout(() => { + toasts.value.splice(index, 1) + }, 300) // Animation duration + } + } + + const clearAll = () => { + toasts.value = [] + } + + return { + toasts, + showToast, + showSuccess, + showError, + showWarning, + showInfo, + removeToast, + clearAll + } +} \ No newline at end of file From 36b7ce93ec31df4345b13030f95a5c5cf3f337be Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 30 Jul 2025 08:16:33 +0200 Subject: [PATCH 003/274] feat: Layout principal et composants de base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - app.vue : Layout principal avec navbar et navigation - ToastContainer.vue : Système de notifications toast - app.css : Styles globaux avec DaisyUI et accessibilité - Configuration des paramètres d'affichage (zoom, densité, contraste) - Navigation responsive avec menu déroulant - Bouton 'Nouveau' avec actions rapides --- app/app.vue | 138 ++++++++++++++ app/assets/app.css | 297 ++++++++++++++++++++++++++++++ app/components/ToastContainer.vue | 95 ++++++++++ 3 files changed, 530 insertions(+) create mode 100644 app/app.vue create mode 100644 app/assets/app.css create mode 100644 app/components/ToastContainer.vue diff --git a/app/app.vue b/app/app.vue new file mode 100644 index 0000000..40d80c5 --- /dev/null +++ b/app/app.vue @@ -0,0 +1,138 @@ + + + diff --git a/app/assets/app.css b/app/assets/app.css new file mode 100644 index 0000000..45b8d7f --- /dev/null +++ b/app/assets/app.css @@ -0,0 +1,297 @@ +@import "tailwindcss"; +@plugin "daisyui"; +@plugin "daisyui/theme" { + name: "mytheme"; + default: true; /* set as default */ + prefersdark: false; /* set as default dark mode (prefers-color-scheme:dark) */ + color-scheme: light; /* color of browser-provided UI */ + + --color-base-100: oklch(98% 0.02 240); + --color-base-200: oklch(95% 0.03 240); + --color-base-300: oklch(92% 0.04 240); + --color-base-content: oklch(20% 0.05 240); + --color-primary: oklch(55% 0.3 240); + --color-primary-content: oklch(98% 0.01 240); + --color-secondary: oklch(70% 0.25 200); + --color-secondary-content: oklch(98% 0.01 200); + --color-accent: oklch(65% 0.25 160); + --color-accent-content: oklch(98% 0.01 160); + --color-neutral: oklch(50% 0.05 240); + --color-neutral-content: oklch(98% 0.01 240); + --color-info: oklch(70% 0.2 220); + --color-info-content: oklch(98% 0.01 220); + --color-success: oklch(65% 0.25 140); + --color-success-content: oklch(98% 0.01 140); + --color-warning: oklch(80% 0.25 80); + --color-warning-content: oklch(20% 0.05 80); + --color-error: oklch(65% 0.3 30); + --color-error-content: oklch(98% 0.01 30); + + /* border radius */ + --radius-selector: 1rem; + --radius-field: 0.25rem; + --radius-box: 0.5rem; + + /* base sizes */ + --size-selector: 0.25rem; + --size-field: 0.25rem; + + /* border size */ + --border: 1px; + + /* effects */ + --depth: 1; + --noise: 0; +} + +/* Styles pour l'accessibilité et les paramètres d'affichage */ +:root { + --spacing-xs: 0.5rem; + --spacing-sm: 0.75rem; + --spacing-md: 1rem; + --spacing-lg: 1.5rem; + --spacing-xl: 2rem; +} + +/* Densité compacte */ +.density-compact { + --spacing-xs: 0.25rem; + --spacing-sm: 0.5rem; + --spacing-md: 0.75rem; + --spacing-lg: 1rem; + --spacing-xl: 1.25rem; +} + +/* Densité confortable (défaut) */ +.density-comfortable { + --spacing-xs: 0.5rem; + --spacing-sm: 0.75rem; + --spacing-md: 1rem; + --spacing-lg: 1.5rem; + --spacing-xl: 2rem; +} + +/* Densité espacée */ +.density-spacious { + --spacing-xs: 0.75rem; + --spacing-sm: 1rem; + --spacing-md: 1.5rem; + --spacing-lg: 2rem; + --spacing-xl: 3rem; +} + +/* Contraste élevé avec DaisyUI */ +.contrast-high .btn { + @apply border-2; +} + +.contrast-high .input { + @apply border-2; +} + +.contrast-high .select { + @apply border-2; +} + +.contrast-high .textarea { + @apply border-2; +} + +.contrast-high .modal-box { + @apply border-2 border-base-content; +} + +/* Amélioration de l'accessibilité */ +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} + +/* Focus visible pour l'accessibilité */ +*:focus-visible { + outline: 2px solid #3b82f6; + outline-offset: 2px; +} + +/* Styles pour les boutons de paramètres */ +.btn-circle { + transition: all 0.2s ease-in-out; +} + +.btn-circle:hover { + transform: scale(1.05); +} + +.btn-circle:active { + transform: scale(0.95); +} + +/* Animation pour le modal */ +.modal { + transition: opacity 0.3s ease-in-out; + font-size: 100% !important; /* Force la taille normale pour le modal */ + transform: none !important; /* Empêche les transformations */ + scale: 1 !important; /* Force l'échelle à 1 */ +} + +.modal.modal-open { + animation: modalFadeIn 0.3s ease-in-out; +} + +/* S'assurer que le contenu du modal garde une taille normale */ +.modal-box { + font-size: 100% !important; + transform: none !important; + scale: 1 !important; + width: auto !important; + max-width: 500px !important; +} + +.modal .form-control { + font-size: 100% !important; + transform: none !important; +} + +.modal .btn { + font-size: 100% !important; + transform: none !important; + padding: 0.5rem 1rem !important; + height: auto !important; + min-height: 2.5rem !important; +} + +.modal .input { + font-size: 100% !important; + transform: none !important; + height: auto !important; + min-height: 2.5rem !important; +} + +.modal .select { + font-size: 100% !important; + transform: none !important; + height: auto !important; + min-height: 2.5rem !important; +} + +.modal .textarea { + font-size: 100% !important; + transform: none !important; + min-height: 4rem !important; +} + +.modal .range { + font-size: 100% !important; + transform: none !important; + height: auto !important; + min-height: 1.5rem !important; +} + +.modal .label { + font-size: 100% !important; + transform: none !important; +} + +.modal .label-text { + font-size: 100% !important; + transform: none !important; +} + +.modal .label-text-alt { + font-size: 100% !important; + transform: none !important; +} + +.modal .checkbox { + font-size: 100% !important; + transform: none !important; + width: 1rem !important; + height: 1rem !important; +} + +.modal .text-xs { + font-size: 0.75rem !important; + transform: none !important; +} + +.modal .text-sm { + font-size: 0.875rem !important; + transform: none !important; +} + +.modal .text-lg { + font-size: 1.125rem !important; + transform: none !important; +} + +.modal .font-bold { + font-weight: 700 !important; + transform: none !important; +} + +.modal .font-medium { + font-weight: 500 !important; + transform: none !important; +} + +/* Empêcher les héritages de taille */ +.modal * { + font-size: inherit !important; + transform: none !important; + scale: 1 !important; +} + +@keyframes modalFadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +/* Styles pour les contrôles de zoom */ +.range { + transition: all 0.2s ease-in-out; +} + +.range::-webkit-slider-thumb { + transition: all 0.2s ease-in-out; +} + +.range::-webkit-slider-thumb:hover { + transform: scale(1.1); +} + +/* Amélioration de la lisibilité */ +.text-sm { + line-height: 1.5; +} + +.text-xs { + line-height: 1.4; +} + +/* Espacement adaptatif */ +.p-1 { padding: var(--spacing-xs); } +.p-2 { padding: var(--spacing-sm); } +.p-3 { padding: var(--spacing-md); } +.p-4 { padding: var(--spacing-lg); } +.p-5 { padding: var(--spacing-xl); } + +.m-1 { margin: var(--spacing-xs); } +.m-2 { margin: var(--spacing-sm); } +.m-3 { margin: var(--spacing-md); } +.m-4 { margin: var(--spacing-lg); } +.m-5 { margin: var(--spacing-xl); } + +.gap-1 { gap: var(--spacing-xs); } +.gap-2 { gap: var(--spacing-sm); } +.gap-3 { gap: var(--spacing-md); } +.gap-4 { gap: var(--spacing-lg); } +.gap-5 { gap: var(--spacing-xl); } \ No newline at end of file diff --git a/app/components/ToastContainer.vue b/app/components/ToastContainer.vue new file mode 100644 index 0000000..f604625 --- /dev/null +++ b/app/components/ToastContainer.vue @@ -0,0 +1,95 @@ + + + + + \ No newline at end of file From 9fb0353442fe13da848805e8335ab4b0aa10cdc0 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 30 Jul 2025 08:17:01 +0200 Subject: [PATCH 004/274] feat: Composants d'affichage des types de machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TypeComponentDisplay.vue : Affichage des composants existants avec hiérarchie - TypeInfoDisplay.vue : Informations générales du type de machine - TypeMachinePieceDisplay.vue : Affichage des pièces principales - Support de l'affichage en lecture seule des structures complexes - Gestion des champs personnalisés et sous-composants --- app/components/TypeComponentDisplay.vue | 157 +++++++++++++++++++++ app/components/TypeInfoDisplay.vue | 23 +++ app/components/TypeMachinePieceDisplay.vue | 50 +++++++ 3 files changed, 230 insertions(+) create mode 100644 app/components/TypeComponentDisplay.vue create mode 100644 app/components/TypeInfoDisplay.vue create mode 100644 app/components/TypeMachinePieceDisplay.vue diff --git a/app/components/TypeComponentDisplay.vue b/app/components/TypeComponentDisplay.vue new file mode 100644 index 0000000..32edaa1 --- /dev/null +++ b/app/components/TypeComponentDisplay.vue @@ -0,0 +1,157 @@ + + + \ No newline at end of file diff --git a/app/components/TypeInfoDisplay.vue b/app/components/TypeInfoDisplay.vue new file mode 100644 index 0000000..7ee594b --- /dev/null +++ b/app/components/TypeInfoDisplay.vue @@ -0,0 +1,23 @@ + + + \ No newline at end of file diff --git a/app/components/TypeMachinePieceDisplay.vue b/app/components/TypeMachinePieceDisplay.vue new file mode 100644 index 0000000..0445779 --- /dev/null +++ b/app/components/TypeMachinePieceDisplay.vue @@ -0,0 +1,50 @@ + + + \ No newline at end of file From ca44a78aad4b62440fb6d9d023012e268f1d39aa Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 30 Jul 2025 08:17:33 +0200 Subject: [PATCH 005/274] feat: Composants de formulaire pour les types de machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TypeComponentForm.vue : Formulaire pour ajouter des composants avec hiérarchie - TypeMachinePieceForm.vue : Formulaire pour ajouter des pièces principales - Support des champs personnalisés avec différents types (text, number, select, boolean, date) - Gestion des sous-composants et pièces imbriquées - Validation et gestion des options pour les champs de type SELECT --- app/components/TypeComponentForm.vue | 698 ++++++++++++++++++++++++ app/components/TypeMachinePieceForm.vue | 224 ++++++++ 2 files changed, 922 insertions(+) create mode 100644 app/components/TypeComponentForm.vue create mode 100644 app/components/TypeMachinePieceForm.vue diff --git a/app/components/TypeComponentForm.vue b/app/components/TypeComponentForm.vue new file mode 100644 index 0000000..f49eed2 --- /dev/null +++ b/app/components/TypeComponentForm.vue @@ -0,0 +1,698 @@ + + + \ No newline at end of file diff --git a/app/components/TypeMachinePieceForm.vue b/app/components/TypeMachinePieceForm.vue new file mode 100644 index 0000000..9eb837e --- /dev/null +++ b/app/components/TypeMachinePieceForm.vue @@ -0,0 +1,224 @@ + + + \ No newline at end of file From 23e2397de6694afdb307ae95cb60017cfaaa721a Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 30 Jul 2025 08:17:44 +0200 Subject: [PATCH 006/274] =?UTF-8?q?feat:=20Syst=C3=A8me=20de=20param=C3=A8?= =?UTF-8?q?tres=20d'affichage=20et=20accessibilit=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DisplaySettings.vue : Modal pour configurer l'affichage - Contrôles de zoom (80% à 150%) - Densité de l'interface (compacte, confortable, espacée) - Contraste (normal, élevé) - Persistance des paramètres via localStorage - Protection du modal contre les transformations de zoom --- app/components/DisplaySettings.vue | 203 +++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 app/components/DisplaySettings.vue diff --git a/app/components/DisplaySettings.vue b/app/components/DisplaySettings.vue new file mode 100644 index 0000000..4b075ca --- /dev/null +++ b/app/components/DisplaySettings.vue @@ -0,0 +1,203 @@ + + + + + \ No newline at end of file From 8965ee97a3397f1ad4e8669aef1f54227597dbcc Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 30 Jul 2025 08:18:11 +0200 Subject: [PATCH 007/274] feat: Pages principales de l'application MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - index.vue : Dashboard avec vue hiérarchique des sites et machines - machines.vue : Liste des machines avec filtres et actions - sites.vue : Gestion des sites industriels - types.vue : Gestion des types de machines - generator.vue : Générateur de types de machines - Système de navigation et gestion d'état --- app/pages/generator.vue | 1416 +++++++++++++++++++++++++++++++++++++++ app/pages/index.vue | 535 +++++++++++++++ app/pages/machines.vue | 379 +++++++++++ app/pages/sites.vue | 191 ++++++ app/pages/types.vue | 147 ++++ 5 files changed, 2668 insertions(+) create mode 100644 app/pages/generator.vue create mode 100644 app/pages/index.vue create mode 100644 app/pages/machines.vue create mode 100644 app/pages/sites.vue create mode 100644 app/pages/types.vue diff --git a/app/pages/generator.vue b/app/pages/generator.vue new file mode 100644 index 0000000..42912b5 --- /dev/null +++ b/app/pages/generator.vue @@ -0,0 +1,1416 @@ + + + \ No newline at end of file diff --git a/app/pages/index.vue b/app/pages/index.vue new file mode 100644 index 0000000..e0fb70d --- /dev/null +++ b/app/pages/index.vue @@ -0,0 +1,535 @@ + + + \ No newline at end of file diff --git a/app/pages/machines.vue b/app/pages/machines.vue new file mode 100644 index 0000000..40db60d --- /dev/null +++ b/app/pages/machines.vue @@ -0,0 +1,379 @@ + + + \ No newline at end of file diff --git a/app/pages/sites.vue b/app/pages/sites.vue new file mode 100644 index 0000000..d5b1443 --- /dev/null +++ b/app/pages/sites.vue @@ -0,0 +1,191 @@ + + + \ No newline at end of file diff --git a/app/pages/types.vue b/app/pages/types.vue new file mode 100644 index 0000000..5ffa991 --- /dev/null +++ b/app/pages/types.vue @@ -0,0 +1,147 @@ + + + \ No newline at end of file From d99768bc943f7ec99f00d0159d43d05b596674b3 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 30 Jul 2025 08:18:20 +0200 Subject: [PATCH 008/274] =?UTF-8?q?feat:=20Pages=20de=20d=C3=A9tail=20et?= =?UTF-8?q?=20=C3=A9dition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - type/[id].vue : Page de détail et édition des types de machines - machine/[id].vue : Page de détail et édition des machines - Support du mode édition avec paramètre URL ?edit=true - Gestion des composants hiérarchiques et champs personnalisés - Interface d'édition en temps réel avec sauvegarde --- app/pages/machine/[id].vue | 646 +++++++++++++++++++++++++++++++++++++ app/pages/type/[id].vue | 249 ++++++++++++++ 2 files changed, 895 insertions(+) create mode 100644 app/pages/machine/[id].vue create mode 100644 app/pages/type/[id].vue diff --git a/app/pages/machine/[id].vue b/app/pages/machine/[id].vue new file mode 100644 index 0000000..5bc8416 --- /dev/null +++ b/app/pages/machine/[id].vue @@ -0,0 +1,646 @@ + + + \ No newline at end of file diff --git a/app/pages/type/[id].vue b/app/pages/type/[id].vue new file mode 100644 index 0000000..a9657b2 --- /dev/null +++ b/app/pages/type/[id].vue @@ -0,0 +1,249 @@ + + + \ No newline at end of file From 36a44848d2c6a8bdd469a5089210b25e40834e5f Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 30 Jul 2025 08:18:30 +0200 Subject: [PATCH 009/274] feat: Composants d'affichage des machines et composants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ComponentHierarchy.vue : Affichage hiérarchique des composants - ComponentItem.vue : Affichage d'un composant individuel - CustomFieldsDisplay.vue : Affichage des champs personnalisés - PieceItem.vue : Affichage des pièces de machines - Support de l'affichage en lecture seule et édition - Gestion des relations parent-enfant entre composants --- app/components/ComponentHierarchy.vue | 30 +++ app/components/ComponentItem.vue | 268 +++++++++++++++++++++++++ app/components/CustomFieldsDisplay.vue | 135 +++++++++++++ app/components/PieceItem.vue | 247 +++++++++++++++++++++++ 4 files changed, 680 insertions(+) create mode 100644 app/components/ComponentHierarchy.vue create mode 100644 app/components/ComponentItem.vue create mode 100644 app/components/CustomFieldsDisplay.vue create mode 100644 app/components/PieceItem.vue diff --git a/app/components/ComponentHierarchy.vue b/app/components/ComponentHierarchy.vue new file mode 100644 index 0000000..445b5a3 --- /dev/null +++ b/app/components/ComponentHierarchy.vue @@ -0,0 +1,30 @@ + + + \ No newline at end of file diff --git a/app/components/ComponentItem.vue b/app/components/ComponentItem.vue new file mode 100644 index 0000000..19fa99d --- /dev/null +++ b/app/components/ComponentItem.vue @@ -0,0 +1,268 @@ + + + \ No newline at end of file diff --git a/app/components/CustomFieldsDisplay.vue b/app/components/CustomFieldsDisplay.vue new file mode 100644 index 0000000..276657a --- /dev/null +++ b/app/components/CustomFieldsDisplay.vue @@ -0,0 +1,135 @@ + + + \ No newline at end of file diff --git a/app/components/PieceItem.vue b/app/components/PieceItem.vue new file mode 100644 index 0000000..b4f4d1f --- /dev/null +++ b/app/components/PieceItem.vue @@ -0,0 +1,247 @@ + + + \ No newline at end of file From 74b78137a0f2beb9faa5245ffb54395e9c116c27 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 30 Jul 2025 09:59:05 +0200 Subject: [PATCH 010/274] =?UTF-8?q?feat:=20mise=20=C3=A0=20jour=20package.?= =?UTF-8?q?json=20frontend=20avec=20script=20start=20pour=20production?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5ea96c2..d3f9bc4 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", - "postinstall": "nuxt prepare" + "postinstall": "nuxt prepare", + "start": "nuxt start" }, "dependencies": { "@nuxtjs/tailwindcss": "^6.14.0", From c33a04b68ee0010509aacfedbf9ee57a2b3619ba Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 31 Jul 2025 17:42:28 +0200 Subject: [PATCH 011/274] =?UTF-8?q?feat:=20ajout=20du=20formulaire=20de=20?= =?UTF-8?q?modification=20compl=C3=A8te=20des=20types=20de=20machines?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Création du composant TypeEditForm.vue pour l'édition complète des types - Ajout de la page /type/edit/[id].vue pour l'édition complète - Ajout des boutons d'édition dans les pages types.vue et type/[id].vue - Gestion complète des champs personnalisés, pièces et composants - Interface intuitive avec ajout/suppression dynamique d'éléments --- app/components/TypeEditForm.vue | 859 ++++++++++++++++++++++++++++++++ app/pages/type/[id].vue | 14 +- app/pages/type/edit/[id].vue | 221 ++++++++ app/pages/types.vue | 6 + 4 files changed, 1097 insertions(+), 3 deletions(-) create mode 100644 app/components/TypeEditForm.vue create mode 100644 app/pages/type/edit/[id].vue diff --git a/app/components/TypeEditForm.vue b/app/components/TypeEditForm.vue new file mode 100644 index 0000000..d3492fb --- /dev/null +++ b/app/components/TypeEditForm.vue @@ -0,0 +1,859 @@ + + + \ No newline at end of file diff --git a/app/pages/type/[id].vue b/app/pages/type/[id].vue index a9657b2..348b479 100644 --- a/app/pages/type/[id].vue +++ b/app/pages/type/[id].vue @@ -26,9 +26,17 @@

Modifier : {{ type.name }}

- - Retour - +
+ + + + + Éditer complètement + + + Retour + +
diff --git a/app/pages/type/edit/[id].vue b/app/pages/type/edit/[id].vue new file mode 100644 index 0000000..5ef2bd9 --- /dev/null +++ b/app/pages/type/edit/[id].vue @@ -0,0 +1,221 @@ + + + \ No newline at end of file diff --git a/app/pages/types.vue b/app/pages/types.vue index 5ffa991..2cbd896 100644 --- a/app/pages/types.vue +++ b/app/pages/types.vue @@ -76,6 +76,12 @@ Supprimer Voir détails + + + + + Modifier + From 95da7c72db5c927a944e33219bc1da76170166fb Mon Sep 17 00:00:00 2001 From: Matthieu Date: Tue, 16 Sep 2025 17:14:42 +0200 Subject: [PATCH 012/274] =?UTF-8?q?feat:=20replis=20hi=C3=A9rarchie=20comp?= =?UTF-8?q?osants=20et=20sections=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/components/ComponentHierarchy.vue | 12 +- app/components/ComponentItem.vue | 295 ++--- app/components/TypeEditForm.vue | 104 +- app/pages/machine/[id].vue | 38 +- app/pages/types.vue | 6 - nuxt.config.ts | 5 +- package-lock.json | 1709 +------------------------ 7 files changed, 290 insertions(+), 1879 deletions(-) diff --git a/app/components/ComponentHierarchy.vue b/app/components/ComponentHierarchy.vue index 445b5a3..2570290 100644 --- a/app/components/ComponentHierarchy.vue +++ b/app/components/ComponentHierarchy.vue @@ -5,6 +5,8 @@ @@ -23,8 +25,16 @@ defineProps({ isEditMode: { type: Boolean, default: false + }, + collapseAll: { + type: Boolean, + default: true + }, + toggleToken: { + type: Number, + default: 0 } }) defineEmits(['update', 'edit-piece']) - \ No newline at end of file + diff --git a/app/components/ComponentItem.vue b/app/components/ComponentItem.vue index 19fa99d..566e715 100644 --- a/app/components/ComponentItem.vue +++ b/app/components/ComponentItem.vue @@ -1,125 +1,107 @@ \ No newline at end of file + diff --git a/app/components/TypeEditForm.vue b/app/components/TypeEditForm.vue index d3492fb..3dfd83d 100644 --- a/app/components/TypeEditForm.vue +++ b/app/components/TypeEditForm.vue @@ -62,7 +62,25 @@
-

Champs personnalisés du type

+
+ +

Champs personnalisés du type

+ {{ formData.customFields.length }} +
-
+
-
Champ personnalisé {{ fieldIndex + 1 }}
+
+ + + +
Champ personnalisé {{ fieldIndex + 1 }}
+
+

Pièces principales

+ {{ formData.machinePieces.length }} +
-
+
-
Pièce {{ pieceIndex + 1 }}
+
+ + + +
Pièce {{ pieceIndex + 1 }}
+
+

Composants

+ {{ formData.components.length }} +
-
+
-
Composant {{ componentIndex + 1 }}
+
+ + + +
Composant {{ componentIndex + 1 }}
+
@@ -322,6 +343,20 @@ const machineCustomFieldValues = reactive({}) const isEditMode = ref(false) const debug = ref(false) // Ajout de debug pour afficher les infos de debug +// Gestion du pliage global des composants +const componentsCollapsed = ref(true) +const collapseToggleToken = ref(0) + +const toggleAllComponents = () => { + componentsCollapsed.value = !componentsCollapsed.value + collapseToggleToken.value += 1 +} + +const collapseAllComponents = () => { + componentsCollapsed.value = true + collapseToggleToken.value += 1 +} + // Méthodes pour initialiser les champs const initMachineFields = () => { if (machine.value) { @@ -456,6 +491,7 @@ const loadMachineData = async () => { components.value = transformComponentCustomFields(componentsResult.data) console.log('Composants chargés:', components.value.length) console.log('Composants transformés:', components.value) + collapseAllComponents() // Debug: afficher la hiérarchie console.log('=== HIÉRARCHIE DES COMPOSANTS ===') @@ -643,4 +679,4 @@ onMounted(() => { console.log('Mode édition activé depuis l\'URL') } }) - \ No newline at end of file + diff --git a/app/pages/types.vue b/app/pages/types.vue index 2cbd896..5ffa991 100644 --- a/app/pages/types.vue +++ b/app/pages/types.vue @@ -76,12 +76,6 @@ Supprimer Voir détails - - - - - Modifier -
diff --git a/nuxt.config.ts b/nuxt.config.ts index 1b3f21a..92fde2d 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -2,6 +2,9 @@ import tailwindcss from "@tailwindcss/vite"; export default defineNuxtConfig({ compatibilityDate: '2025-07-15', devtools: { enabled: true }, + devServer: { + port: 3001, + }, vite: { plugins: [tailwindcss()], }, @@ -14,4 +17,4 @@ export default defineNuxtConfig({ experimental: { payloadExtraction: false } -}) \ No newline at end of file +}) diff --git a/package-lock.json b/package-lock.json index 77fe210..c9b2d3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,7 @@ "vue": "^3.5.17", "vue-router": "^4.5.1" }, - "devDependencies": { - "cypress": "^14.5.3" - } + "devDependencies": {} }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", @@ -518,90 +516,6 @@ "postcss-selector-parser": "^7.0.0" } }, - "node_modules/@cypress/request": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.9.tgz", - "integrity": "sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~4.0.4", - "http-signature": "~1.4.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "performance-now": "^2.1.0", - "qs": "6.14.0", - "safe-buffer": "^5.1.2", - "tough-cookie": "^5.0.0", - "tunnel-agent": "^0.6.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@cypress/request/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@cypress/request/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@cypress/request/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@cypress/xvfb": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", - "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.1.0", - "lodash.once": "^4.1.1" - } - }, - "node_modules/@cypress/xvfb/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/@dabh/diagnostics": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", @@ -4420,20 +4334,6 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "license": "MIT" }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", - "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/sizzle": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz", - "integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/triple-beam": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", @@ -5029,59 +4929,6 @@ "node": ">= 14" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", @@ -5146,27 +4993,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/archiver": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", @@ -5221,26 +5047,6 @@ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", "license": "MIT" }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, "node_modules/ast-kit": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.1.1.tgz", @@ -5282,16 +5088,6 @@ "url": "https://github.com/sponsors/sxzz" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", @@ -5304,13 +5100,6 @@ "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", "license": "MIT" }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -5357,23 +5146,6 @@ "postcss": "^8.1.0" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", - "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", - "dev": true, - "license": "MIT" - }, "node_modules/b4a": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", @@ -5413,16 +5185,6 @@ ], "license": "MIT" }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -5453,20 +5215,6 @@ "url": "https://github.com/sponsors/antfu" } }, - "node_modules/blob-util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", - "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true, - "license": "MIT" - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -5663,16 +5411,6 @@ "node": ">= 0.6" } }, - "node_modules/cachedir": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", - "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -5751,13 +5489,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5813,16 +5544,6 @@ "node": ">=8" } }, - "node_modules/check-more-types": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", - "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -5847,22 +5568,6 @@ "node": ">=18" } }, - "node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/citty": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", @@ -5872,152 +5577,6 @@ "consola": "^3.2.3" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-table3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", - "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "colors": "1.4.0" - } - }, - "node_modules/cli-table3/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-table3/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-table3/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/clipboardy": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-4.0.0.tgz", @@ -6200,24 +5759,6 @@ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "license": "MIT" }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/colorspace": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", @@ -6228,19 +5769,6 @@ "text-hex": "1.0.x" } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", @@ -6256,16 +5784,6 @@ "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", "license": "ISC" }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -6689,276 +6207,6 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, - "node_modules/cypress": { - "version": "14.5.3", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-14.5.3.tgz", - "integrity": "sha512-syLwKjDeMg77FRRx68bytLdlqHXDT4yBVh0/PPkcgesChYDjUZbwxLqMXuryYKzAyJsPsQHUDW1YU74/IYEUIA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@cypress/request": "^3.0.9", - "@cypress/xvfb": "^1.2.4", - "@types/sinonjs__fake-timers": "8.1.1", - "@types/sizzle": "^2.3.2", - "arch": "^2.2.0", - "blob-util": "^2.0.2", - "bluebird": "^3.7.2", - "buffer": "^5.7.1", - "cachedir": "^2.3.0", - "chalk": "^4.1.0", - "check-more-types": "^2.24.0", - "ci-info": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-table3": "0.6.1", - "commander": "^6.2.1", - "common-tags": "^1.8.0", - "dayjs": "^1.10.4", - "debug": "^4.3.4", - "enquirer": "^2.3.6", - "eventemitter2": "6.4.7", - "execa": "4.1.0", - "executable": "^4.1.1", - "extract-zip": "2.0.1", - "figures": "^3.2.0", - "fs-extra": "^9.1.0", - "getos": "^3.2.1", - "hasha": "5.2.2", - "is-installed-globally": "~0.4.0", - "lazy-ass": "^1.6.0", - "listr2": "^3.8.3", - "lodash": "^4.17.21", - "log-symbols": "^4.0.0", - "minimist": "^1.2.8", - "ospath": "^1.2.2", - "pretty-bytes": "^5.6.0", - "process": "^0.11.10", - "proxy-from-env": "1.0.0", - "request-progress": "^3.0.0", - "semver": "^7.7.1", - "supports-color": "^8.1.1", - "tmp": "~0.2.3", - "tree-kill": "1.2.2", - "untildify": "^4.0.0", - "yauzl": "^2.10.0" - }, - "bin": { - "cypress": "bin/cypress" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - } - }, - "node_modules/cypress/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/cypress/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/cypress/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/cypress/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cypress/node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/cypress/node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cypress/node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cypress/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cypress/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cypress/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cypress/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cypress/node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cypress/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/cypress/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cypress/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/daisyui": { "version": "5.0.48", "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.0.48.tgz", @@ -6968,19 +6216,6 @@ "url": "https://github.com/saadeghi/daisyui?sponsor=1" } }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -6990,13 +6225,6 @@ "node": ">= 12" } }, - "node_modules/dayjs": { - "version": "1.11.13", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", - "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", - "dev": true, - "license": "MIT" - }, "node_modules/db0": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/db0/-/db0-0.3.2.tgz", @@ -7115,16 +6343,6 @@ "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", "license": "MIT" }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -7444,17 +6662,6 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -7510,43 +6717,6 @@ "node": ">=10.13.0" } }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/enquirer/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/enquirer/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -7622,22 +6792,6 @@ "node": ">= 0.4" } }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/esbuild": { "version": "0.25.8", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", @@ -7807,13 +6961,6 @@ "node": ">=6" } }, - "node_modules/eventemitter2": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", - "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", - "dev": true, - "license": "MIT" - }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -7846,32 +6993,12 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.2.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/exsolve": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", "license": "MIT" }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true, - "license": "MIT" - }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -7907,16 +7034,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT" - }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", @@ -8009,32 +7126,6 @@ "node": "^12.20 || >= 14.13" } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -8116,56 +7207,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/form-data/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/form-data/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -8339,26 +7380,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/getos": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", - "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^3.2.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/giget": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", @@ -8442,32 +7463,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/global-dirs/node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/globby": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", @@ -8607,46 +7602,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasha/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasha/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -8765,21 +7720,6 @@ "node": ">= 0.12.0" } }, - "node_modules/http-signature": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", - "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2", - "sshpk": "^1.18.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -8865,16 +7805,6 @@ "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/index-to-position": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.1.0.tgz", @@ -9175,26 +8105,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-url": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", @@ -9270,13 +8180,6 @@ "node": ">=16" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true, - "license": "MIT" - }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", @@ -9307,13 +8210,6 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "license": "MIT" - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -9326,20 +8222,6 @@ "node": ">=6" } }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "license": "(AFL-2.1 OR BSD-3-Clause)" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -9364,22 +8246,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, "node_modules/junk": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", @@ -9645,16 +8511,6 @@ "shell-quote": "^1.8.1" } }, - "node_modules/lazy-ass": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", - "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "> 0.8" - } - }, "node_modules/lazystream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", @@ -9988,142 +8844,6 @@ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "license": "MIT" }, - "node_modules/listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "node_modules/listr2/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/listr2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/listr2/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/listr2/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/listr2/node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/listr2/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/listr2/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/listr2/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/local-pkg": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", @@ -10192,162 +8912,12 @@ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "license": "MIT" }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", "license": "MIT" }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/log-update/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-update/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-update/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/log-update/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-update/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/logform": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", @@ -11344,13 +9914,6 @@ "node": ">=8" } }, - "node_modules/ospath": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", - "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", - "dev": true, - "license": "MIT" - }, "node_modules/oxc-minify": { "version": "0.77.3", "resolved": "https://registry.npmjs.org/oxc-minify/-/oxc-minify-0.77.3.tgz", @@ -11698,13 +10261,6 @@ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", "license": "MIT" }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -12498,13 +11054,6 @@ "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", "license": "MIT" }, - "node_modules/proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", - "dev": true, - "license": "MIT" - }, "node_modules/pump": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", @@ -12797,16 +11346,6 @@ "node": "*" } }, - "node_modules/request-progress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", - "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "throttleit": "^1.0.0" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -12906,53 +11445,6 @@ "node": ">= 0.6" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -13073,16 +11565,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -13129,13 +11611,6 @@ "node": ">=10" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -13394,50 +11869,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, "node_modules/smob": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", @@ -13522,32 +11953,6 @@ "node": ">=0.10.0" } }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -13973,23 +12378,6 @@ "node": ">=0.8" } }, - "node_modules/throttleit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", - "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "license": "MIT" - }, "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", @@ -14018,26 +12406,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tldts": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tldts-core": "^6.1.86" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tldts-core": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", - "dev": true, - "license": "MIT" - }, "node_modules/tmp": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", @@ -14092,35 +12460,12 @@ "node": ">=6" } }, - "node_modules/tough-cookie": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tldts": "^6.1.32" - }, - "engines": { - "node": ">=16" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "license": "MIT", - "bin": { - "tree-kill": "cli.js" - } - }, "node_modules/triple-beam": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", @@ -14163,26 +12508,6 @@ "node": ">=0.6.x" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "license": "Unlicense" - }, "node_modules/type-fest": { "version": "4.41.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", @@ -14539,16 +12864,6 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/untun": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/untun/-/untun-0.1.3.tgz", @@ -14721,28 +13036,6 @@ "node": ">= 0.8" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "license": "MIT" - }, "node_modules/vite": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.6.tgz", From 4d2d35f3609b60fce77fd6c72ab1165f0aa48133 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 17 Sep 2025 08:16:27 +0200 Subject: [PATCH 013/274] feat: use runtime config for public env --- app/composables/useApi.js | 8 +++++--- nuxt.config.ts | 13 +++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/composables/useApi.js b/app/composables/useApi.js index 232c416..b5ec749 100644 --- a/app/composables/useApi.js +++ b/app/composables/useApi.js @@ -2,8 +2,10 @@ import { useToast } from './useToast' export function useApi() { const { showSuccess, showError, showInfo } = useToast() - const API_BASE_URL = process.env.NUXT_PUBLIC_API_BASE_URL || 'http://localhost:3000/api' - const API_TIMEOUT = parseInt(process.env.NUXT_PUBLIC_API_TIMEOUT || '30000') + const { public: publicConfig } = useRuntimeConfig() + const API_BASE_URL = publicConfig.apiBaseUrl || 'http://localhost:3000/api' + const parsedApiTimeout = Number(publicConfig.apiTimeout ?? 30000) + const API_TIMEOUT = Number.isNaN(parsedApiTimeout) ? 30000 : parsedApiTimeout const apiCall = async (endpoint, options = {}) => { const url = `${API_BASE_URL}${endpoint}` @@ -72,4 +74,4 @@ export function useApi() { patch, delete: del } -} \ No newline at end of file +} diff --git a/nuxt.config.ts b/nuxt.config.ts index 92fde2d..0dad093 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -5,6 +5,19 @@ export default defineNuxtConfig({ devServer: { port: 3001, }, + runtimeConfig: { + public: { + apiBaseUrl: process.env.NUXT_PUBLIC_API_BASE_URL || 'http://localhost:3000/api', + appUrl: process.env.NUXT_PUBLIC_APP_URL || 'http://localhost:3001', + appName: process.env.NUXT_PUBLIC_APP_NAME || 'Inventory Management System', + apiTimeout: process.env.NUXT_PUBLIC_API_TIMEOUT || '30000', + requestTimeout: process.env.NUXT_PUBLIC_REQUEST_TIMEOUT || '10000', + enableDebug: process.env.NUXT_PUBLIC_ENABLE_DEBUG || 'true', + enableAnalytics: process.env.NUXT_PUBLIC_ENABLE_ANALYTICS || 'false', + csrfToken: process.env.NUXT_PUBLIC_CSRF_TOKEN || '', + logLevel: process.env.NUXT_PUBLIC_LOG_LEVEL || 'debug', + }, + }, vite: { plugins: [tailwindcss()], }, From d605f2418f9b0bebbfca5ffac04620ff46a9e029 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 17 Sep 2025 08:18:28 +0200 Subject: [PATCH 014/274] feat: refactor type management screens --- app/components/TypeComponentDisplay.vue | 609 ++++++++-- app/components/TypeComponentForm.vue | 1218 +++++++++++++++----- app/components/TypeEditForm.vue | 505 +++++++- app/components/TypeMachinePieceDisplay.vue | 103 +- app/components/TypeMachinePieceForm.vue | 181 ++- app/pages/generator.vue | 175 ++- app/pages/type/[id].vue | 194 +--- 7 files changed, 2328 insertions(+), 657 deletions(-) diff --git a/app/components/TypeComponentDisplay.vue b/app/components/TypeComponentDisplay.vue index 32edaa1..5fbcfbb 100644 --- a/app/components/TypeComponentDisplay.vue +++ b/app/components/TypeComponentDisplay.vue @@ -2,156 +2,521 @@
+

{{ component.name }}

+ (Ref: {{ component.reference }})
-
- {{ component.reference ? `Ref: ${component.reference}` : '' }} +
+ {{ compactInfo }}
- -
-
- Prestataire: {{ component.prestataire }} -
-
- Emplacement: {{ component.emplacement }} -
-
- Prix: {{ component.prix }}€ -
-
- - -
-
Champs personnalisés:
-
-
-
{{ field.name }}
-
{{ field.type }}
-
Obligatoire
-
Défaut: {{ field.defaultValue }}
+
\ No newline at end of file + +const expanded = ref(true) +const expandedSections = reactive({ + customFields: true, + pieces: true, + subComponents: true +}) + +const expandedPieces = ref([]) +const expandedPieceCustomFields = ref([]) +const expandedSubComponents = ref([]) +const expandedSubComponentCustomFields = ref([]) +const expandedSubComponentPieces = ref([]) +const expandedSubComponentPieceCustomFields = reactive({}) + +const compactInfo = computed(() => { + const infos = [] + if (props.component?.prestataire) { + infos.push(props.component.prestataire) + } + if (props.component?.emplacement) { + infos.push(props.component.emplacement) + } + return infos.join(' • ') +}) + +const quickPieceSummary = (piece) => { + const infos = [] + if (piece?.prestataire) infos.push(piece.prestataire) + if (piece?.emplacement) infos.push(piece.emplacement) + return infos.join(' • ') +} + +const quickSubSummary = (subComponent) => { + const infos = [] + if (subComponent?.prestataire) infos.push(subComponent.prestataire) + if (subComponent?.emplacement) infos.push(subComponent.emplacement) + return infos.join(' • ') +} + +const applyGlobalExpansion = (expand) => { + expanded.value = expand + expandedSections.customFields = expand && (props.component?.customFields || []).length > 0 + expandedSections.pieces = expand && (props.component?.pieces || []).length > 0 + expandedSections.subComponents = expand && (props.component?.subComponents || []).length > 0 + + expandedPieces.value = (props.component?.pieces || []).map(() => expand) + expandedPieceCustomFields.value = (props.component?.pieces || []).map(() => expand) + + expandedSubComponents.value = (props.component?.subComponents || []).map(() => expand) + expandedSubComponentCustomFields.value = (props.component?.subComponents || []).map(() => expand) + expandedSubComponentPieces.value = (props.component?.subComponents || []).map(() => expand) + + Object.keys(expandedSubComponentPieceCustomFields).forEach((key) => delete expandedSubComponentPieceCustomFields[key]) + ;(props.component?.subComponents || []).forEach((subComponent, subIndex) => { + expandedSubComponentPieceCustomFields[subIndex] = (subComponent.pieces || []).map(() => ({ + expanded: expand, + customFields: expand + })) + }) +} + +const initializeExpansionState = () => { + const initialExpand = props.globalExpandState ? props.globalExpandState.expanded : true + applyGlobalExpansion(initialExpand) +} + +watch(() => props.component, () => { + initializeExpansionState() +}, { deep: true }) + +onMounted(() => { + initializeExpansionState() +}) + +const toggleComponent = () => { + expanded.value = !expanded.value +} + +const toggleSection = (section) => { + expandedSections[section] = !expandedSections[section] +} + +const isPieceExpanded = (index) => expandedPieces.value[index] +const togglePieceDetails = (index) => { + expandedPieces.value[index] = !expandedPieces.value[index] +} + +const isPieceCustomFieldSectionExpanded = (index) => expandedPieceCustomFields.value[index] +const togglePieceCustomFields = (index) => { + expandedPieceCustomFields.value[index] = !expandedPieceCustomFields.value[index] +} + +const isSubComponentExpanded = (index) => expandedSubComponents.value[index] +const toggleSubComponentDetails = (index) => { + expandedSubComponents.value[index] = !expandedSubComponents.value[index] +} + +const isSubComponentCustomFieldSectionExpanded = (index) => expandedSubComponentCustomFields.value[index] +const toggleSubComponentCustomFieldSection = (index) => { + expandedSubComponentCustomFields.value[index] = !expandedSubComponentCustomFields.value[index] +} + +const isSubComponentPieceSectionExpanded = (index) => expandedSubComponentPieces.value[index] +const toggleSubComponentPieceSection = (index) => { + expandedSubComponentPieces.value[index] = !expandedSubComponentPieces.value[index] +} + +const isSubPieceExpanded = (subIndex, pieceIndex) => expandedSubComponentPieceCustomFields[subIndex]?.[pieceIndex]?.expanded ?? false + +const ensureSubPieceEntry = (subIndex, pieceIndex) => { + if (!expandedSubComponentPieceCustomFields[subIndex]) { + expandedSubComponentPieceCustomFields[subIndex] = [] + } + if (!expandedSubComponentPieceCustomFields[subIndex][pieceIndex]) { + expandedSubComponentPieceCustomFields[subIndex][pieceIndex] = { expanded: false, customFields: false } + } +} + +const toggleSubPieceDetails = (subIndex, pieceIndex) => { + ensureSubPieceEntry(subIndex, pieceIndex) + expandedSubComponentPieceCustomFields[subIndex][pieceIndex].expanded = !expandedSubComponentPieceCustomFields[subIndex][pieceIndex].expanded +} + +const isSubPieceCustomFieldSectionExpanded = (subIndex, pieceIndex) => expandedSubComponentPieceCustomFields[subIndex]?.[pieceIndex]?.customFields ?? false +const toggleSubPieceCustomFields = (subIndex, pieceIndex) => { + ensureSubPieceEntry(subIndex, pieceIndex) + expandedSubComponentPieceCustomFields[subIndex][pieceIndex].customFields = !expandedSubComponentPieceCustomFields[subIndex][pieceIndex].customFields +} + +watch(() => props.globalExpandState?.id, () => { + if (props.globalExpandState) { + applyGlobalExpansion(props.globalExpandState.expanded) + } +}) + diff --git a/app/components/TypeComponentForm.vue b/app/components/TypeComponentForm.vue index f49eed2..8368f18 100644 --- a/app/components/TypeComponentForm.vue +++ b/app/components/TypeComponentForm.vue @@ -1,8 +1,59 @@ @@ -133,30 +314,82 @@ const { sites, loading, loadSites, createSite, updateSite, deleteSite } = useSit // Data const showAddSiteModal = ref(false) +const showEditSiteModal = ref(false) + +const siteBeingEdited = ref(null) const newSite = reactive({ name: '', - description: '' + contactName: '', + contactPhone: '', + contactAddress: '', + contactPostalCode: '', + contactCity: '' +}) + +const editSiteForm = reactive({ + name: '', + contactName: '', + contactPhone: '', + contactAddress: '', + contactPostalCode: '', + contactCity: '' }) // Methods const handleCreateSite = async () => { const result = await createSite({ name: newSite.name, - description: newSite.description + contactName: newSite.contactName, + contactPhone: newSite.contactPhone, + contactAddress: newSite.contactAddress, + contactPostalCode: newSite.contactPostalCode, + contactCity: newSite.contactCity }) if (result.success) { // Reset form newSite.name = '' - newSite.description = '' + newSite.contactName = '' + newSite.contactPhone = '' + newSite.contactAddress = '' + newSite.contactPostalCode = '' + newSite.contactCity = '' showAddSiteModal.value = false } } const editSite = (site) => { - // TODO: Ouvrir le modal d'édition - console.log('Modifier le site:', site) + siteBeingEdited.value = site + editSiteForm.name = site.name || '' + editSiteForm.contactName = site.contactName || '' + editSiteForm.contactPhone = site.contactPhone || '' + editSiteForm.contactAddress = site.contactAddress || '' + editSiteForm.contactPostalCode = site.contactPostalCode || '' + editSiteForm.contactCity = site.contactCity || '' + showEditSiteModal.value = true +} + +const handleUpdateSite = async () => { + if (!siteBeingEdited.value) return + + const result = await updateSite(siteBeingEdited.value.id, { + name: editSiteForm.name, + contactName: editSiteForm.contactName, + contactPhone: editSiteForm.contactPhone, + contactAddress: editSiteForm.contactAddress, + contactPostalCode: editSiteForm.contactPostalCode, + contactCity: editSiteForm.contactCity + }) + + if (result.success) { + closeEditModal() + } +} + +const closeEditModal = () => { + showEditSiteModal.value = false + siteBeingEdited.value = null } const confirmDeleteSite = async (site) => { @@ -188,4 +421,4 @@ onMounted(async () => { await navigateTo('/sites', { replace: true }) } }) - \ No newline at end of file + From 0fbf77ab4373629557ac7f4acb90ede77568d7bc Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 17 Sep 2025 11:40:50 +0200 Subject: [PATCH 017/274] feat(site): allow document management --- app/components/DocumentUpload.vue | 151 +++++++++++++++++++++++++ app/composables/useDocuments.js | 126 +++++++++++++++++++++ app/pages/documents.vue | 180 ++++++++++++++++++++++++++++++ app/pages/sites.vue | 174 ++++++++++++++++++++++++++++- 4 files changed, 627 insertions(+), 4 deletions(-) create mode 100644 app/components/DocumentUpload.vue create mode 100644 app/composables/useDocuments.js create mode 100644 app/pages/documents.vue diff --git a/app/components/DocumentUpload.vue b/app/components/DocumentUpload.vue new file mode 100644 index 0000000..e459002 --- /dev/null +++ b/app/components/DocumentUpload.vue @@ -0,0 +1,151 @@ + + + diff --git a/app/composables/useDocuments.js b/app/composables/useDocuments.js new file mode 100644 index 0000000..8cbe590 --- /dev/null +++ b/app/composables/useDocuments.js @@ -0,0 +1,126 @@ +import { ref } from 'vue' +import { useApi } from './useApi' +import { useToast } from './useToast' + +const documents = ref([]) +const loading = ref(false) + +const fileToBase64 = (file) => + new Promise((resolve, reject) => { + const reader = new FileReader() + reader.onload = () => resolve(reader.result) + reader.onerror = () => reject(new Error(`Lecture du fichier ${file.name} impossible`)) + reader.readAsDataURL(file) + }) + +export function useDocuments() { + const { get, post, delete: del } = useApi() + const { showError, showSuccess } = useToast() + + const loadDocuments = async () => { + loading.value = true + try { + const result = await get('/documents') + if (result.success) { + documents.value = result.data + } + return result + } catch (error) { + console.error('Erreur lors du chargement des documents:', error) + showError("Impossible de charger les documents") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const loadDocumentsBySite = async (siteId) => { + if (!siteId) return { success: false, error: 'Aucun site sélectionné' } + loading.value = true + try { + const result = await get(`/documents/site/${siteId}`) + if (result.success) { + documents.value = result.data + } + return result + } catch (error) { + console.error('Erreur lors du chargement des documents du site:', error) + showError("Impossible de charger les documents du site") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const uploadDocuments = async ({ files = [], context = {} }) => { + if (!files.length) return { success: false, error: 'Aucun fichier sélectionné' } + + loading.value = true + const created = [] + + try { + for (const file of files) { + const dataUrl = await fileToBase64(file) + + const payload = { + name: file.name, + filename: file.name, + mimeType: file.type || 'application/octet-stream', + size: file.size, + path: dataUrl, + ...context, + } + + const result = await post('/documents', payload) + if (result.success) { + created.push(result.data) + showSuccess(`Document "${file.name}" ajouté`) + } else if (result.error) { + showError(`Erreur sur ${file.name} : ${result.error}`) + } + } + + if (created.length) { + documents.value = [...created, ...documents.value] + return { success: true, data: created } + } + + return { success: false, error: 'Aucun document ajouté' } + } catch (error) { + console.error('Erreur lors de l\'upload des documents:', error) + showError("Échec de l'ajout des documents") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const deleteDocument = async (id) => { + if (!id) return { success: false, error: 'Identifiant manquant' } + + loading.value = true + try { + const result = await del(`/documents/${id}`) + if (result.success) { + documents.value = documents.value.filter(doc => doc.id !== id) + showSuccess('Document supprimé') + } + return result + } catch (error) { + console.error('Erreur lors de la suppression du document:', error) + showError("Impossible de supprimer le document") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + return { + documents, + loading, + loadDocuments, + loadDocumentsBySite, + uploadDocuments, + deleteDocument, + } +} diff --git a/app/pages/documents.vue b/app/pages/documents.vue new file mode 100644 index 0000000..0c0cca3 --- /dev/null +++ b/app/pages/documents.vue @@ -0,0 +1,180 @@ + + + diff --git a/app/pages/sites.vue b/app/pages/sites.vue index b12bda8..522a4cd 100644 --- a/app/pages/sites.vue +++ b/app/pages/sites.vue @@ -291,11 +291,60 @@
+
+
+
+

Documents liés

+

Ajoutez des documents (PDF, images...) relatifs à ce site.

+
+ + {{ selectedFiles.length }} fichier{{ selectedFiles.length > 1 ? 's' : '' }} prêt{{ selectedFiles.length > 1 ? 's' : '' }} à être ajouté + +
+ + + +
+
Documents existants
+
+
+
+
{{ document.name }}
+
+ {{ document.mimeType || 'Inconnu' }} • {{ formatSize(document.size) }} +
+
+
+ + +
+
+
+
+
+ @@ -306,11 +355,14 @@ diff --git a/app/components/DocumentUpload.vue b/app/components/DocumentUpload.vue index e459002..9e1bff9 100644 --- a/app/components/DocumentUpload.vue +++ b/app/components/DocumentUpload.vue @@ -34,9 +34,12 @@
  • -
    - {{ file.name }} - {{ formatSize(file.size) }} • {{ file.type || 'Type inconnu' }} +
    + {{ getIcon(file).icon }} +
    + {{ file.name }} + {{ formatSize(file.size) }} • {{ file.type || 'Type inconnu' }} +
+ +
+
+
Documents
+ + {{ selectedFiles.length }} fichier{{ selectedFiles.length > 1 ? 's' : '' }} sélectionné{{ selectedFiles.length > 1 ? 's' : '' }} + +
+ +

Chargement des documents...

+ + + +
+
+
+ + {{ documentIcon(document).icon }} + +
+
{{ document.name }}
+
+ {{ document.mimeType || 'Inconnu' }} • {{ formatSize(document.size) }} +
+
+
+
+ + +
+
+
+

Aucun document lié à cette pièce.

+
\ No newline at end of file + diff --git a/app/composables/useDocuments.js b/app/composables/useDocuments.js index 8cbe590..4cf8b6b 100644 --- a/app/composables/useDocuments.js +++ b/app/composables/useDocuments.js @@ -17,16 +17,23 @@ export function useDocuments() { const { get, post, delete: del } = useApi() const { showError, showSuccess } = useToast() - const loadDocuments = async () => { + const loadFromEndpoint = async (endpoint, { updateStore = false } = {}) => { loading.value = true try { - const result = await get('/documents') + const result = await get(endpoint) if (result.success) { - documents.value = result.data + const data = result.data || [] + if (updateStore) { + documents.value = data + } + return { success: true, data } + } + if (result.error) { + showError(result.error) } return result } catch (error) { - console.error('Erreur lors du chargement des documents:', error) + console.error(`Erreur lors du chargement des documents (${endpoint}):`, error) showError("Impossible de charger les documents") return { success: false, error: error.message } } finally { @@ -34,25 +41,31 @@ export function useDocuments() { } } - const loadDocumentsBySite = async (siteId) => { - if (!siteId) return { success: false, error: 'Aucun site sélectionné' } - loading.value = true - try { - const result = await get(`/documents/site/${siteId}`) - if (result.success) { - documents.value = result.data - } - return result - } catch (error) { - console.error('Erreur lors du chargement des documents du site:', error) - showError("Impossible de charger les documents du site") - return { success: false, error: error.message } - } finally { - loading.value = false - } + const loadDocuments = async (options = {}) => { + return loadFromEndpoint('/documents', { updateStore: options.updateStore ?? true }) } - const uploadDocuments = async ({ files = [], context = {} }) => { + const loadDocumentsBySite = async (siteId, options = {}) => { + if (!siteId) return { success: false, error: 'Aucun site sélectionné' } + return loadFromEndpoint(`/documents/site/${siteId}`, { updateStore: options.updateStore ?? false }) + } + + const loadDocumentsByMachine = async (machineId, options = {}) => { + if (!machineId) return { success: false, error: 'Aucune machine sélectionnée' } + return loadFromEndpoint(`/documents/machine/${machineId}`, { updateStore: options.updateStore ?? false }) + } + + const loadDocumentsByComponent = async (componentId, options = {}) => { + if (!componentId) return { success: false, error: 'Aucun composant sélectionné' } + return loadFromEndpoint(`/documents/composant/${componentId}`, { updateStore: options.updateStore ?? false }) + } + + const loadDocumentsByPiece = async (pieceId, options = {}) => { + if (!pieceId) return { success: false, error: 'Aucune pièce sélectionnée' } + return loadFromEndpoint(`/documents/piece/${pieceId}`, { updateStore: options.updateStore ?? false }) + } + + const uploadDocuments = async ({ files = [], context = {} }, { updateStore = false } = {}) => { if (!files.length) return { success: false, error: 'Aucun fichier sélectionné' } loading.value = true @@ -81,7 +94,9 @@ export function useDocuments() { } if (created.length) { - documents.value = [...created, ...documents.value] + if (updateStore) { + documents.value = [...created, ...documents.value] + } return { success: true, data: created } } @@ -95,14 +110,16 @@ export function useDocuments() { } } - const deleteDocument = async (id) => { + const deleteDocument = async (id, { updateStore = false } = {}) => { if (!id) return { success: false, error: 'Identifiant manquant' } loading.value = true try { const result = await del(`/documents/${id}`) if (result.success) { - documents.value = documents.value.filter(doc => doc.id !== id) + if (updateStore) { + documents.value = documents.value.filter(doc => doc.id !== id) + } showSuccess('Document supprimé') } return result @@ -120,6 +137,9 @@ export function useDocuments() { loading, loadDocuments, loadDocumentsBySite, + loadDocumentsByMachine, + loadDocumentsByComponent, + loadDocumentsByPiece, uploadDocuments, deleteDocument, } diff --git a/app/pages/documents.vue b/app/pages/documents.vue index 0c0cca3..f98dce2 100644 --- a/app/pages/documents.vue +++ b/app/pages/documents.vue @@ -70,8 +70,15 @@ -
{{ document.name }}
-
{{ document.filename }}
+
+ + {{ documentIcon(document).icon }} + +
+
{{ document.name }}
+
{{ document.filename }}
+
+
{{ document.mimeType || 'Inconnu' }} {{ formatSize(document.size) }} @@ -104,6 +111,7 @@ +watch( + constructeurs, + (list) => { + options.value = [...list] + }, + { immediate: true } +) diff --git a/app/components/DocumentUpload.vue b/app/components/DocumentUpload.vue index 9e1bff9..e14809e 100644 --- a/app/components/DocumentUpload.vue +++ b/app/components/DocumentUpload.vue @@ -78,7 +78,7 @@ const props = defineProps({ }, maxFileSizeMb: { type: Number, - default: 100, + default: 200, }, }) diff --git a/app/components/PieceItem.vue b/app/components/PieceItem.vue index 2f56a75..10f5ee6 100644 --- a/app/components/PieceItem.vue +++ b/app/components/PieceItem.vue @@ -34,15 +34,16 @@
Constructeur: - + {{ piece.constructeur?.name || 'Non défini' }} + + {{ [piece.constructeur?.email, piece.constructeur?.phone].filter(Boolean).join(' • ') }} + + + - {{ pieceData.constructeur || 'Non défini' }}
Emplacement: @@ -229,6 +230,7 @@ import { useToast } from '~/composables/useToast' import { useDocuments } from '~/composables/useDocuments' import { getFileIcon } from '~/utils/fileIcons' import DocumentUpload from '~/components/DocumentUpload.vue' +import ConstructeurSelect from './ConstructeurSelect.vue' const props = defineProps({ piece: { @@ -247,7 +249,6 @@ const emit = defineEmits(['update', 'edit', 'custom-field-update']) const pieceData = reactive({ name: props.piece.name || '', reference: props.piece.reference || '', - constructeur: props.piece.constructeur || '', emplacement: props.piece.emplacement || '', prix: props.piece.prix || '' }) @@ -336,6 +337,17 @@ watch( } ) +watch( + () => props.piece.constructeurId, + (newVal, oldVal) => { + if (!props.isEditMode) return + if (oldVal === undefined) return + if (newVal !== oldVal) { + updatePiece() + } + } +) + // Méthodes pour gérer les champs personnalisés const setCustomFieldValue = (fieldValueId, value) => { const fieldValue = props.piece.customFieldValues?.find(fv => fv.id === fieldValueId) @@ -349,7 +361,8 @@ const updatePiece = () => { emit('update', { ...props.piece, ...pieceData, - prix: prixValue && prixValue !== '' ? parseFloat(prixValue) : null + prix: prixValue && prixValue !== '' ? parseFloat(prixValue) : null, + constructeurId: props.piece.constructeurId || null, }) } @@ -377,7 +390,6 @@ onMounted(() => { // Initialiser les données avec les props pieceData.name = props.piece.name || '' pieceData.reference = props.piece.reference || '' - pieceData.constructeur = props.piece.constructeur || '' pieceData.emplacement = props.piece.emplacement || '' pieceData.prix = props.piece.prix || '' diff --git a/app/composables/useComposants.js b/app/composables/useComposants.js index 54e3b26..88f7991 100644 --- a/app/composables/useComposants.js +++ b/app/composables/useComposants.js @@ -78,11 +78,12 @@ export function useComposants() { try { const result = await patch(`/composants/${id}`, composantData) if (result.success) { + const updated = result.data const index = composants.value.findIndex(comp => comp.id === id) if (index !== -1) { - composants.value[index] = result.data + composants.value[index] = updated } - showSuccess(`Composant "${composantData.name}" mis à jour avec succès`) + showSuccess(`Composant "${updated?.name || composantData.name || ''}" mis à jour avec succès`) } return result } catch (error) { @@ -131,4 +132,4 @@ export function useComposants() { getComposants, isLoading } -} \ No newline at end of file +} diff --git a/app/composables/useConstructeurs.js b/app/composables/useConstructeurs.js new file mode 100644 index 0000000..fb11f6a --- /dev/null +++ b/app/composables/useConstructeurs.js @@ -0,0 +1,108 @@ +import { ref } from 'vue' +import { useApi } from './useApi' +import { useToast } from './useToast' + +const constructeurs = ref([]) +const loading = ref(false) + +export function useConstructeurs() { + const { get, post, patch, delete: del } = useApi() + const { showSuccess, showError } = useToast() + + const loadConstructeurs = async (search = '') => { + loading.value = true + try { + const query = search ? `?search=${encodeURIComponent(search)}` : '' + const result = await get(`/constructeurs${query}`) + if (result.success) { + constructeurs.value = result.data + } + return result + } catch (error) { + console.error('Erreur lors du chargement des constructeurs:', error) + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const searchConstructeurs = async (search = '') => { + return loadConstructeurs(search) + } + + const createConstructeur = async (data) => { + loading.value = true + try { + const result = await post('/constructeurs', data) + if (result.success) { + constructeurs.value = [result.data, ...constructeurs.value] + showSuccess(`Constructeur "${result.data.name}" créé`) + } else if (result.error) { + showError(result.error) + } + return result + } catch (error) { + console.error('Erreur lors de la création du constructeur:', error) + showError("Impossible de créer le constructeur") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const updateConstructeur = async (id, data) => { + loading.value = true + try { + const result = await patch(`/constructeurs/${id}`, data) + if (result.success) { + const index = constructeurs.value.findIndex(item => item.id === id) + if (index !== -1) { + constructeurs.value[index] = result.data + } + showSuccess(`Constructeur "${result.data.name}" mis à jour`) + } else if (result.error) { + showError(result.error) + } + return result + } catch (error) { + console.error('Erreur lors de la mise à jour du constructeur:', error) + showError("Impossible de mettre à jour le constructeur") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const deleteConstructeur = async (id) => { + loading.value = true + try { + const result = await del(`/constructeurs/${id}`) + if (result.success) { + constructeurs.value = constructeurs.value.filter(item => item.id !== id) + showSuccess('Constructeur supprimé') + } else if (result.error) { + showError(result.error) + } + return result + } catch (error) { + console.error('Erreur lors de la suppression du constructeur:', error) + showError("Impossible de supprimer le constructeur") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const getConstructeurById = (id) => constructeurs.value.find(item => item.id === id) + + return { + constructeurs, + loading, + loadConstructeurs, + searchConstructeurs, + createConstructeur, + updateConstructeur, + deleteConstructeur, + getConstructeurById, + } +} diff --git a/app/composables/useMachines.js b/app/composables/useMachines.js index adfda1e..eb50e76 100644 --- a/app/composables/useMachines.js +++ b/app/composables/useMachines.js @@ -62,7 +62,7 @@ export function useMachines() { if (index !== -1) { machines.value[index] = result.data } - showSuccess(`Machine "${machineData.name}" mise à jour avec succès`) + showSuccess(`Machine "${result.data?.name || machineData.name || ''}" mise à jour avec succès`) } return result } catch (error) { @@ -120,4 +120,4 @@ export function useMachines() { getMachines, isLoading } -} \ No newline at end of file +} diff --git a/app/composables/usePieces.js b/app/composables/usePieces.js index 337ec21..581a795 100644 --- a/app/composables/usePieces.js +++ b/app/composables/usePieces.js @@ -78,11 +78,12 @@ export function usePieces() { try { const result = await patch(`/pieces/${id}`, pieceData) if (result.success) { + const updated = result.data const index = pieces.value.findIndex(piece => piece.id === id) if (index !== -1) { - pieces.value[index] = result.data + pieces.value[index] = updated } - showSuccess(`Pièce "${pieceData.name}" mise à jour avec succès`) + showSuccess(`Pièce "${updated?.name || pieceData.name || ''}" mise à jour avec succès`) } return result } catch (error) { @@ -131,4 +132,4 @@ export function usePieces() { getPieces, isLoading } -} \ No newline at end of file +} diff --git a/app/pages/constructeurs.vue b/app/pages/constructeurs.vue new file mode 100644 index 0000000..dc96978 --- /dev/null +++ b/app/pages/constructeurs.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/app/pages/machine/[id].vue b/app/pages/machine/[id].vue index 8cdd7d4..19f66ff 100644 --- a/app/pages/machine/[id].vue +++ b/app/pages/machine/[id].vue @@ -105,16 +105,19 @@ -
- {{ machineConstructeur || 'Non défini' }} +
+ {{ machine.value?.constructeur?.name || 'Non défini' }} + + {{ [machine.value?.constructeur?.email, machine.value?.constructeur?.phone].filter(Boolean).join(' • ') }} + +
@@ -350,7 +353,7 @@ -watch( - constructeurs, - (list) => { - options.value = [...list] - }, - { immediate: true } -) diff --git a/app/components/PieceItem.vue b/app/components/PieceItem.vue index 10f5ee6..9774748 100644 --- a/app/components/PieceItem.vue +++ b/app/components/PieceItem.vue @@ -42,7 +42,9 @@
@@ -260,6 +262,11 @@ const documentsLoaded = ref(!!(props.piece.documents && props.piece.documents.le const pieceDocuments = computed(() => props.piece.documents || []) const documentIcon = (doc) => getFileIcon({ name: doc.filename || doc.name, mime: doc.mimeType }) +const handleConstructeurChange = (value) => { + props.piece.constructeurId = value + updatePiece() +} + const { uploadDocuments, deleteDocument, loadDocumentsByPiece } = useDocuments() const refreshDocuments = async () => { @@ -337,16 +344,6 @@ watch( } ) -watch( - () => props.piece.constructeurId, - (newVal, oldVal) => { - if (!props.isEditMode) return - if (oldVal === undefined) return - if (newVal !== oldVal) { - updatePiece() - } - } -) // Méthodes pour gérer les champs personnalisés const setCustomFieldValue = (fieldValueId, value) => { diff --git a/app/pages/machine/[id].vue b/app/pages/machine/[id].vue index 19f66ff..aac401b 100644 --- a/app/pages/machine/[id].vue +++ b/app/pages/machine/[id].vue @@ -107,15 +107,17 @@
- {{ machine.value?.constructeur?.name || 'Non défini' }} + {{ machineConstructeurDisplay?.name || 'Non défini' }} - {{ [machine.value?.constructeur?.email, machine.value?.constructeur?.phone].filter(Boolean).join(' • ') }} + {{ [machineConstructeurDisplay?.email, machineConstructeurDisplay?.phone].filter(Boolean).join(' • ') || '' }}
@@ -366,6 +368,7 @@ import { getFileIcon } from '~/utils/fileIcons' import ComponentHierarchy from '~/components/ComponentHierarchy.vue' import DocumentUpload from '~/components/DocumentUpload.vue' import ConstructeurSelect from '~/components/ConstructeurSelect.vue' +import { useConstructeurs } from '~/composables/useConstructeurs' const route = useRoute() const machineId = route.params.id @@ -401,11 +404,18 @@ const machine = ref(null) const components = ref([]) const pieces = ref([]) +const { constructeurs, loadConstructeurs } = useConstructeurs() + // Champs de la machine const machineName = ref('') const machineReference = ref('') const machineEmplacement = ref('') const machineConstructeurId = ref(null) +const machineConstructeurDisplay = computed(() => { + const id = machineConstructeurId.value || machine.value?.constructeur?.id || machine.value?.constructeurId + if (!id) return machine.value?.constructeur || null + return constructeurs.value.find(item => item.id === id) || machine.value?.constructeur || null +}) // Valeurs des champs personnalisés de la machine const machineCustomFieldValues = reactive({}) @@ -413,18 +423,11 @@ const machineCustomFieldValues = reactive({}) const machineDocumentFiles = ref([]) const machineDocumentsUploading = ref(false) const machineDocumentsLoaded = ref(false) -const machineConstructeurInitialized = ref(false) -watch(machineConstructeurId, (newValue, oldValue) => { - if (!machine.value) return - if (!machineConstructeurInitialized.value) { - machineConstructeurInitialized.value = true - return - } - if (newValue !== oldValue) { - updateMachineInfo() - } -}) +const handleMachineConstructeurChange = async (value) => { + machineConstructeurId.value = value + await updateMachineInfo() +} // Mode d'édition const isEditMode = ref(false) @@ -451,7 +454,6 @@ const initMachineFields = () => { machineReference.value = machine.value.reference || '' machineEmplacement.value = machine.value.emplacement || '' machineConstructeurId.value = machine.value.constructeurId || machine.value.constructeur?.id || null - machineConstructeurInitialized.value = false } } @@ -839,7 +841,10 @@ const toggleEditMode = () => { // Lifecycle onMounted(() => { loadMachineData() - + if (!constructeurs.value.length) { + loadConstructeurs() + } + // Vérifier si on doit activer le mode édition depuis l'URL const route = useRoute() if (route.query.edit === 'true') { From 37c66ac3d6460470339d048548b25c8c01175c9f Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 17 Sep 2025 17:12:41 +0200 Subject: [PATCH 021/274] feat: add document preview overlay --- app/components/ComponentItem.vue | 30 +++ app/components/DocumentPreviewModal.vue | 152 +++++++++++++ app/components/PieceItem.vue | 30 +++ app/pages/documents.vue | 32 ++- app/pages/machine/[id].vue | 30 +++ app/pages/sites.vue | 29 +++ app/utils/documentPreview.js | 25 ++ deploy.sh | 290 ++++++++++++++++++++++++ 8 files changed, 617 insertions(+), 1 deletion(-) create mode 100644 app/components/DocumentPreviewModal.vue create mode 100644 app/utils/documentPreview.js create mode 100644 deploy.sh diff --git a/app/components/ComponentItem.vue b/app/components/ComponentItem.vue index a4bf63a..95c7a54 100644 --- a/app/components/ComponentItem.vue +++ b/app/components/ComponentItem.vue @@ -1,5 +1,11 @@ diff --git a/app/components/PieceItem.vue b/app/components/PieceItem.vue index 8b92423..f212b4f 100644 --- a/app/components/PieceItem.vue +++ b/app/components/PieceItem.vue @@ -276,13 +276,21 @@ class="flex items-center justify-between rounded border border-base-200 bg-base-100 px-3 py-2" >
- +
+
{{ document.name }} @@ -340,7 +348,7 @@ import { useCustomFields } from "~/composables/useCustomFields"; import { useToast } from "~/composables/useToast"; import { useDocuments } from "~/composables/useDocuments"; import { getFileIcon } from "~/utils/fileIcons"; -import { canPreviewDocument } from "~/utils/documentPreview"; +import { canPreviewDocument, isImageDocument } from "~/utils/documentPreview"; import DocumentUpload from "~/components/DocumentUpload.vue"; import DocumentPreviewModal from "~/components/DocumentPreviewModal.vue"; import IconLucidePackage from "~icons/lucide/package"; diff --git a/app/components/sites/SiteEditModal.vue b/app/components/sites/SiteEditModal.vue index 945c8bf..224addb 100644 --- a/app/components/sites/SiteEditModal.vue +++ b/app/components/sites/SiteEditModal.vue @@ -53,9 +53,21 @@ class="flex items-center justify-between rounded border border-base-200 bg-base-100 px-3 py-2" >
- - +
+ +
{{ document.name }} @@ -103,6 +115,7 @@ diff --git a/app/pages/component-catalog.vue b/app/pages/component-catalog.vue index cc73db3..f653435 100644 --- a/app/pages/component-catalog.vue +++ b/app/pages/component-catalog.vue @@ -91,6 +91,7 @@ + @@ -99,6 +100,12 @@ + @@ -134,6 +141,8 @@ import { computed, onMounted, ref } from 'vue' import { useComposants } from '~/composables/useComposants' import { useToast } from '~/composables/useToast' +import DocumentThumbnail from '~/components/DocumentThumbnail.vue' +import { isImageDocument, isPdfDocument } from '~/utils/documentPreview' const { showError } = useToast() const { composants, loadComposants, loading: loadingComposantsRef, deleteComposant } = useComposants() @@ -145,6 +154,32 @@ const searchTerm = ref('') const sortField = ref<'name' | 'createdAt'>('name') const sortDirection = ref<'asc' | 'desc'>('asc') +const resolvePrimaryDocument = (component: Record) => { + const documents = Array.isArray(component?.documents) ? component.documents : [] + if (!documents.length) { + return null + } + const normalized = documents.filter((doc) => doc && typeof doc === 'object') + const withPath = normalized.filter((doc) => doc?.path) + const pdf = withPath.find((doc) => isPdfDocument(doc)) + if (pdf) { + return pdf + } + const image = withPath.find((doc) => isImageDocument(doc)) + if (image) { + return image + } + return withPath[0] ?? normalized[0] ?? null +} + +const resolvePreviewAlt = (component: Record) => { + const parts = [component?.name, component?.reference].filter(Boolean) + if (parts.length) { + return `Aperçu du document de ${parts.join(' – ')}` + } + return 'Aperçu du document' +} + const resolveComparableName = (component: Record) => { const toComparable = (value?: string | null) => (value ?? '').toString().trim().toLowerCase() diff --git a/app/pages/pieces-catalog.vue b/app/pages/pieces-catalog.vue index 95265a1..6530c14 100644 --- a/app/pages/pieces-catalog.vue +++ b/app/pages/pieces-catalog.vue @@ -90,6 +90,7 @@
Aperçu Nom Catégorie Référence
+ + {{ component.name || 'Composant sans nom' }} {{ component.typeComposant?.name || '—' }} {{ component.reference || '—' }}
+ @@ -98,6 +99,12 @@ + @@ -133,6 +140,8 @@ import { computed, onMounted, ref } from 'vue' import { usePieces } from '~/composables/usePieces' import { useToast } from '~/composables/useToast' +import DocumentThumbnail from '~/components/DocumentThumbnail.vue' +import { isImageDocument, isPdfDocument } from '~/utils/documentPreview' const { showError } = useToast() const { pieces, loadPieces, loading: loadingPiecesRef, deletePiece } = usePieces() @@ -144,6 +153,35 @@ const searchTerm = ref('') const sortField = ref<'name' | 'createdAt'>('name') const sortDirection = ref<'asc' | 'desc'>('asc') +const resolvePrimaryDocument = (piece: Record) => { + const documents = Array.isArray(piece?.documents) ? piece.documents : [] + if (!documents.length) { + return null + } + const normalized = documents.filter((doc) => doc && typeof doc === 'object') + const withPath = normalized.filter((doc) => doc?.path) + + const pdf = withPath.find((doc) => isPdfDocument(doc)) + if (pdf) { + return pdf + } + + const image = withPath.find((doc) => isImageDocument(doc)) + if (image) { + return image + } + + return withPath[0] ?? normalized[0] ?? null +} + +const resolvePreviewAlt = (piece: Record) => { + const parts = [piece?.name, piece?.reference].filter(Boolean) + if (parts.length) { + return `Aperçu du document de ${parts.join(' – ')}` + } + return 'Aperçu du document' +} + const resolveComparableName = (piece: Record) => { const normalise = (value?: string | null) => (value ?? '').toString().trim().toLowerCase() From 5684bc282bb7ec582c30308ff6d73bd77483392c Mon Sep 17 00:00:00 2001 From: Matthieu Date: Fri, 24 Oct 2025 15:42:22 +0200 Subject: [PATCH 093/274] =?UTF-8?q?fix:=20afficher=20le=20d=C3=A9tail=20de?= =?UTF-8?q?s=20blocages=20avant=20suppression?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/pages/component-catalog.vue | 37 +++++++++++++++++++++++++++------ app/pages/pieces-catalog.vue | 37 +++++++++++++++++++++++++++------ 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/app/pages/component-catalog.vue b/app/pages/component-catalog.vue index f653435..d2ce710 100644 --- a/app/pages/component-catalog.vue +++ b/app/pages/component-catalog.vue @@ -180,6 +180,30 @@ const resolvePreviewAlt = (component: Record) => { return 'Aperçu du document' } +const resolveDeleteBlockingReasons = (component: Record) => { + const reasons: string[] = [] + const machineLinks = Array.isArray(component?.machineLinks) + ? component.machineLinks.length + : component?.machineLinksCount ?? 0 + const documents = Array.isArray(component?.documents) + ? component.documents.length + : component?.documentsCount ?? 0 + const customFields = Array.isArray(component?.customFieldValues) + ? component.customFieldValues.length + : component?.customFieldValuesCount ?? 0 + + if (machineLinks > 0) { + reasons.push(`${machineLinks} liaison${machineLinks > 1 ? 's' : ''} machine`) + } + if (documents > 0) { + reasons.push(`${documents} document${documents > 1 ? 's' : ''}`) + } + if (customFields > 0) { + reasons.push(`${customFields} valeur${customFields > 1 ? 's' : ''} de champ personnalisé`) + } + return reasons +} + const resolveComparableName = (component: Record) => { const toComparable = (value?: string | null) => (value ?? '').toString().trim().toLowerCase() @@ -235,13 +259,14 @@ const visibleComposants = computed(() => { }) const handleDeleteComponent = async (component: Record) => { - const hasLinkedElements = - (component?.machineLinks?.length ?? 0) > 0 || - (component?.documents?.length ?? 0) > 0 || - (component?.customFieldValues?.length ?? 0) > 0 + const blockingReasons = resolveDeleteBlockingReasons(component) - if (hasLinkedElements) { - showError('Impossible de supprimer ce composant car il possède des éléments liés.') + if (blockingReasons.length) { + showError( + `Impossible de supprimer ce composant car il possède encore: ${blockingReasons.join( + ', ', + )}. Supprimez ou détachez ces éléments avant de réessayer.` + ) return } diff --git a/app/pages/pieces-catalog.vue b/app/pages/pieces-catalog.vue index 6530c14..202cc55 100644 --- a/app/pages/pieces-catalog.vue +++ b/app/pages/pieces-catalog.vue @@ -182,6 +182,30 @@ const resolvePreviewAlt = (piece: Record) => { return 'Aperçu du document' } +const resolveDeleteBlockingReasons = (piece: Record) => { + const reasons: string[] = [] + const machineLinks = Array.isArray(piece?.machineLinks) + ? piece.machineLinks.length + : piece?.machineLinksCount ?? 0 + const documents = Array.isArray(piece?.documents) + ? piece.documents.length + : piece?.documentsCount ?? 0 + const customFields = Array.isArray(piece?.customFieldValues) + ? piece.customFieldValues.length + : piece?.customFieldValuesCount ?? 0 + + if (machineLinks > 0) { + reasons.push(`${machineLinks} liaison${machineLinks > 1 ? 's' : ''} machine`) + } + if (documents > 0) { + reasons.push(`${documents} document${documents > 1 ? 's' : ''}`) + } + if (customFields > 0) { + reasons.push(`${customFields} valeur${customFields > 1 ? 's' : ''} de champ personnalisé`) + } + return reasons +} + const resolveComparableName = (piece: Record) => { const normalise = (value?: string | null) => (value ?? '').toString().trim().toLowerCase() @@ -237,13 +261,14 @@ const visiblePieces = computed(() => { }) const handleDeletePiece = async (piece: Record) => { - const hasLinkedElements = - (piece?.machineLinks?.length ?? 0) > 0 || - (piece?.documents?.length ?? 0) > 0 || - (piece?.customFieldValues?.length ?? 0) > 0 + const blockingReasons = resolveDeleteBlockingReasons(piece) - if (hasLinkedElements) { - showError('Impossible de supprimer cette pièce car elle possède des éléments liés.') + if (blockingReasons.length) { + showError( + `Impossible de supprimer cette pièce car elle possède encore: ${blockingReasons.join( + ', ', + )}. Supprimez ou détachez ces éléments avant de réessayer.` + ) return } From da447e4ea2a4d82be1253452ff43133c44d02e74 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Fri, 24 Oct 2025 15:50:20 +0200 Subject: [PATCH 094/274] feat: supprimer automatiquement les valeurs de champs si besoin --- app/pages/component-catalog.vue | 27 ++++++++++++++++++--------- app/pages/pieces-catalog.vue | 28 +++++++++++++++++++--------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/app/pages/component-catalog.vue b/app/pages/component-catalog.vue index d2ce710..6c92083 100644 --- a/app/pages/component-catalog.vue +++ b/app/pages/component-catalog.vue @@ -180,8 +180,8 @@ const resolvePreviewAlt = (component: Record) => { return 'Aperçu du document' } -const resolveDeleteBlockingReasons = (component: Record) => { - const reasons: string[] = [] +const resolveDeleteGuard = (component: Record) => { + const blockingReasons: string[] = [] const machineLinks = Array.isArray(component?.machineLinks) ? component.machineLinks.length : component?.machineLinksCount ?? 0 @@ -193,15 +193,15 @@ const resolveDeleteBlockingReasons = (component: Record) => { : component?.customFieldValuesCount ?? 0 if (machineLinks > 0) { - reasons.push(`${machineLinks} liaison${machineLinks > 1 ? 's' : ''} machine`) + blockingReasons.push(`${machineLinks} liaison${machineLinks > 1 ? 's' : ''} machine`) } if (documents > 0) { - reasons.push(`${documents} document${documents > 1 ? 's' : ''}`) + blockingReasons.push(`${documents} document${documents > 1 ? 's' : ''}`) } - if (customFields > 0) { - reasons.push(`${customFields} valeur${customFields > 1 ? 's' : ''} de champ personnalisé`) + return { + blockingReasons, + hasCustomFields: customFields > 0, } - return reasons } const resolveComparableName = (component: Record) => { @@ -259,7 +259,7 @@ const visibleComposants = computed(() => { }) const handleDeleteComponent = async (component: Record) => { - const blockingReasons = resolveDeleteBlockingReasons(component) + const { blockingReasons, hasCustomFields } = resolveDeleteGuard(component) if (blockingReasons.length) { showError( @@ -271,7 +271,16 @@ const handleDeleteComponent = async (component: Record) => { } const componentName = component?.name || 'ce composant' - const confirmed = window.confirm(`Voulez-vous vraiment supprimer ${componentName} ?`) + const confirmLines = [ + `Voulez-vous vraiment supprimer ${componentName} ?`, + ] + if (hasCustomFields) { + confirmLines.push( + 'Les valeurs de champs personnalisés associées seront également supprimées.' + ) + } + + const confirmed = window.confirm(confirmLines.join('\n\n')) if (!confirmed) { return } diff --git a/app/pages/pieces-catalog.vue b/app/pages/pieces-catalog.vue index 202cc55..6e616a8 100644 --- a/app/pages/pieces-catalog.vue +++ b/app/pages/pieces-catalog.vue @@ -182,8 +182,8 @@ const resolvePreviewAlt = (piece: Record) => { return 'Aperçu du document' } -const resolveDeleteBlockingReasons = (piece: Record) => { - const reasons: string[] = [] +const resolveDeleteGuard = (piece: Record) => { + const blockingReasons: string[] = [] const machineLinks = Array.isArray(piece?.machineLinks) ? piece.machineLinks.length : piece?.machineLinksCount ?? 0 @@ -195,15 +195,15 @@ const resolveDeleteBlockingReasons = (piece: Record) => { : piece?.customFieldValuesCount ?? 0 if (machineLinks > 0) { - reasons.push(`${machineLinks} liaison${machineLinks > 1 ? 's' : ''} machine`) + blockingReasons.push(`${machineLinks} liaison${machineLinks > 1 ? 's' : ''} machine`) } if (documents > 0) { - reasons.push(`${documents} document${documents > 1 ? 's' : ''}`) + blockingReasons.push(`${documents} document${documents > 1 ? 's' : ''}`) } - if (customFields > 0) { - reasons.push(`${customFields} valeur${customFields > 1 ? 's' : ''} de champ personnalisé`) + return { + blockingReasons, + hasCustomFields: customFields > 0, } - return reasons } const resolveComparableName = (piece: Record) => { @@ -261,7 +261,7 @@ const visiblePieces = computed(() => { }) const handleDeletePiece = async (piece: Record) => { - const blockingReasons = resolveDeleteBlockingReasons(piece) + const { blockingReasons, hasCustomFields } = resolveDeleteGuard(piece) if (blockingReasons.length) { showError( @@ -273,7 +273,17 @@ const handleDeletePiece = async (piece: Record) => { } const pieceName = piece?.name || 'cette pièce' - const confirmed = window.confirm(`Voulez-vous vraiment supprimer ${pieceName} ?`) + const confirmLines = [ + `Voulez-vous vraiment supprimer ${pieceName} ?`, + ] + + if (hasCustomFields) { + confirmLines.push( + 'Les valeurs de champs personnalisés associées seront également supprimées.' + ) + } + + const confirmed = window.confirm(confirmLines.join('\n\n')) if (!confirmed) { return } From b752fba69a26943042410dae99560448d450aa0a Mon Sep 17 00:00:00 2001 From: Matthieu Date: Tue, 28 Oct 2025 16:37:10 +0100 Subject: [PATCH 095/274] =?UTF-8?q?feat:=20g=C3=A9rer=20les=20constructeur?= =?UTF-8?q?s=20multiples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/components/ComponentItem.vue | 77 ++++- app/components/ConstructeurSelect.vue | 279 ++++++++++++------ app/components/PieceItem.vue | 76 ++++- app/composables/useComposants.js | 5 +- app/composables/useMachines.js | 7 +- app/composables/usePieces.js | 5 +- app/pages/component/[id]/edit.vue | 15 +- app/pages/component/create.vue | 13 +- app/pages/machine/[id].vue | 335 ++++++++++++++++++---- app/pages/pieces/[id]/edit.vue | 15 +- app/pages/pieces/create.vue | 9 +- app/shared/constructeurUtils.ts | 115 ++++++++ app/shared/modelUtils.ts | 13 +- app/utils/printTemplates/machineReport.js | 159 +++++++--- 14 files changed, 901 insertions(+), 222 deletions(-) create mode 100644 app/shared/constructeurUtils.ts diff --git a/app/components/ComponentItem.vue b/app/components/ComponentItem.vue index af727e9..8624d41 100644 --- a/app/components/ComponentItem.vue +++ b/app/components/ComponentItem.vue @@ -32,7 +32,15 @@ Défini dans le catalogue {{ component.reference }} - {{ component.constructeur?.name }} + {{ component.prix }}€
-
- {{ component.constructeur?.name || 'Non défini' }} - - {{ [component.constructeur?.email, component.constructeur?.phone].filter(Boolean).join(' • ') }} - +
+
+ {{ constructeur.name }} + + {{ formatConstructeurContact(constructeur) }} + +
+ Non défini
@@ -331,6 +349,12 @@ import DocumentPreviewModal from '~/components/DocumentPreviewModal.vue' import IconLucideChevronRight from '~icons/lucide/chevron-right' import { useCustomFields } from '~/composables/useCustomFields' import { useToast } from '~/composables/useToast' +import { useConstructeurs } from '~/composables/useConstructeurs' +import { + formatConstructeurContact as formatConstructeurContactSummary, + resolveConstructeurs, + uniqueConstructeurIds, +} from '~/shared/constructeurUtils' const props = defineProps({ component: { @@ -406,6 +430,28 @@ const childComponents = computed(() => { return Array.isArray(list) ? list : [] }) +const { constructeurs } = useConstructeurs() + +const componentConstructeurIds = computed(() => + uniqueConstructeurIds( + props.component, + Array.isArray(props.component.constructeurs) ? props.component.constructeurs : [], + props.component.constructeur ? [props.component.constructeur] : [], + ), +) + +const componentConstructeursDisplay = computed(() => + resolveConstructeurs( + componentConstructeurIds.value, + Array.isArray(props.component.constructeurs) ? props.component.constructeurs : [], + props.component.constructeur ? [props.component.constructeur] : [], + constructeurs.value, + ), +) + +const formatConstructeurContact = (constructeur) => + formatConstructeurContactSummary(constructeur) + const extractStructureCustomFields = (structure) => { if (!structure || typeof structure !== 'object') { return [] @@ -686,7 +732,17 @@ watch( ) const handleConstructeurChange = async (value) => { - props.component.constructeurId = value + const ids = uniqueConstructeurIds(value) + + props.component.constructeurIds = [...ids] + props.component.constructeurId = null + props.component.constructeur = null + props.component.constructeurs = resolveConstructeurs( + ids, + constructeurs.value, + Array.isArray(props.component.constructeurs) ? props.component.constructeurs : [], + ) + await updateComponent() } @@ -723,7 +779,10 @@ const toggleCollapse = () => { } const updateComponent = () => { - emit('update', props.component) + emit('update', { + ...props.component, + constructeurIds: componentConstructeurIds.value, + }) } function resolveFieldKey(field, index) { diff --git a/app/components/ConstructeurSelect.vue b/app/components/ConstructeurSelect.vue index c9ea3dc..6bdaa13 100644 --- a/app/components/ConstructeurSelect.vue +++ b/app/components/ConstructeurSelect.vue @@ -1,7 +1,7 @@ - diff --git a/app/components/PieceItem.vue b/app/components/PieceItem.vue index 9c709f5..85d439b 100644 --- a/app/components/PieceItem.vue +++ b/app/components/PieceItem.vue @@ -68,22 +68,33 @@
Constructeur: - - {{ - piece.constructeur?.name || "Non défini" - }} - - {{ - [piece.constructeur?.email, piece.constructeur?.phone] - .filter(Boolean) - .join(" • ") - }} +
+
+
+ + {{ constructeur.name }} + + + {{ formatConstructeurContact(constructeur) }} + +
+
+ + Non défini - +
@@ -353,6 +364,7 @@ diff --git a/app/components/TypeEditForm.vue b/app/components/TypeEditForm.vue index 9bab4c5..33f1ec0 100644 --- a/app/components/TypeEditForm.vue +++ b/app/components/TypeEditForm.vue @@ -54,14 +54,33 @@ const emit = defineEmits(['update:modelValue', 'submit']) const deepClone = value => JSON.parse(JSON.stringify(value)) +const createFieldKey = () => `cf-${Math.random().toString(16).slice(2)}-${Date.now()}` + +const withNormalizedOrder = (items = []) => { + if (!Array.isArray(items)) { return [] } + return items + .map((item, index) => { + const clone = deepClone(item) + const currentOrder = + typeof clone?.orderIndex === 'number' ? clone.orderIndex : index + clone.orderIndex = currentOrder + if (typeof clone?.__key !== 'string' || !clone.__key) { + clone.__key = createFieldKey() + } + return clone + }) + .sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)) + .map((item, index) => ({ ...item, orderIndex: index })) +} + const createDefaultForm = (source = {}) => ({ name: source.name || '', description: source.description || '', category: source.category || '', maintenanceFrequency: source.maintenanceFrequency || '', - customFields: deepClone(source.customFields || []), - componentRequirements: deepClone(source.componentRequirements || []), - pieceRequirements: deepClone(source.pieceRequirements || []) + customFields: withNormalizedOrder(source.customFields || []), + componentRequirements: withNormalizedOrder(source.componentRequirements || []), + pieceRequirements: withNormalizedOrder(source.pieceRequirements || []) }) const formData = reactive(createDefaultForm(props.modelValue)) diff --git a/app/pages/component/[id]/edit.vue b/app/pages/component/[id]/edit.vue index e57fa7c..d503b67 100644 --- a/app/pages/component/[id]/edit.vue +++ b/app/pages/component/[id]/edit.vue @@ -424,6 +424,7 @@ interface CustomFieldInput { value: string customFieldId: string | null customFieldValueId: string | null + orderIndex: number } const route = useRoute() @@ -756,6 +757,7 @@ const buildCustomFieldInputs = ( ...definition, customFieldId: definition.customFieldId || definition.id, customFieldValueId: null, + orderIndex: definition.orderIndex, } } @@ -765,8 +767,14 @@ const buildCustomFieldInputs = ( customFieldId: matched.customField?.id || definition.customFieldId || definition.id, customFieldValueId: matched.id ?? null, value: formatDefaultValue(definition.type, resolvedValue), + orderIndex: Math.min( + definition.orderIndex ?? 0, + typeof matched.customField?.orderIndex === 'number' + ? matched.customField.orderIndex + : definition.orderIndex ?? 0, + ), } - }) + }).sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)) return resolved } @@ -780,11 +788,12 @@ const normalizeCustomFieldInputs = (structure: ComponentModelStructure | null): } const fields = Array.isArray(structure.customFields) ? structure.customFields : [] return fields - .map((field) => normalizeCustomField(field)) + .map((field, index) => normalizeCustomField(field, index)) .filter((field): field is CustomFieldInput => field !== null) + .sort((a, b) => a.orderIndex - b.orderIndex) } -const normalizeCustomField = (rawField: any): CustomFieldInput | null => { +const normalizeCustomField = (rawField: any, fallbackIndex = 0): CustomFieldInput | null => { if (!rawField || typeof rawField !== 'object') { return null } @@ -802,7 +811,8 @@ const normalizeCustomField = (rawField: any): CustomFieldInput | null => { const customFieldValueId = typeof rawField.customFieldValueId === 'string' ? rawField.customFieldValueId : null - return { id, name, type, required, options, value, customFieldId, customFieldValueId } + const orderIndex = typeof rawField.orderIndex === 'number' ? rawField.orderIndex : fallbackIndex + return { id, name, type, required, options, value, customFieldId, customFieldValueId, orderIndex } } const resolveFieldName = (field: any): string => { diff --git a/app/pages/component/create.vue b/app/pages/component/create.vue index e381119..2d1bc6a 100644 --- a/app/pages/component/create.vue +++ b/app/pages/component/create.vue @@ -841,6 +841,7 @@ interface CustomFieldInput { value: string customFieldId: string | null customFieldValueId: string | null + orderIndex: number } const fieldKey = (field: CustomFieldInput, index: number) => @@ -852,11 +853,12 @@ const normalizeCustomFieldInputs = (structure: ComponentModelStructure | null): } const fields = Array.isArray(structure.customFields) ? structure.customFields : [] return fields - .map((field) => normalizeCustomField(field)) + .map((field, index) => normalizeCustomField(field, index)) .filter((field): field is CustomFieldInput => field !== null) + .sort((a, b) => a.orderIndex - b.orderIndex) } -const normalizeCustomField = (rawField: any): CustomFieldInput | null => { +const normalizeCustomField = (rawField: any, fallbackIndex = 0): CustomFieldInput | null => { if (!rawField || typeof rawField !== 'object') { return null } @@ -874,7 +876,8 @@ const normalizeCustomField = (rawField: any): CustomFieldInput | null => { const customFieldValueId = typeof rawField.customFieldValueId === 'string' ? rawField.customFieldValueId : null - return { id, name, type, required, options, value, customFieldId, customFieldValueId } + const orderIndex = typeof rawField.orderIndex === 'number' ? rawField.orderIndex : fallbackIndex + return { id, name, type, required, options, value, customFieldId, customFieldValueId, orderIndex } } const resolveFieldName = (field: any): string => { diff --git a/app/pages/machine-skeleton/new.vue b/app/pages/machine-skeleton/new.vue index 49dc61b..26112cd 100644 --- a/app/pages/machine-skeleton/new.vue +++ b/app/pages/machine-skeleton/new.vue @@ -139,12 +139,15 @@ const parseOptions = (field = {}) => { const normalizeCustomFields = (fields = []) => fields .filter(field => field?.name && field.name.trim() !== '') - .map(field => ({ + .map((field, index) => ({ name: field.name, type: field.type || '', required: !!field.required, - options: parseOptions(field) + options: parseOptions(field), + orderIndex: typeof field.orderIndex === 'number' ? field.orderIndex : index })) + .sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)) + .map((field, index) => ({ ...field, orderIndex: index })) const toIntegerOrNull = (value, fallback = null) => { if (value === '' || value === undefined || value === null) { diff --git a/app/pages/machine/[id].vue b/app/pages/machine/[id].vue index a5f0d54..4fdb4c8 100644 --- a/app/pages/machine/[id].vue +++ b/app/pages/machine/[id].vue @@ -1853,6 +1853,12 @@ const visibleMachineCustomFields = computed(() => { const summarizeCustomFields = (fields = []) => { const seen = new Set() return fields + .slice() + .sort((a, b) => { + const left = typeof a?.orderIndex === 'number' ? a.orderIndex : 0 + const right = typeof b?.orderIndex === 'number' ? b.orderIndex : 0 + return left - right + }) .filter(shouldDisplayCustomField) .filter((field) => { const key = field.customFieldId || field.id || field.name @@ -2013,11 +2019,12 @@ const normalizeExistingCustomFieldDefinitions = (fields) => { return [] } return fields - .map((field) => normalizeCustomFieldDefinitionEntry(field)) + .map((field, index) => normalizeCustomFieldDefinitionEntry(field, index)) .filter((definition) => definition !== null) + .sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)) } -const normalizeCustomFieldDefinitionEntry = (definition = {}) => { +const normalizeCustomFieldDefinitionEntry = (definition = {}, fallbackIndex = 0) => { const name = extractDefinitionName(definition) if (!name) { return null @@ -2028,6 +2035,7 @@ const normalizeCustomFieldDefinitionEntry = (definition = {}) => { const defaultValue = extractDefinitionDefaultValue(definition) const id = typeof definition?.id === 'string' ? definition.id : undefined const customFieldId = typeof definition?.customFieldId === 'string' ? definition.customFieldId : id + const orderIndex = typeof definition?.orderIndex === 'number' ? definition.orderIndex : fallbackIndex return { id, customFieldId, @@ -2037,6 +2045,7 @@ const normalizeCustomFieldDefinitionEntry = (definition = {}) => { options, defaultValue, readOnly: !!definition?.readOnly, + orderIndex, } } diff --git a/app/pages/pieces/[id]/edit.vue b/app/pages/pieces/[id]/edit.vue index 3e0fd9b..ce2e891 100644 --- a/app/pages/pieces/[id]/edit.vue +++ b/app/pages/pieces/[id]/edit.vue @@ -383,6 +383,7 @@ interface CustomFieldInput { value: string customFieldId: string | null customFieldValueId: string | null + orderIndex: number } const route = useRoute() @@ -706,6 +707,7 @@ const buildCustomFieldInputs = ( ...definition, customFieldId: definition.customFieldId || definition.id, customFieldValueId: null, + orderIndex: definition.orderIndex, } } @@ -715,8 +717,14 @@ const buildCustomFieldInputs = ( customFieldId: matched.customField?.id || definition.customFieldId || definition.id, customFieldValueId: matched.id ?? null, value: formatDefaultValue(definition.type, resolvedValue), + orderIndex: Math.min( + definition.orderIndex ?? 0, + typeof matched.customField?.orderIndex === 'number' + ? matched.customField.orderIndex + : definition.orderIndex ?? 0, + ), } - }) + }).sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)) return resolved } @@ -730,11 +738,12 @@ const normalizeCustomFieldInputs = (structure: PieceModelStructure | null): Cust } const fields = Array.isArray(structure.customFields) ? structure.customFields : [] return fields - .map((field) => normalizeCustomField(field)) + .map((field, index) => normalizeCustomField(field, index)) .filter((field): field is CustomFieldInput => field !== null) + .sort((a, b) => a.orderIndex - b.orderIndex) } -const normalizeCustomField = (rawField: any): CustomFieldInput | null => { +const normalizeCustomField = (rawField: any, fallbackIndex = 0): CustomFieldInput | null => { if (!rawField || typeof rawField !== 'object') { return null } @@ -755,7 +764,9 @@ const normalizeCustomField = (rawField: any): CustomFieldInput | null => { ? rawField.customFieldValueId : null - return { id, name, type, required, options, value, customFieldId, customFieldValueId } + const orderIndex = typeof rawField.orderIndex === 'number' ? rawField.orderIndex : fallbackIndex + + return { id, name, type, required, options, value, customFieldId, customFieldValueId, orderIndex } } const resolveFieldName = (field: any): string => { diff --git a/app/pages/pieces/create.vue b/app/pages/pieces/create.vue index ec2437b..7952368 100644 --- a/app/pages/pieces/create.vue +++ b/app/pages/pieces/create.vue @@ -467,6 +467,7 @@ interface CustomFieldInput { value: string customFieldId: string | null customFieldValueId: string | null + orderIndex: number } const fieldKey = (field: CustomFieldInput, index: number) => @@ -478,11 +479,12 @@ const normalizeCustomFieldInputs = (structure: PieceModelStructure | null): Cust } const fields = Array.isArray(structure.customFields) ? structure.customFields : [] return fields - .map((field) => normalizeCustomField(field)) + .map((field, index) => normalizeCustomField(field, index)) .filter((field): field is CustomFieldInput => field !== null) + .sort((a, b) => a.orderIndex - b.orderIndex) } -const normalizeCustomField = (rawField: any): CustomFieldInput | null => { +const normalizeCustomField = (rawField: any, fallbackIndex = 0): CustomFieldInput | null => { if (!rawField || typeof rawField !== 'object') { return null } @@ -503,7 +505,9 @@ const normalizeCustomField = (rawField: any): CustomFieldInput | null => { ? rawField.customFieldValueId : null - return { id, name, type, required, options, value, customFieldId, customFieldValueId } + const orderIndex = typeof rawField.orderIndex === 'number' ? rawField.orderIndex : fallbackIndex + + return { id, name, type, required, options, value, customFieldId, customFieldValueId, orderIndex } } const resolveFieldName = (field: any): string => { diff --git a/app/pages/type/edit/[id].vue b/app/pages/type/edit/[id].vue index 15cc7f4..dcaba98 100644 --- a/app/pages/type/edit/[id].vue +++ b/app/pages/type/edit/[id].vue @@ -92,12 +92,15 @@ const parseOptions = (field = {}) => { const normalizeCustomFields = (fields = []) => fields .filter(field => field?.name && field.name.trim() !== '') - .map(field => ({ + .map((field, index) => ({ name: field.name, type: field.type || '', required: !!field.required, - options: parseOptions(field) + options: parseOptions(field), + orderIndex: typeof field.orderIndex === 'number' ? field.orderIndex : index })) + .sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)) + .map((field, index) => ({ ...field, orderIndex: index })) const toIntegerOrNull = (value, fallback = null) => { if (value === '' || value === undefined || value === null) { diff --git a/app/shared/modelUtils.ts b/app/shared/modelUtils.ts index 68d6025..fbe1522 100644 --- a/app/shared/modelUtils.ts +++ b/app/shared/modelUtils.ts @@ -94,7 +94,7 @@ const sanitizeCustomFields = (fields: any[]): ComponentModelCustomField[] => { } return fields - .map((field) => { + .map((field, index) => { const rawName = typeof field?.name === 'string' ? field.name @@ -173,6 +173,8 @@ const sanitizeCustomFields = (fields: any[]): ComponentModelCustomField[] => { if (customFieldId) { result.customFieldId = customFieldId } + const orderIndex = typeof field?.orderIndex === 'number' ? field.orderIndex : index + result.orderIndex = orderIndex return result }) .filter((field): field is ComponentModelCustomField => !!field) @@ -448,7 +450,7 @@ const hydrateCustomFields = (fields: any[]): any[] => { return [] } - return fields.map((field) => { + return fields.map((field, index) => { const valueObject = extractFieldValueObject(field) const name = typeof field?.name === 'string' ? field.name @@ -513,6 +515,7 @@ const hydrateCustomFields = (fields: any[]): any[] => { const id = typeof field?.id === 'string' ? field.id : undefined const customFieldId = typeof field?.customFieldId === 'string' ? field.customFieldId : undefined + const orderIndex = typeof field?.orderIndex === 'number' ? field.orderIndex : index return { name, @@ -523,6 +526,7 @@ const hydrateCustomFields = (fields: any[]): any[] => { defaultValue, id, customFieldId, + orderIndex, } }) } @@ -580,7 +584,7 @@ const mapComponentCustomFields = (fields: any[]) => { if (!Array.isArray(fields)) { return [] } - return hydrateCustomFields(fields).map((field) => { + return hydrateCustomFields(fields).map((field, index) => { const defaultValue = field?.defaultValue !== undefined && field?.defaultValue !== null && field?.defaultValue !== '' ? field.defaultValue @@ -597,6 +601,7 @@ const mapComponentCustomFields = (fields: any[]) => { typeof (field as any)?.customFieldId === 'string' ? (field as any).customFieldId : undefined, + orderIndex: typeof field?.orderIndex === 'number' ? field.orderIndex : index, } }) } @@ -772,7 +777,7 @@ const sanitizePieceCustomFields = (fields: any[]): PieceModelCustomField[] => { } return fields - .map((field) => { + .map((field, index) => { const name = typeof field?.name === 'string' ? field.name.trim() : '' if (!name) { return null @@ -799,6 +804,8 @@ const sanitizePieceCustomFields = (fields: any[]): PieceModelCustomField[] => { if (options) { result.options = options } + const orderIndex = typeof field?.orderIndex === 'number' ? field.orderIndex : index + result.orderIndex = orderIndex return result }) .filter((field): field is PieceModelCustomField => !!field) @@ -819,7 +826,7 @@ const hydratePieceCustomFields = (fields: any[]): PieceModelStructureEditorField return [] } - return fields.map((field) => ({ + return fields.map((field, index) => ({ name: field?.name ?? '', type: field?.type ?? 'text', required: !!field?.required, @@ -829,6 +836,7 @@ const hydratePieceCustomFields = (fields: any[]): PieceModelStructureEditorField : Array.isArray(field?.options) ? field.options.join('\n') : '', + orderIndex: typeof field?.orderIndex === 'number' ? field.orderIndex : index, })) } diff --git a/app/shared/types/inventory.ts b/app/shared/types/inventory.ts index c09546e..d842b5b 100644 --- a/app/shared/types/inventory.ts +++ b/app/shared/types/inventory.ts @@ -9,6 +9,7 @@ export interface ComponentModelCustomField { optionsText?: string id?: string customFieldId?: string + orderIndex?: number } export interface ComponentModelPiece { @@ -40,6 +41,7 @@ export interface PieceModelCustomField { type: PieceModelCustomFieldType required: boolean options?: string[] + orderIndex?: number } export interface PieceModelStructure { From 76cd3fac98384bafb41d127c0c0186255174404e Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 30 Oct 2025 11:34:19 +0100 Subject: [PATCH 097/274] feat: improve piece structure editor UX --- app/components/PieceModelStructureEditor.vue | 434 ++++++++++++------- 1 file changed, 285 insertions(+), 149 deletions(-) diff --git a/app/components/PieceModelStructureEditor.vue b/app/components/PieceModelStructureEditor.vue index 47245ae..fd65a83 100644 --- a/app/components/PieceModelStructureEditor.vue +++ b/app/components/PieceModelStructureEditor.vue @@ -1,185 +1,240 @@ +
+ + {{ restrictedModeMessage }} +
+
(), { initialData: null, saving: false, @@ -170,6 +185,8 @@ const props = withDefaults(defineProps<{ componentSubcomponentMaxDepth: 1, disableSubmit: false, disableSubmitMessage: '', + restrictedMode: false, + restrictedModeMessage: '', }) const emit = defineEmits<{ @@ -192,6 +209,12 @@ const disableSubmitMessage = computed(() => ? props.disableSubmitMessage : 'Cette catégorie ne peut pas être modifiée car des éléments y sont déjà liés.', ) +const restrictedMode = computed(() => props.restrictedMode === true) +const restrictedModeMessage = computed(() => + (props.restrictedModeMessage && props.restrictedModeMessage.trim()) + ? props.restrictedModeMessage + : '', +) const form = reactive({ name: '', diff --git a/app/composables/useCategoryEditGuard.ts b/app/composables/useCategoryEditGuard.ts index 2cfbf1e..74cb23d 100644 --- a/app/composables/useCategoryEditGuard.ts +++ b/app/composables/useCategoryEditGuard.ts @@ -32,7 +32,7 @@ const extractTotal = (payload: any, fallbackLength: number) => { export function useCategoryEditGuard (config: GuardConfig) { const { get } = useApi() - const { showError } = useToast() + const { showInfo } = useToast() const linkedCount = ref(0) const linkedLoading = ref(false) @@ -64,11 +64,15 @@ export function useCategoryEditGuard (config: GuardConfig) { } } - const isSubmitBlocked = computed( - () => linkedLoading.value || linkedCount.value > 0, + const isRestrictedMode = computed( + () => !linkedLoading.value && linkedCount.value > 0, ) - const submitBlockMessage = computed(() => { + const isSubmitBlocked = computed( + () => linkedLoading.value, + ) + + const restrictedModeMessage = computed(() => { if (linkedLoading.value) { return config.labels.verifying } @@ -76,23 +80,32 @@ export function useCategoryEditGuard (config: GuardConfig) { return '' } if (linkedCount.value === 1) { - return `Modification bloquée : 1 ${config.labels.singular} est déjà lié à cette catégorie.` + return `Mode restreint : 1 ${config.labels.singular} est déjà lié à cette catégorie. Vous pouvez ajouter de nouveaux champs personnalisés, mais pas modifier ou supprimer les existants.` } - return `Modification bloquée : ${linkedCount.value} ${config.labels.plural} sont déjà liés à cette catégorie.` + return `Mode restreint : ${linkedCount.value} ${config.labels.plural} sont déjà liés à cette catégorie. Vous pouvez ajouter de nouveaux champs personnalisés, mais pas modifier ou supprimer les existants.` + }) + + const submitBlockMessage = computed(() => { + if (linkedLoading.value) { + return config.labels.verifying + } + return '' }) const guardSubmitOrNotify = () => { if (!isSubmitBlocked.value) { return false } - showError(submitBlockMessage.value || 'Modification bloquée pour cette catégorie.') + showInfo(submitBlockMessage.value || 'Veuillez patienter...') return true } return { linkedCount, linkedLoading, + isRestrictedMode, isSubmitBlocked, + restrictedModeMessage, submitBlockMessage, loadLinkedCount, guardSubmitOrNotify, diff --git a/app/pages/component-category/[id]/edit.vue b/app/pages/component-category/[id]/edit.vue index 567390b..4e0f5af 100644 --- a/app/pages/component-category/[id]/edit.vue +++ b/app/pages/component-category/[id]/edit.vue @@ -28,6 +28,8 @@ :saving="saving" :disable-submit="isSubmitBlocked" :disable-submit-message="submitBlockMessage" + :restricted-mode="isRestrictedMode" + :restricted-mode-message="restrictedModeMessage" @submit="handleSubmit" @cancel="handleCancel" /> @@ -52,7 +54,9 @@ const saving = ref(false) const initialData = ref | null>(null) const { + isRestrictedMode, isSubmitBlocked, + restrictedModeMessage, submitBlockMessage, loadLinkedCount, guardSubmitOrNotify, diff --git a/app/pages/piece-category/[id]/edit.vue b/app/pages/piece-category/[id]/edit.vue index f816c8d..7b17bbc 100644 --- a/app/pages/piece-category/[id]/edit.vue +++ b/app/pages/piece-category/[id]/edit.vue @@ -28,6 +28,8 @@ :saving="saving" :disable-submit="isSubmitBlocked" :disable-submit-message="submitBlockMessage" + :restricted-mode="isRestrictedMode" + :restricted-mode-message="restrictedModeMessage" @submit="handleSubmit" @cancel="handleCancel" /> @@ -52,7 +54,9 @@ const saving = ref(false) const initialData = ref | null>(null) const { + isRestrictedMode, isSubmitBlocked, + restrictedModeMessage, submitBlockMessage, loadLinkedCount, guardSubmitOrNotify, diff --git a/app/pages/product-category/[id]/edit.vue b/app/pages/product-category/[id]/edit.vue index 3707006..687d16d 100644 --- a/app/pages/product-category/[id]/edit.vue +++ b/app/pages/product-category/[id]/edit.vue @@ -28,6 +28,8 @@ :saving="saving" :disable-submit="isSubmitBlocked" :disable-submit-message="submitBlockMessage" + :restricted-mode="isRestrictedMode" + :restricted-mode-message="restrictedModeMessage" @submit="handleSubmit" @cancel="handleCancel" /> @@ -52,7 +54,9 @@ const saving = ref(false) const initialData = ref | null>(null) const { + isRestrictedMode, isSubmitBlocked, + restrictedModeMessage, submitBlockMessage, loadLinkedCount, guardSubmitOrNotify, From 649f8ca9ccb6132578d2c918cd8015f864697886 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Tue, 3 Feb 2026 17:34:33 +0100 Subject: [PATCH 130/274] refacto(F1.1): extract utility modules from machine/[id].vue Extract ~1300 LOC of reusable logic into dedicated modules: - shared/utils/customFieldUtils.ts: field normalization, merge, dedup, display - shared/utils/productDisplayUtils.ts: product resolution and display helpers - composables/useMachineHierarchy.ts: hierarchy tree builder from links - composables/useMachinePrint.ts: print selection and execution logic These extractions prepare the ground for wiring [id].vue to import from these modules instead of inlining all logic. Co-Authored-By: Claude Opus 4.5 --- app/composables/useMachineHierarchy.ts | 292 ++++++++++++++++ app/composables/useMachinePrint.ts | 163 +++++++++ app/shared/utils/customFieldUtils.ts | 426 ++++++++++++++++++++++++ app/shared/utils/productDisplayUtils.ts | 353 ++++++++++++++++++++ 4 files changed, 1234 insertions(+) create mode 100644 app/composables/useMachineHierarchy.ts create mode 100644 app/composables/useMachinePrint.ts create mode 100644 app/shared/utils/customFieldUtils.ts create mode 100644 app/shared/utils/productDisplayUtils.ts diff --git a/app/composables/useMachineHierarchy.ts b/app/composables/useMachineHierarchy.ts new file mode 100644 index 0000000..8d883d1 --- /dev/null +++ b/app/composables/useMachineHierarchy.ts @@ -0,0 +1,292 @@ +/** + * Builds a component/piece hierarchy tree from flat machine link arrays. + * + * Extracted from pages/machine/[id].vue to keep the page orchestrator lean. + */ + +import { resolveIdentifier, resolveProductReference, getProductDisplay } from '~/shared/utils/productDisplayUtils' +import { resolveConstructeurs, uniqueConstructeurIds } from '~/shared/constructeurUtils' + +type AnyRecord = Record + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +const collectConstructeurs = ( + allConstructeurs: AnyRecord[], + ...sources: unknown[] +): AnyRecord[] => { + const ids = uniqueConstructeurIds(...sources) + if (!ids.length) return [] + + const pools = sources + .flatMap((source) => { + if (Array.isArray(source)) return [source] + if (source && typeof source === 'object' && (source as AnyRecord).id) return [[source]] + return [] + }) + .filter(Boolean) as AnyRecord[][] + + return resolveConstructeurs(ids, ...pools, allConstructeurs) +} + +// --------------------------------------------------------------------------- +// Link array resolution +// --------------------------------------------------------------------------- + +export const resolveLinkArray = (source: unknown, keys: string[]): unknown[] | null => { + if (!source || typeof source !== 'object') return null + for (const key of keys) { + const value = (source as AnyRecord)[key] + if (Array.isArray(value)) return value + } + return null +} + +// --------------------------------------------------------------------------- +// Merge trees (for incremental updates) +// --------------------------------------------------------------------------- + +export function mergePieceLists(existing: AnyRecord[] = [], updates: AnyRecord[] = []): AnyRecord[] { + if (!existing.length) { + return updates.map((piece) => ({ ...piece, constructeurs: piece.constructeurs || [] })) + } + if (!updates.length) { + return existing.map((piece) => ({ ...piece, constructeurs: piece.constructeurs || [] })) + } + + const updateMap = new Map( + updates.map((piece) => [piece.id, { ...piece, constructeurs: piece.constructeurs || [] }]), + ) + const merged = existing.map((piece) => { + const update = updateMap.get(piece.id) + if (!update) return piece + return { ...piece, ...update, customFields: update.customFields ?? piece.customFields } + }) + + updates.forEach((update) => { + if (!existing.some((piece) => piece.id === update.id)) merged.push(update) + }) + + return merged +} + +export function mergeComponentTrees(existing: AnyRecord[] = [], updates: AnyRecord[] = []): AnyRecord[] { + if (!existing.length) { + return updates.map((component) => ({ + ...component, + constructeurs: component.constructeurs || [], + pieces: ((component.pieces || []) as AnyRecord[]).map((piece) => ({ + ...piece, + constructeurs: piece.constructeurs || [], + })), + subComponents: mergeComponentTrees([], (component.subComponents || []) as AnyRecord[]), + })) + } + if (!updates.length) return existing + + const updateMap = new Map( + updates.map((component) => [ + component.id, + { + ...component, + constructeurs: component.constructeurs || [], + pieces: ((component.pieces || []) as AnyRecord[]).map((piece) => ({ + ...piece, + constructeurs: piece.constructeurs || [], + })), + subComponents: mergeComponentTrees([], (component.subComponents || []) as AnyRecord[]), + }, + ]), + ) + const merged = existing.map((component) => { + const update = updateMap.get(component.id) + if (!update) { + return { + ...component, + constructeurs: component.constructeurs || [], + pieces: mergePieceLists((component.pieces || []) as AnyRecord[], []), + subComponents: mergeComponentTrees((component.subComponents || []) as AnyRecord[], []), + } + } + return { + ...component, + ...update, + customFields: update.customFields ?? component.customFields, + pieces: mergePieceLists((component.pieces || []) as AnyRecord[], (update.pieces || []) as AnyRecord[]), + subComponents: mergeComponentTrees( + (component.subComponents || []) as AnyRecord[], + (update.subComponents || []) as AnyRecord[], + ), + } + }) + + updates.forEach((update) => { + if (!existing.some((component) => component.id === update.id)) merged.push(update) + }) + + return merged +} + +// --------------------------------------------------------------------------- +// Build hierarchy from links +// --------------------------------------------------------------------------- + +export const buildMachineHierarchyFromLinks = ( + componentLinks: AnyRecord[] = [], + pieceLinks: AnyRecord[] = [], + findProductById: (id: string) => AnyRecord | null, + allConstructeurs: AnyRecord[] = [], +): { components: AnyRecord[]; machinePieces: AnyRecord[] } => { + const normalizeComponentLinkId = (link: AnyRecord) => + resolveIdentifier(link?.id, link?.linkId, link?.machineComponentLinkId) + + const normalizePieceLinkId = (link: AnyRecord) => + resolveIdentifier(link?.id, link?.linkId, link?.machinePieceLinkId) + + const createPieceNode = (link: AnyRecord, parentComponentName: string | null = null): AnyRecord | null => { + if (!link || typeof link !== 'object') return null + + const appliedPiece = (link.piece && typeof link.piece === 'object' ? link.piece : {}) as AnyRecord + const originalPiece = (link.originalPiece && typeof link.originalPiece === 'object' ? link.originalPiece : null) as AnyRecord | null + + const requirement = (link.typeMachinePieceRequirement || appliedPiece.typeMachinePieceRequirement || originalPiece?.typeMachinePieceRequirement || null) as AnyRecord | null + + const machinePieceLinkId = normalizePieceLinkId(link) + const pieceId = resolveIdentifier(appliedPiece.id, appliedPiece.pieceId, link.pieceId) + + const basePiece: AnyRecord = { + ...appliedPiece, + id: appliedPiece.id || pieceId || machinePieceLinkId || `piece-${machinePieceLinkId}`, + pieceId, + name: link.overrides?.name || appliedPiece.name || (appliedPiece.definition as AnyRecord)?.name || (appliedPiece.definition as AnyRecord)?.role || originalPiece?.name || 'Pièce', + reference: link.overrides?.reference || appliedPiece.reference || (appliedPiece.definition as AnyRecord)?.reference || originalPiece?.reference || null, + prix: link.overrides?.prix ?? appliedPiece.prix ?? originalPiece?.prix ?? null, + constructeur: appliedPiece.constructeur || originalPiece?.constructeur || null, + constructeurId: appliedPiece.constructeurId || (appliedPiece.constructeur as AnyRecord)?.id || originalPiece?.constructeurId || null, + documents: Array.isArray(appliedPiece.documents) ? appliedPiece.documents : Array.isArray(originalPiece?.documents) ? originalPiece!.documents : [], + typePiece: appliedPiece.typePiece || requirement?.typePiece || null, + typePieceId: appliedPiece.typePieceId || (appliedPiece.typePiece as AnyRecord)?.id || requirement?.typePieceId || (requirement?.typePiece as AnyRecord)?.id || null, + typeMachinePieceRequirement: requirement, + typeMachinePieceRequirementId: requirement?.id || null, + requirementId: requirement?.id || null, + overrides: link.overrides || null, + originalPiece, + machinePieceLink: link, + machinePieceLinkId, + linkId: machinePieceLinkId, + parentComponentLinkId: resolveIdentifier(link.parentComponentLinkId, link.parentLinkId, link.parentMachineComponentLinkId, appliedPiece.parentComponentLinkId), + parentComponentId: resolveIdentifier(appliedPiece.parentComponentId, link.parentComponentId), + parentComponentName, + parentLinkId: resolveIdentifier(link.parentLinkId, link.parentMachinePieceLinkId, appliedPiece.parentLinkId), + parentPieceLinkId: resolveIdentifier(link.parentPieceLinkId, appliedPiece.parentPieceLinkId), + parentPieceId: resolveIdentifier(appliedPiece.parentPieceId, link.parentPieceId), + parentMachineComponentRequirementId: resolveIdentifier(appliedPiece.parentMachineComponentRequirementId, link.parentMachineComponentRequirementId), + parentMachinePieceRequirementId: resolveIdentifier(appliedPiece.parentMachinePieceRequirementId, link.parentMachinePieceRequirementId), + definition: appliedPiece.definition || originalPiece?.definition || {}, + customFields: appliedPiece.customFields || [], + skeletonOnly: !pieceId, + } + + const resolvedProductId = resolveIdentifier(appliedPiece.productId, (appliedPiece.product as AnyRecord)?.id, link.productId, (link.product as AnyRecord)?.id, originalPiece?.productId, (originalPiece?.product as AnyRecord)?.id) + const resolvedProduct = (appliedPiece.product || link.product || originalPiece?.product || (resolvedProductId ? findProductById(resolvedProductId) : null) || null) as AnyRecord | null + + const constructeurs = collectConstructeurs(allConstructeurs, appliedPiece.constructeurs, appliedPiece.constructeur, appliedPiece.constructeurIds, appliedPiece.constructeurId, originalPiece?.constructeurs, originalPiece?.constructeur, originalPiece?.constructeurIds, originalPiece?.constructeurId) + + return { + ...basePiece, + constructeurs, + constructeur: constructeurs[0] || basePiece.constructeur || null, + constructeurId: (constructeurs[0] as AnyRecord)?.id || basePiece.constructeurId || null, + productId: resolvedProductId || appliedPiece.productId || null, + product: resolvedProduct || appliedPiece.product || null, + __productDisplay: getProductDisplay({ product: resolvedProduct || appliedPiece.product || null, productId: resolvedProductId || appliedPiece.productId || null } as AnyRecord, findProductById), + } + } + + const createComponentNode = (link: AnyRecord): AnyRecord | null => { + if (!link || typeof link !== 'object') return null + + const appliedComponent = (link.composant && typeof link.composant === 'object' ? link.composant : {}) as AnyRecord + const originalComponent = (link.originalComposant && typeof link.originalComposant === 'object' ? link.originalComposant : null) as AnyRecord | null + + const requirement = (link.typeMachineComponentRequirement || appliedComponent.typeMachineComponentRequirement || originalComponent?.typeMachineComponentRequirement || null) as AnyRecord | null + + const machineComponentLinkId = normalizeComponentLinkId(link) + const composantId = resolveIdentifier(appliedComponent.id, appliedComponent.composantId, link.composantId) + + const componentName = (link.overrides?.name || appliedComponent.name || (appliedComponent.definition as AnyRecord)?.alias || (appliedComponent.definition as AnyRecord)?.name || originalComponent?.name || 'Composant') as string + + const pieces = Array.isArray(link.pieceLinks) + ? (link.pieceLinks as AnyRecord[]).map((pl) => createPieceNode(pl, componentName)).filter(Boolean) as AnyRecord[] + : [] + + const subComponents = Array.isArray(link.childLinks) + ? (link.childLinks as AnyRecord[]).map(createComponentNode).filter(Boolean) as AnyRecord[] + : [] + + const resolvedProductId = resolveIdentifier(appliedComponent.productId, (appliedComponent.product as AnyRecord)?.id, link.productId, (link.product as AnyRecord)?.id, originalComponent?.productId, (originalComponent?.product as AnyRecord)?.id) + const resolvedProduct = (appliedComponent.product || link.product || originalComponent?.product || (resolvedProductId ? findProductById(resolvedProductId) : null) || null) as AnyRecord | null + + const baseComponent: AnyRecord = { + ...appliedComponent, + id: appliedComponent.id || composantId || machineComponentLinkId || `component-${machineComponentLinkId}`, + composantId, + name: componentName, + reference: link.overrides?.reference || appliedComponent.reference || (appliedComponent.definition as AnyRecord)?.reference || originalComponent?.reference || null, + prix: link.overrides?.prix ?? appliedComponent.prix ?? originalComponent?.prix ?? null, + constructeur: appliedComponent.constructeur || originalComponent?.constructeur || null, + constructeurId: appliedComponent.constructeurId || (appliedComponent.constructeur as AnyRecord)?.id || originalComponent?.constructeurId || null, + documents: Array.isArray(appliedComponent.documents) ? appliedComponent.documents : Array.isArray(originalComponent?.documents) ? originalComponent!.documents : [], + typeComposant: appliedComponent.typeComposant || requirement?.typeComposant || null, + typeComposantId: appliedComponent.typeComposantId || (appliedComponent.typeComposant as AnyRecord)?.id || requirement?.typeComposantId || (requirement?.typeComposant as AnyRecord)?.id || null, + typeMachineComponentRequirement: requirement, + typeMachineComponentRequirementId: requirement?.id || null, + requirementId: requirement?.id || null, + overrides: link.overrides || null, + machineComponentLinkOverrides: link.overrides || null, + definitionOverrides: link.overrides || null, + originalComposant: originalComponent, + machineComponentLink: link, + machineComponentLinkId, + componentLinkId: machineComponentLinkId, + parentComponentLinkId: resolveIdentifier(link.parentComponentLinkId, link.parentLinkId, link.parentMachineComponentLinkId, appliedComponent.parentComponentLinkId), + parentComposantId: resolveIdentifier(appliedComponent.parentComposantId, link.parentComponentId), + parentRequirementId: resolveIdentifier(appliedComponent.parentRequirementId, link.parentRequirementId), + parentMachineComponentRequirementId: resolveIdentifier(appliedComponent.parentMachineComponentRequirementId, link.parentMachineComponentRequirementId), + parentMachinePieceRequirementId: resolveIdentifier(appliedComponent.parentMachinePieceRequirementId, link.parentMachinePieceRequirementId), + definition: appliedComponent.definition || originalComponent?.definition || {}, + customFields: appliedComponent.customFields || [], + pieces, + subComponents, + subcomponents: subComponents, + sousComposants: subComponents, + skeletonOnly: !composantId, + } + + const constructeurs = collectConstructeurs(allConstructeurs, appliedComponent.constructeurs, appliedComponent.constructeur, appliedComponent.constructeurIds, appliedComponent.constructeurId, originalComponent?.constructeurs, originalComponent?.constructeur, originalComponent?.constructeurIds, originalComponent?.constructeurId) + + return { + ...baseComponent, + constructeurs, + constructeur: constructeurs[0] || baseComponent.constructeur || null, + constructeurId: (constructeurs[0] as AnyRecord)?.id || baseComponent.constructeurId || null, + productId: resolvedProductId || appliedComponent.productId || null, + product: resolvedProduct || appliedComponent.product || null, + __productDisplay: getProductDisplay({ product: resolvedProduct || appliedComponent.product || null, productId: resolvedProductId || appliedComponent.productId || null } as AnyRecord, findProductById), + } + } + + const rootComponents = (Array.isArray(componentLinks) ? componentLinks : []) + .filter((link) => !resolveIdentifier(link?.parentComponentLinkId, link?.parentLinkId, link?.parentMachineComponentLinkId)) + .map(createComponentNode) + .filter(Boolean) as AnyRecord[] + + const machinePieces = (Array.isArray(pieceLinks) ? pieceLinks : []) + .filter((link) => !resolveIdentifier(link?.parentComponentLinkId, link?.parentLinkId, link?.parentMachineComponentLinkId)) + .map((link) => createPieceNode(link, null)) + .filter(Boolean) as AnyRecord[] + + return { components: rootComponents, machinePieces } +} diff --git a/app/composables/useMachinePrint.ts b/app/composables/useMachinePrint.ts new file mode 100644 index 0000000..cd9252b --- /dev/null +++ b/app/composables/useMachinePrint.ts @@ -0,0 +1,163 @@ +/** + * Machine print selection and execution logic. + * + * Extracted from pages/machine/[id].vue. + */ + +import { ref, reactive, nextTick } from 'vue' +import { buildMachinePrintContext, buildMachinePrintHtml } from '~/utils/printTemplates/machineReport' +import { resolveIdentifier } from '~/shared/utils/productDisplayUtils' + +type AnyRecord = Record + +export interface PrintSelection { + machine: { info: boolean; customFields: boolean; documents: boolean } + components: Record + pieces: Record +} + +export function useMachinePrint() { + const printModalOpen = ref(false) + const printSelection = reactive({ + machine: { info: true, customFields: true, documents: true }, + components: {}, + pieces: {}, + }) + + const ensurePrintSelectionEntries = ( + components: AnyRecord[], + machinePieces: AnyRecord[], + ) => { + printSelection.machine.info ??= true + printSelection.machine.customFields ??= true + printSelection.machine.documents ??= true + + const ensureComponent = (component: AnyRecord) => { + if (component?.id !== undefined && printSelection.components[component.id as string] === undefined) { + printSelection.components[component.id as string] = true + } + ;((component.pieces || []) as AnyRecord[]).forEach((piece) => { + if (piece?.id !== undefined && printSelection.pieces[piece.id as string] === undefined) { + printSelection.pieces[piece.id as string] = true + } + }) + ;((component.subComponents || []) as AnyRecord[]).forEach(ensureComponent) + } + + components.forEach(ensureComponent) + machinePieces.forEach((piece) => { + if (piece?.id !== undefined && printSelection.pieces[piece.id as string] === undefined) { + printSelection.pieces[piece.id as string] = true + } + }) + } + + const setAllPrintSelection = ( + value: boolean, + components: AnyRecord[], + machinePieces: AnyRecord[], + ) => { + ensurePrintSelectionEntries(components, machinePieces) + printSelection.machine.info = value + printSelection.machine.customFields = value + printSelection.machine.documents = value + Object.keys(printSelection.components).forEach((key) => { + printSelection.components[key] = value + }) + Object.keys(printSelection.pieces).forEach((key) => { + printSelection.pieces[key] = value + }) + } + + const openPrintModal = (components: AnyRecord[], machinePieces: AnyRecord[]) => { + ensurePrintSelectionEntries(components, machinePieces) + printModalOpen.value = true + } + + const closePrintModal = () => { + printModalOpen.value = false + } + + const printMachine = ( + machine: AnyRecord, + machineName: string, + machineReference: string, + machinePieces: AnyRecord[], + components: AnyRecord[], + currentSelection: PrintSelection = printSelection, + ) => { + if (typeof window === 'undefined') return + + const context = buildMachinePrintContext({ + machine, + machineName, + machineReference, + machinePieces, + components, + selection: currentSelection, + }) + const styles = Array.from(document.querySelectorAll('link[rel="stylesheet"], style')) + .map((node) => node.outerHTML) + .join('') + + const htmlContent = buildMachinePrintHtml(context, styles) + + const iframe = document.createElement('iframe') + iframe.style.position = 'fixed' + iframe.style.right = '0' + iframe.style.bottom = '0' + iframe.style.width = '0' + iframe.style.height = '0' + iframe.style.border = '0' + iframe.setAttribute('title', 'print-frame') + document.body.appendChild(iframe) + + const iframeWindow = iframe.contentWindow + const iframeDocument = iframe.contentDocument || iframeWindow?.document + if (!iframeDocument || !iframeWindow) { + iframe.remove() + return + } + + iframeDocument.open() + iframeDocument.write(htmlContent) + iframeDocument.close() + + const triggerPrint = () => { + iframeWindow.focus() + iframeWindow.print() + setTimeout(() => { + iframe.remove() + }, 1000) + } + + if (iframeDocument.readyState === 'complete') { + setTimeout(triggerPrint, 50) + } else { + iframe.onload = () => setTimeout(triggerPrint, 50) + } + } + + const handlePrintConfirm = async ( + machine: AnyRecord, + machineName: string, + machineReference: string, + machinePieces: AnyRecord[], + components: AnyRecord[], + ) => { + closePrintModal() + await nextTick() + printMachine(machine, machineName, machineReference, machinePieces, components, printSelection) + } + + return { + printModalOpen, + printSelection, + ensurePrintSelectionEntries, + setAllPrintSelection, + openPrintModal, + closePrintModal, + printMachine, + handlePrintConfirm, + } +} diff --git a/app/shared/utils/customFieldUtils.ts b/app/shared/utils/customFieldUtils.ts new file mode 100644 index 0000000..7500edc --- /dev/null +++ b/app/shared/utils/customFieldUtils.ts @@ -0,0 +1,426 @@ +/** + * Custom field normalization, merging and display utilities. + * + * Extracted from pages/machine/[id].vue to be reusable across + * machine detail, component, piece and product views. + */ + +// --------------------------------------------------------------------------- +// Primitive helpers +// --------------------------------------------------------------------------- + +export const coerceValueForType = (type: string, rawValue: unknown): string => { + if (rawValue === undefined || rawValue === null || rawValue === '') { + return '' + } + if (type === 'boolean') { + const normalized = String(rawValue).toLowerCase() + if (normalized === 'true' || normalized === '1') return 'true' + if (normalized === 'false' || normalized === '0') return 'false' + return '' + } + return String(rawValue) +} + +export const formatCustomFieldValue = (field: Record | null | undefined): string => { + if (!field) return 'Non défini' + + const value = (field.value ?? field.defaultValue ?? '') as string + if (value === '' || value === null || value === undefined) return 'Non défini' + + if (field.type === 'boolean') { + const normalized = String(value).toLowerCase() + if (normalized === 'true' || normalized === '1') return 'Oui' + if (normalized === 'false' || normalized === '0') return 'Non' + } + + return String(value) +} + +export const shouldDisplayCustomField = (field: Record | null | undefined): boolean => { + if (!field) return false + if (field.readOnly) return true + if (field.type === 'boolean') return field.value !== undefined && field.value !== null + + const value = field.value + if (value === null || value === undefined) return false + if (typeof value === 'string') return value.trim().length > 0 + return true +} + +// --------------------------------------------------------------------------- +// Definition extraction helpers +// --------------------------------------------------------------------------- + +export const extractDefinitionName = (definition: Record = {}): string => { + if (typeof definition?.name === 'string' && (definition.name as string).trim()) { + return (definition.name as string).trim() + } + if (typeof definition?.key === 'string' && (definition.key as string).trim()) { + return (definition.key as string).trim() + } + if (typeof definition?.label === 'string' && (definition.label as string).trim()) { + return (definition.label as string).trim() + } + return '' +} + +export const extractDefinitionType = ( + definition: Record = {}, + fallback = 'text', +): string => { + const allowed = ['text', 'number', 'select', 'boolean', 'date'] + const rawType = + typeof definition?.type === 'string' + ? definition.type + : typeof (definition?.value as Record)?.type === 'string' + ? (definition.value as Record).type as string + : typeof fallback === 'string' + ? fallback + : 'text' + const normalized = (rawType as string).toLowerCase() + return allowed.includes(normalized) ? normalized : 'text' +} + +export const extractDefinitionRequired = ( + definition: Record = {}, + fallback = false, +): boolean => { + if (typeof definition?.required === 'boolean') return definition.required + const nested = (definition?.value as Record)?.required + if (typeof nested === 'boolean') return nested + if (typeof nested === 'string') { + const normalized = nested.toLowerCase() + if (normalized === 'true' || normalized === '1') return true + if (normalized === 'false' || normalized === '0') return false + } + return !!fallback +} + +const extractOptionList = (input: unknown): string[] | undefined => { + if (!Array.isArray(input)) return undefined + const mapped = input + .map((option) => { + if (option === null || option === undefined) return '' + if (typeof option === 'string') return option.trim() + if (typeof option === 'object') { + const record = (option || {}) as Record + for (const key of ['value', 'label', 'name']) { + const candidate = record[key] + if (typeof candidate === 'string' && candidate.trim().length > 0) return candidate.trim() + } + } + const fallback = String(option).trim() + return fallback === '[object Object]' ? '' : fallback + }) + .filter((option) => option.length > 0) + return mapped.length ? mapped : undefined +} + +export const extractDefinitionOptions = (definition: Record = {}): string[] => { + const sources = [ + definition?.options, + (definition?.value as Record)?.options, + (definition?.value as Record)?.choices, + ] + for (const source of sources) { + const list = extractOptionList(source) + if (list) return list + } + return [] +} + +export const extractDefinitionDefaultValue = (definition: Record = {}): unknown => { + const candidates = [ + definition?.defaultValue, + (definition?.value as Record)?.defaultValue, + (definition?.value as Record)?.value, + definition?.value, + definition?.default, + ] + for (const candidate of candidates) { + if (candidate === undefined || candidate === null || candidate === '') continue + if (typeof candidate === 'object') { + if (candidate === null) continue + const nestedDefault = + (candidate as Record).defaultValue !== undefined && + (candidate as Record).defaultValue !== null + ? (candidate as Record).defaultValue + : (candidate as Record).value + if (nestedDefault !== undefined && nestedDefault !== null && nestedDefault !== '') { + return nestedDefault + } + continue + } + return candidate + } + return undefined +} + +// --------------------------------------------------------------------------- +// Normalization +// --------------------------------------------------------------------------- + +export interface NormalizedCustomFieldDefinition { + id?: string + customFieldId?: string + name: string + type: string + required: boolean + options: string[] + defaultValue?: unknown + readOnly: boolean + orderIndex: number +} + +export const normalizeCustomFieldDefinitionEntry = ( + definition: Record = {}, + fallbackIndex = 0, +): NormalizedCustomFieldDefinition | null => { + const name = extractDefinitionName(definition) + if (!name) return null + const type = extractDefinitionType(definition) + const required = extractDefinitionRequired(definition) + const options = extractDefinitionOptions(definition) + const defaultValue = extractDefinitionDefaultValue(definition) + const id = typeof definition?.id === 'string' ? definition.id : undefined + const customFieldId = typeof definition?.customFieldId === 'string' ? definition.customFieldId : id + const orderIndex = typeof definition?.orderIndex === 'number' ? definition.orderIndex : fallbackIndex + return { id, customFieldId, name, type, required, options, defaultValue, readOnly: !!definition?.readOnly, orderIndex } +} + +export const normalizeExistingCustomFieldDefinitions = ( + fields: unknown, +): NormalizedCustomFieldDefinition[] => { + if (!Array.isArray(fields)) return [] + return fields + .map((field, index) => normalizeCustomFieldDefinitionEntry(field as Record, index)) + .filter((d): d is NormalizedCustomFieldDefinition => d !== null) + .sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)) +} + +// --------------------------------------------------------------------------- +// Custom field value normalization +// --------------------------------------------------------------------------- + +export const normalizeCustomFieldValueEntry = (entry: Record = {}): Record | null => { + if (!entry || typeof entry !== 'object') return null + const normalizedDefinition = normalizeCustomFieldDefinitionEntry(entry) + if (!normalizedDefinition) return null + + const value = coerceValueForType( + normalizedDefinition.type, + (entry?.value ?? entry?.defaultValue ?? normalizedDefinition.defaultValue ?? '') as string, + ) + + return { + id: (entry?.customFieldValueId ?? entry?.id ?? null) as string | null, + customFieldId: + (entry?.customFieldId ?? normalizedDefinition.customFieldId ?? normalizedDefinition.id ?? null) as string | null, + customField: { + id: normalizedDefinition.id ?? normalizedDefinition.customFieldId ?? null, + name: normalizedDefinition.name, + type: normalizedDefinition.type, + required: normalizedDefinition.required, + options: normalizedDefinition.options, + defaultValue: normalizedDefinition.defaultValue ?? '', + }, + value, + } +} + +// --------------------------------------------------------------------------- +// Merge & dedup +// --------------------------------------------------------------------------- + +export const mergeCustomFieldValuesWithDefinitions = ( + valueEntries: Record[] = [], + ...definitionSources: unknown[][] +): Record[] => { + const normalizedValues = (Array.isArray(valueEntries) ? valueEntries : []) + .map((entry) => { + if (!entry || typeof entry !== 'object') return null + const normalizedDefinition = normalizeCustomFieldDefinitionEntry( + ((entry as Record).customField || entry) as Record, + ) + if (!normalizedDefinition) return null + + const value = coerceValueForType( + normalizedDefinition.type, + ((entry as Record)?.value ?? + (entry as Record)?.defaultValue ?? + normalizedDefinition.defaultValue ?? + '') as string, + ) + + return { + customFieldValueId: (entry as Record)?.id ?? (entry as Record)?.customFieldValueId ?? null, + id: normalizedDefinition.id, + customFieldId: normalizedDefinition.customFieldId ?? normalizedDefinition.id ?? null, + name: normalizedDefinition.name, + type: normalizedDefinition.type, + required: normalizedDefinition.required, + options: normalizedDefinition.options, + optionsText: normalizedDefinition.options?.length ? normalizedDefinition.options.join('\n') : '', + defaultValue: normalizedDefinition.defaultValue ?? '', + value, + readOnly: !!(entry as Record)?.readOnly, + } + }) + .filter((entry): entry is Record => entry !== null) + + const result = [...normalizedValues] + const keyFor = (item: Record) => (item?.id as string) ?? `${item?.name ?? ''}::${item?.type ?? ''}` + const existingMap = new Map>() + + result.forEach((item) => { + const key = keyFor(item) + if (key) existingMap.set(key, item) + const fallbackKey = item?.name ? `${item.name}::${item.type ?? ''}` : null + if (fallbackKey) existingMap.set(fallbackKey, item) + }) + + const definitions = definitionSources + .flatMap((source) => (Array.isArray(source) ? source : [])) + .map((definition) => normalizeCustomFieldDefinitionEntry(definition as Record)) + .filter((d): d is NormalizedCustomFieldDefinition => d !== null) + + definitions.forEach((normalizedDefinition) => { + const key = normalizedDefinition.id ?? `${normalizedDefinition.name}::${normalizedDefinition.type}` + if (!key) return + + if (normalizedDefinition.id) { + const fallbackKey = `${normalizedDefinition.name}::${normalizedDefinition.type}` + if (existingMap.has(fallbackKey)) { + const existingFallback = existingMap.get(fallbackKey) + if (existingFallback) { + existingFallback.id = existingFallback.id || normalizedDefinition.id + existingFallback.customFieldId = normalizedDefinition.id + existingFallback.readOnly = (existingFallback.readOnly as boolean) && normalizedDefinition.readOnly + existingMap.delete(fallbackKey) + existingMap.set(normalizedDefinition.id, existingFallback) + existingMap.set(fallbackKey, existingFallback) + return + } + } + } + + const existing = + existingMap.get(key) || + (normalizedDefinition.name ? existingMap.get(`${normalizedDefinition.name}::${normalizedDefinition.type}`) : null) + + if (existing) { + existing.name = existing.name || normalizedDefinition.name + existing.type = existing.type || normalizedDefinition.type + existing.required = (existing.required as boolean) || normalizedDefinition.required + if (!(existing.options as string[])?.length && normalizedDefinition.options?.length) { + existing.options = normalizedDefinition.options + } + if (!existing.defaultValue && normalizedDefinition.defaultValue) { + existing.defaultValue = String(normalizedDefinition.defaultValue) + if (!existing.value) { + existing.value = coerceValueForType(existing.type as string, normalizedDefinition.defaultValue) + } + } + existing.customFieldId = existing.customFieldId || normalizedDefinition.id + existing.readOnly = (existing.readOnly as boolean) && normalizedDefinition.readOnly + if (!existing.optionsText && normalizedDefinition.options?.length) { + existing.optionsText = normalizedDefinition.options.join('\n') + } + if (normalizedDefinition.id) existingMap.set(normalizedDefinition.id, existing) + if (normalizedDefinition.name) { + existingMap.set(`${normalizedDefinition.name}::${normalizedDefinition.type}`, existing) + } + return + } + + const entry: Record = { + customFieldValueId: null, + id: normalizedDefinition.id, + customFieldId: normalizedDefinition.id, + name: normalizedDefinition.name, + type: normalizedDefinition.type, + required: normalizedDefinition.required, + options: normalizedDefinition.options, + optionsText: normalizedDefinition.options?.length ? normalizedDefinition.options.join('\n') : '', + defaultValue: normalizedDefinition.defaultValue ?? '', + value: coerceValueForType(normalizedDefinition.type, (normalizedDefinition.defaultValue ?? '') as string), + readOnly: false, + } + result.push(entry) + existingMap.set(key, entry) + const fallbackKey = entry.name ? `${entry.name}::${entry.type}` : null + if (fallbackKey) existingMap.set(fallbackKey, entry) + }) + + return result +} + +export const dedupeCustomFieldEntries = (fields: Record[]): Record[] => { + if (!Array.isArray(fields) || fields.length <= 1) { + return Array.isArray(fields) ? fields : [] + } + + const seen = new Set() + const result: Record[] = [] + + for (const field of fields) { + if (!field) continue + + field.type = field.type || 'text' + + let normalizedName = typeof field.name === 'string' ? (field.name as string).trim() : '' + + if (!normalizedName && (field.customField as Record)?.name) { + normalizedName = String((field.customField as Record).name).trim() + field.name = normalizedName + } else if (typeof field.name === 'string') { + field.name = normalizedName + } + + const key = + (field.customFieldId as string) || + (field.id as string) || + (normalizedName ? `${normalizedName}::${field.type || 'text'}` : null) + + if (!key && !normalizedName) continue + if (key && seen.has(key)) continue + if (!normalizedName) continue + + if (key) seen.add(key) + if (normalizedName) seen.add(`${normalizedName}::${field.type || 'text'}`) + result.push(field) + } + + return result +} + +// --------------------------------------------------------------------------- +// Summarize for display +// --------------------------------------------------------------------------- + +export const summarizeCustomFields = ( + fields: Record[] = [], +): { key: string; label: string; value: string }[] => { + const seen = new Set() + return fields + .slice() + .sort((a, b) => { + const left = typeof a?.orderIndex === 'number' ? a.orderIndex : 0 + const right = typeof b?.orderIndex === 'number' ? b.orderIndex : 0 + return (left as number) - (right as number) + }) + .filter(shouldDisplayCustomField) + .filter((field) => { + const key = (field.customFieldId || field.id || field.name) as string + if (!key) return true + if (seen.has(key)) return false + seen.add(key) + return true + }) + .map((field, index) => ({ + key: ((field.customFieldId || field.id || field.name) as string) || `custom-field-${index}`, + label: (field.name as string) || 'Champ', + value: formatCustomFieldValue(field), + })) +} diff --git a/app/shared/utils/productDisplayUtils.ts b/app/shared/utils/productDisplayUtils.ts new file mode 100644 index 0000000..433e61e --- /dev/null +++ b/app/shared/utils/productDisplayUtils.ts @@ -0,0 +1,353 @@ +/** + * Product resolution and display utilities. + * + * Extracted from pages/machine/[id].vue – these functions resolve product + * references from deeply nested API payloads and build display objects. + */ + +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + +export interface ProductDisplay { + name: string + reference: string | null + category: string | null + suppliers: string | null + price: string | null +} + +type AnyRecord = Record + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +const isPlainObject = (value: unknown): value is AnyRecord => + Object.prototype.toString.call(value) === '[object Object]' + +export const resolveIdentifier = (...candidates: unknown[]): string | null => { + for (const candidate of candidates) { + if (candidate !== undefined && candidate !== null && candidate !== '') { + return candidate as string + } + } + return null +} + +// --------------------------------------------------------------------------- +// Supplier / price labels +// --------------------------------------------------------------------------- + +export const getProductSuppliersLabel = (product: AnyRecord | null): string | null => { + if (!product) return null + const suppliers = Array.isArray(product.constructeurs) + ? (product.constructeurs as AnyRecord[]).map((c) => c?.name as string).filter(Boolean) + : [] + return suppliers.length > 0 ? suppliers.join(', ') : null +} + +export const getProductPriceLabel = (product: AnyRecord | null): string | null => { + if (!product) return null + const priceValue = + (product.supplierPrice ?? product.prix ?? product.price ?? null) as string | number | null + if (priceValue === undefined || priceValue === null) return null + const numeric = Number(priceValue) + if (Number.isNaN(numeric)) return null + return `${numeric.toFixed(2)} €` +} + +// --------------------------------------------------------------------------- +// resolveProductReference +// --------------------------------------------------------------------------- + +export const resolveProductReference = ( + source: AnyRecord | null | undefined, + findProductById: (id: string) => AnyRecord | null, +): { product: AnyRecord | null; productId: string | null } => { + if (!source || typeof source !== 'object') { + return { product: null, productId: null } + } + + const candidateKeys: (string | null)[] = [ + null, + 'productLink', + 'machinePieceLink', + 'machineComponentLink', + 'machineProductLink', + 'originalPiece', + 'originalComposant', + 'link', + 'overrides', + 'machineComponentLinkOverrides', + 'requirement', + 'selection', + 'entry', + ] + + let product: AnyRecord | null = null + let productId: string | null = null + + const inspect = (container: unknown) => { + if (!container || typeof container !== 'object') return + const c = container as AnyRecord + if (!product && c.product && typeof c.product === 'object') { + product = c.product as AnyRecord + } + if (!productId) { + const candidate = + (c.productId as string) || + (c.product && typeof c.product === 'object' + ? ((c.product as AnyRecord).id as string) || ((c.product as AnyRecord).productId as string) + : null) || + null + if (candidate) productId = candidate + } + } + + candidateKeys.forEach((key) => { + if (key === null) inspect(source) + else inspect((source as AnyRecord)[key]) + }) + + if (!product && productId) { + product = findProductById(productId) || null + } + + if (!product && !productId && source.productName) { + const suppliersLabel = + typeof source.constructeursLabel === 'string' + ? source.constructeursLabel + : typeof source.productSuppliers === 'string' + ? source.productSuppliers + : null + + return { + product: { + name: source.productName, + reference: source.productReference || null, + typeProduct: source.productCategory ? { name: source.productCategory } : null, + constructeurs: suppliersLabel + ? (suppliersLabel as string) + .split(',') + .map((name: string) => name.trim()) + .filter((name: string) => name.length > 0) + .map((name: string) => ({ name })) + : undefined, + supplierPrice: source.productPrice ?? source.productPriceLabel ?? source.price ?? null, + } as AnyRecord, + productId: null, + } + } + + if (productId && product && product.id && product.id !== productId) { + const resolved = findProductById(productId) + if (resolved) product = resolved + } + + return { product: product || null, productId: productId || null } +} + +// --------------------------------------------------------------------------- +// getProductDisplay +// --------------------------------------------------------------------------- + +export const getProductDisplay = ( + source: AnyRecord | null | undefined, + findProductById: (id: string) => AnyRecord | null, +): ProductDisplay | null => { + if (!source || typeof source !== 'object') return null + + const { product, productId } = resolveProductReference(source, findProductById) + + if (product) { + return { + name: (product.name as string) || (product.reference as string) || 'Produit catalogue', + reference: (product.reference as string) || null, + category: (product.typeProduct as AnyRecord)?.name as string || null, + suppliers: getProductSuppliersLabel(product), + price: getProductPriceLabel(product), + } + } + + let fallbackName = + (source.productName || + source.productLabel || + source.typeProductLabel || + (source.typeProduct as AnyRecord)?.name || + (productId ? `Produit ${productId}` : null)) as string | null + let fallbackReference = (source.productReference || source.reference || null) as string | null + let fallbackCategory = + (source.productCategory || + source.typeProductLabel || + (source.typeProduct as AnyRecord)?.name || + null) as string | null + let fallbackSuppliers = + (source.productSuppliers || + source.constructeursLabel || + source.supplierLabel || + null) as string | null + let fallbackPrice = + (source.productPriceLabel || + source.productPrice || + source.priceLabel || + source.price || + null) as string | number | null + + const structuralCandidates = [ + source.products, + source.productSkeleton, + (source.definition as AnyRecord)?.products, + (source.definition as AnyRecord)?.productSkeleton, + ((source.definition as AnyRecord)?.structure as AnyRecord)?.products, + ((source.definition as AnyRecord)?.structure as AnyRecord)?.productSkeleton, + (source.structure as AnyRecord)?.products, + (source.structure as AnyRecord)?.productSkeleton, + (source.requirement as AnyRecord)?.products, + (source.requirement as AnyRecord)?.productSkeleton, + ((source.requirement as AnyRecord)?.structure as AnyRecord)?.products, + ((source.requirement as AnyRecord)?.structure as AnyRecord)?.productSkeleton, + ((source.requirement as AnyRecord)?.componentSkeleton as AnyRecord)?.products, + (source.typeMachineComponentRequirement as AnyRecord)?.products, + (source.typeMachineComponentRequirement as AnyRecord)?.productSkeleton, + ((source.typeMachineComponentRequirement as AnyRecord)?.structure as AnyRecord)?.products, + ((source.typeMachineComponentRequirement as AnyRecord)?.structure as AnyRecord)?.productSkeleton, + ((source.typeMachineComponentRequirement as AnyRecord)?.componentSkeleton as AnyRecord)?.products, + (source.typeComposant as AnyRecord)?.products, + (source.typeComposant as AnyRecord)?.productSkeleton, + ((source.typeComposant as AnyRecord)?.structure as AnyRecord)?.products, + ((source.typeComposant as AnyRecord)?.structure as AnyRecord)?.productSkeleton, + (source.originalComposant as AnyRecord)?.products, + (source.originalComposant as AnyRecord)?.productSkeleton, + ((source.originalComposant as AnyRecord)?.definition as AnyRecord)?.products, + ((source.originalComposant as AnyRecord)?.definition as AnyRecord)?.productSkeleton, + (((source.originalComposant as AnyRecord)?.definition as AnyRecord)?.structure as AnyRecord)?.products, + (((source.originalComposant as AnyRecord)?.definition as AnyRecord)?.structure as AnyRecord)?.productSkeleton, + (source.originalComponent as AnyRecord)?.products, + (source.originalComponent as AnyRecord)?.productSkeleton, + ((source.originalComponent as AnyRecord)?.definition as AnyRecord)?.products, + ((source.originalComponent as AnyRecord)?.definition as AnyRecord)?.productSkeleton, + (((source.originalComponent as AnyRecord)?.definition as AnyRecord)?.structure as AnyRecord)?.products, + (((source.originalComponent as AnyRecord)?.definition as AnyRecord)?.structure as AnyRecord)?.productSkeleton, + ] + + const structuralProducts = structuralCandidates + .flatMap((candidate) => { + if (Array.isArray(candidate)) return candidate + if (candidate && typeof candidate === 'object' && Array.isArray((candidate as AnyRecord).products)) { + return (candidate as AnyRecord).products as unknown[] + } + return [] + }) + .filter((entry) => entry && typeof entry === 'object') + + const structuralProduct = structuralProducts.length ? (structuralProducts[0] as AnyRecord) : null + + const structuralFamilyCode = + (structuralProduct && typeof structuralProduct.familyCode === 'string' + ? structuralProduct.familyCode + : null) || + (typeof source.familyCode === 'string' ? source.familyCode : null) + + if (!fallbackName && structuralProduct) { + fallbackName = + (structuralProduct.typeProductLabel as string) || + ((structuralProduct.typeProduct as AnyRecord)?.name as string) || + (structuralProduct.reference as string) || + (structuralFamilyCode ? `Famille ${structuralFamilyCode}` : null) || + null + } + + if (!fallbackReference && structuralProduct?.reference) { + fallbackReference = structuralProduct.reference as string + } + + if (!fallbackCategory) { + fallbackCategory = + (structuralProduct?.typeProductLabel as string) || + ((structuralProduct?.typeProduct as AnyRecord)?.name as string) || + (structuralFamilyCode ? `Famille ${structuralFamilyCode}` : null) || + null + } + + if (!fallbackSuppliers && structuralProduct?.supplierLabel) { + fallbackSuppliers = structuralProduct.supplierLabel as string + } + + if (!fallbackSuppliers && Array.isArray(structuralProduct?.constructeurs)) { + const supplierNames = (structuralProduct!.constructeurs as AnyRecord[]) + .map((c) => c?.name as string) + .filter((name) => typeof name === 'string' && name.trim().length > 0) + if (supplierNames.length) fallbackSuppliers = supplierNames.join(', ') + } + + if (!fallbackPrice && structuralProduct?.priceLabel) fallbackPrice = structuralProduct.priceLabel as string + if (!fallbackPrice && structuralProduct?.price) fallbackPrice = structuralProduct.price as string | number + + if (fallbackName || fallbackReference || fallbackCategory || fallbackSuppliers || fallbackPrice) { + return { + name: fallbackName || 'Produit catalogue', + reference: fallbackReference, + category: fallbackCategory, + suppliers: fallbackSuppliers, + price: + typeof fallbackPrice === 'number' + ? `${fallbackPrice.toFixed(2)} €` + : (fallbackPrice as string) || null, + } + } + + return null +} + +// --------------------------------------------------------------------------- +// Parent link identifiers +// --------------------------------------------------------------------------- + +export const extractParentLinkIdentifiers = (source: AnyRecord | null | undefined): AnyRecord => { + if (!source || typeof source !== 'object') return {} + + const identifiers: AnyRecord = {} + + const idKeys = [ + 'parentRequirementId', + 'parentComponentRequirementId', + 'parentPieceRequirementId', + 'parentMachineComponentRequirementId', + 'parentMachinePieceRequirementId', + 'parentLinkId', + 'parentComponentLinkId', + 'parentPieceLinkId', + 'parentComponentId', + 'parentPieceId', + ] + + idKeys.forEach((key) => { + if (Object.prototype.hasOwnProperty.call(source, key)) { + const value = source[key] + if (value !== undefined && value !== null && value !== '') { + identifiers[key] = value + } + } + }) + + const objectKeys = [ + 'parentRequirement', + 'parentComponentRequirement', + 'parentPieceRequirement', + 'parentMachineComponentRequirement', + 'parentMachinePieceRequirement', + ] + + objectKeys.forEach((key) => { + const value = source[key] + if (isPlainObject(value) && value.id !== undefined && value.id !== null && value.id !== '') { + const idKey = `${key}Id` + if (!Object.prototype.hasOwnProperty.call(identifiers, idKey)) { + identifiers[idKey] = value.id + } + } + }) + + return identifiers +} From 1f2d6c78e8fc3b9cfd38211c9dfd400bac81bf49 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 4 Feb 2026 08:58:42 +0100 Subject: [PATCH 131/274] refacto(F1.1) : wire [id].vue to use extracted modules and fix TS errors Wire machine/[id].vue to import from extracted utility modules (customFieldUtils, productDisplayUtils, useMachineHierarchy, useMachinePrint). Remove ~1400 LOC of inline functions replaced by imports. Fix TypeScript errors in extracted composables (AnyRecord/ConstructeurSummary boundary casts, Map generics, optional chaining on unknown). Co-Authored-By: Claude Opus 4.5 --- app/composables/useMachineHierarchy.ts | 36 +- app/composables/useMachinePrint.ts | 3 +- app/pages/machine/[id].vue | 1459 ++---------------------- 3 files changed, 93 insertions(+), 1405 deletions(-) diff --git a/app/composables/useMachineHierarchy.ts b/app/composables/useMachineHierarchy.ts index 8d883d1..bf09f94 100644 --- a/app/composables/useMachineHierarchy.ts +++ b/app/composables/useMachineHierarchy.ts @@ -5,7 +5,7 @@ */ import { resolveIdentifier, resolveProductReference, getProductDisplay } from '~/shared/utils/productDisplayUtils' -import { resolveConstructeurs, uniqueConstructeurIds } from '~/shared/constructeurUtils' +import { resolveConstructeurs, uniqueConstructeurIds, type ConstructeurSummary } from '~/shared/constructeurUtils' type AnyRecord = Record @@ -28,7 +28,9 @@ const collectConstructeurs = ( }) .filter(Boolean) as AnyRecord[][] - return resolveConstructeurs(ids, ...pools, allConstructeurs) + // ConstructeurSummary and AnyRecord are structurally compatible at runtime + const allPools = [...pools, allConstructeurs] as unknown as Array + return resolveConstructeurs(ids, ...allPools) as unknown as AnyRecord[] } // --------------------------------------------------------------------------- @@ -56,7 +58,7 @@ export function mergePieceLists(existing: AnyRecord[] = [], updates: AnyRecord[] return existing.map((piece) => ({ ...piece, constructeurs: piece.constructeurs || [] })) } - const updateMap = new Map( + const updateMap = new Map( updates.map((piece) => [piece.id, { ...piece, constructeurs: piece.constructeurs || [] }]), ) const merged = existing.map((piece) => { @@ -86,7 +88,7 @@ export function mergeComponentTrees(existing: AnyRecord[] = [], updates: AnyReco } if (!updates.length) return existing - const updateMap = new Map( + const updateMap = new Map( updates.map((component) => [ component.id, { @@ -100,7 +102,7 @@ export function mergeComponentTrees(existing: AnyRecord[] = [], updates: AnyReco }, ]), ) - const merged = existing.map((component) => { + const merged: AnyRecord[] = existing.map((component) => { const update = updateMap.get(component.id) if (!update) { return { @@ -156,13 +158,15 @@ export const buildMachineHierarchyFromLinks = ( const machinePieceLinkId = normalizePieceLinkId(link) const pieceId = resolveIdentifier(appliedPiece.id, appliedPiece.pieceId, link.pieceId) + const overrides = (link.overrides || null) as AnyRecord | null + const basePiece: AnyRecord = { ...appliedPiece, id: appliedPiece.id || pieceId || machinePieceLinkId || `piece-${machinePieceLinkId}`, pieceId, - name: link.overrides?.name || appliedPiece.name || (appliedPiece.definition as AnyRecord)?.name || (appliedPiece.definition as AnyRecord)?.role || originalPiece?.name || 'Pièce', - reference: link.overrides?.reference || appliedPiece.reference || (appliedPiece.definition as AnyRecord)?.reference || originalPiece?.reference || null, - prix: link.overrides?.prix ?? appliedPiece.prix ?? originalPiece?.prix ?? null, + name: overrides?.name || appliedPiece.name || (appliedPiece.definition as AnyRecord)?.name || (appliedPiece.definition as AnyRecord)?.role || originalPiece?.name || 'Pièce', + reference: overrides?.reference || appliedPiece.reference || (appliedPiece.definition as AnyRecord)?.reference || originalPiece?.reference || null, + prix: overrides?.prix ?? appliedPiece.prix ?? originalPiece?.prix ?? null, constructeur: appliedPiece.constructeur || originalPiece?.constructeur || null, constructeurId: appliedPiece.constructeurId || (appliedPiece.constructeur as AnyRecord)?.id || originalPiece?.constructeurId || null, documents: Array.isArray(appliedPiece.documents) ? appliedPiece.documents : Array.isArray(originalPiece?.documents) ? originalPiece!.documents : [], @@ -171,7 +175,7 @@ export const buildMachineHierarchyFromLinks = ( typeMachinePieceRequirement: requirement, typeMachinePieceRequirementId: requirement?.id || null, requirementId: requirement?.id || null, - overrides: link.overrides || null, + overrides, originalPiece, machinePieceLink: link, machinePieceLinkId, @@ -216,7 +220,9 @@ export const buildMachineHierarchyFromLinks = ( const machineComponentLinkId = normalizeComponentLinkId(link) const composantId = resolveIdentifier(appliedComponent.id, appliedComponent.composantId, link.composantId) - const componentName = (link.overrides?.name || appliedComponent.name || (appliedComponent.definition as AnyRecord)?.alias || (appliedComponent.definition as AnyRecord)?.name || originalComponent?.name || 'Composant') as string + const compOverrides = (link.overrides || null) as AnyRecord | null + + const componentName = (compOverrides?.name || appliedComponent.name || (appliedComponent.definition as AnyRecord)?.alias || (appliedComponent.definition as AnyRecord)?.name || originalComponent?.name || 'Composant') as string const pieces = Array.isArray(link.pieceLinks) ? (link.pieceLinks as AnyRecord[]).map((pl) => createPieceNode(pl, componentName)).filter(Boolean) as AnyRecord[] @@ -234,8 +240,8 @@ export const buildMachineHierarchyFromLinks = ( id: appliedComponent.id || composantId || machineComponentLinkId || `component-${machineComponentLinkId}`, composantId, name: componentName, - reference: link.overrides?.reference || appliedComponent.reference || (appliedComponent.definition as AnyRecord)?.reference || originalComponent?.reference || null, - prix: link.overrides?.prix ?? appliedComponent.prix ?? originalComponent?.prix ?? null, + reference: compOverrides?.reference || appliedComponent.reference || (appliedComponent.definition as AnyRecord)?.reference || originalComponent?.reference || null, + prix: compOverrides?.prix ?? appliedComponent.prix ?? originalComponent?.prix ?? null, constructeur: appliedComponent.constructeur || originalComponent?.constructeur || null, constructeurId: appliedComponent.constructeurId || (appliedComponent.constructeur as AnyRecord)?.id || originalComponent?.constructeurId || null, documents: Array.isArray(appliedComponent.documents) ? appliedComponent.documents : Array.isArray(originalComponent?.documents) ? originalComponent!.documents : [], @@ -244,9 +250,9 @@ export const buildMachineHierarchyFromLinks = ( typeMachineComponentRequirement: requirement, typeMachineComponentRequirementId: requirement?.id || null, requirementId: requirement?.id || null, - overrides: link.overrides || null, - machineComponentLinkOverrides: link.overrides || null, - definitionOverrides: link.overrides || null, + overrides: compOverrides, + machineComponentLinkOverrides: compOverrides, + definitionOverrides: compOverrides, originalComposant: originalComponent, machineComponentLink: link, machineComponentLinkId, diff --git a/app/composables/useMachinePrint.ts b/app/composables/useMachinePrint.ts index cd9252b..d62d0d3 100644 --- a/app/composables/useMachinePrint.ts +++ b/app/composables/useMachinePrint.ts @@ -88,7 +88,8 @@ export function useMachinePrint() { ) => { if (typeof window === 'undefined') return - const context = buildMachinePrintContext({ + // machineReport.js has no type annotations; cast to avoid inferred never[] params + const context = (buildMachinePrintContext as unknown as (config: Record) => Record)({ machine, machineName, machineReference, diff --git a/app/pages/machine/[id].vue b/app/pages/machine/[id].vue index b177531..5491abd 100644 --- a/app/pages/machine/[id].vue +++ b/app/pages/machine/[id].vue @@ -689,7 +689,7 @@ diff --git a/app/pages/product/[id]/edit.vue b/app/pages/product/[id]/edit.vue index c811798..900f1da 100644 --- a/app/pages/product/[id]/edit.vue +++ b/app/pages/product/[id]/edit.vue @@ -402,20 +402,28 @@ import { formatProductStructurePreview, normalizeProductStructureForSave } from import { uniqueConstructeurIds } from '~/shared/constructeurUtils' import { getModelType } from '~/services/modelTypes' import type { ProductModelStructure } from '~/shared/types/inventory' -import { getFileIcon } from '~/utils/fileIcons' -import { canPreviewDocument, isImageDocument, isPdfDocument } from '~/utils/documentPreview' - -interface CustomFieldInput { - id: string | null - name: string - type: string - required: boolean - options: string[] - value: string - customFieldId: string | null - customFieldValueId: string | null - orderIndex: number -} +import { canPreviewDocument } from '~/utils/documentPreview' +import { + type CustomFieldInput, + fieldKey, + buildCustomFieldInputs, + requiredCustomFieldsFilled as _requiredCustomFieldsFilled, + saveCustomFieldValues as _saveCustomFieldValues, +} from '~/shared/utils/customFieldFormUtils' +import { + documentIcon, + formatSize, + shouldInlinePdf, + documentPreviewSrc, + documentThumbnailClass, + downloadDocument, +} from '~/shared/utils/documentDisplayUtils' +import { + historyActionLabel, + formatHistoryDate, + formatHistoryValue, + historyDiffEntries as _historyDiffEntries, +} from '~/shared/utils/historyDisplayUtils' const route = useRoute() const router = useRouter() @@ -458,75 +466,8 @@ const historyFieldLabels: Record = { constructeurIds: 'Fournisseurs', } -const historyActionLabel = (action: string) => { - if (action === 'create') { - return 'Création' - } - if (action === 'delete') { - return 'Suppression' - } - return 'Modification' -} - -const historyDateFormatter = new Intl.DateTimeFormat('fr-FR', { - dateStyle: 'medium', - timeStyle: 'short', -}) - -const formatHistoryDate = (value: string) => { - const date = new Date(value) - if (Number.isNaN(date.getTime())) { - return value - } - return historyDateFormatter.format(date) -} - -const formatHistoryValue = (value: unknown): string => { - if (value === null || value === undefined || value === '') { - return '—' - } - if (Array.isArray(value)) { - if (value.length === 0) { - return '—' - } - return value.map((item) => formatHistoryValue(item)).join(', ') - } - if (typeof value === 'object') { - const maybeRecord = value as Record - const name = typeof maybeRecord.name === 'string' ? maybeRecord.name : null - const id = typeof maybeRecord.id === 'string' ? maybeRecord.id : null - if (name && id) { - return `${name} (#${id})` - } - if (name) { - return name - } - if (id) { - return `#${id}` - } - try { - return JSON.stringify(value) - } catch (error) { - return String(value) - } - } - return String(value) -} - -const historyDiffEntries = (entry: ProductHistoryEntry) => { - const diff = entry.diff ?? {} - return Object.entries(diff).map(([field, change]) => { - const label = historyFieldLabels[field] ?? field - const fromLabel = formatHistoryValue(change?.from) - const toLabel = formatHistoryValue(change?.to) - return { - field, - label, - fromLabel, - toLabel, - } - }) -} +const historyDiffEntries = (entry: ProductHistoryEntry) => + _historyDiffEntries(entry, historyFieldLabels) const refreshCustomFieldInputs = ( structureOverride?: ProductModelStructure | null, @@ -545,15 +486,7 @@ const editionForm = reactive({ }) const requiredCustomFieldsFilled = computed(() => - customFieldInputs.value.every((field) => { - if (!field.required) { - return true - } - if (field.type === 'boolean') { - return field.value === 'true' || field.value === 'false' - } - return field.value.trim().length > 0 - }), + _requiredCustomFieldsFilled(customFieldInputs.value), ) const canSubmit = computed(() => @@ -562,60 +495,6 @@ const canSubmit = computed(() => const structurePreview = computed(() => formatProductStructurePreview(structure.value)) -const documentIcon = (doc: any) => - getFileIcon({ name: doc?.filename || doc?.name, mime: doc?.mimeType }) - -const formatSize = (size: number | null | undefined) => { - if (size === null || size === undefined) { - return '—' - } - if (size === 0) { - return '0 B' - } - const units = ['B', 'KB', 'MB', 'GB'] - const index = Math.min(units.length - 1, Math.floor(Math.log(size) / Math.log(1024))) - const formatted = size / Math.pow(1024, index) - return `${formatted.toFixed(1)} ${units[index]}` -} - -const PDF_PREVIEW_MAX_BYTES = 5 * 1024 * 1024 - -const shouldInlinePdf = (document: any) => { - if (!document || !isPdfDocument(document) || !document.path) { - return false - } - if (typeof document.size === 'number' && document.size > PDF_PREVIEW_MAX_BYTES) { - return false - } - return true -} - -const appendPdfViewerParams = (src: string) => { - if (!src || src.startsWith('data:')) { - return src || '' - } - if (src.includes('#')) { - return `${src}&toolbar=0&navpanes=0` - } - return `${src}#toolbar=0&navpanes=0` -} - -const documentPreviewSrc = (document: any) => { - if (!document?.path) { - return '' - } - if (isPdfDocument(document)) { - return appendPdfViewerParams(document.path) - } - return document.path -} - -const documentThumbnailClass = (document: any) => { - if (shouldInlinePdf(document) || (isImageDocument(document) && document?.path)) { - return 'h-24 w-20' - } - return 'h-16 w-16' -} const openPreview = (doc: any) => { if (!doc || !canPreviewDocument(doc)) { @@ -630,20 +509,6 @@ const closePreview = () => { previewDocument.value = null } -const downloadDocument = (doc: any) => { - if (!doc?.path) { - return - } - const target = String(doc.path) - if (target.startsWith('data:')) { - const link = document.createElement('a') - link.href = target - link.download = doc.filename || doc.name || 'document' - link.click() - return - } - window.open(target, '_blank') -} const loadProduct = async () => { const id = route.params.id @@ -768,86 +633,6 @@ watch( { immediate: true }, ) -const fieldKey = (field: CustomFieldInput, index: number) => - field.customFieldValueId || field.customFieldId || `${field.name}-${index}` - -const buildCustomFieldInputs = ( - productStructure: ProductModelStructure | null, - values: any[] | null | undefined, -): CustomFieldInput[] => { - if (!productStructure || typeof productStructure !== 'object') { - return [] - } - const definitions = Array.isArray(productStructure.customFields) ? productStructure.customFields : [] - const valueList = Array.isArray(values) ? values : [] - - const byId = new Map() - const byName = new Map() - - valueList.forEach((entry) => { - if (!entry || typeof entry !== 'object') { - return - } - const fieldId = entry.customField?.id || entry.customFieldId || null - if (fieldId) { - byId.set(fieldId, entry) - } - const fieldName = entry.customField?.name || entry.name || entry.key || null - if (fieldName) { - byName.set(fieldName, entry) - } - }) - - return definitions - .map((definition, index) => { - const definitionId = definition.customFieldId || definition.id || null - const matched = (definitionId ? byId.get(definitionId) : null) || byName.get(definition.name) - const type = typeof definition.type === 'string' ? definition.type : 'text' - const options = Array.isArray(definition.options) ? definition.options : [] - const required = !!definition.required - const orderIndex = typeof definition.orderIndex === 'number' ? definition.orderIndex : index - - if (!matched) { - return { - id: definition.id ?? null, - name: definition.name, - type, - required, - options, - value: '', - customFieldId: definition.customFieldId || definition.id || null, - customFieldValueId: null, - orderIndex, - } - } - - const resolvedValue = matched.value ?? '' - return { - id: definition.id ?? null, - name: definition.name, - type, - required, - options, - value: formatDefaultValue(type, resolvedValue), - customFieldId: matched.customField?.id || definition.customFieldId || definition.id || null, - customFieldValueId: matched.id ?? null, - orderIndex, - } - }) - .filter((field): field is CustomFieldInput => !!field?.name) - .sort((a, b) => a.orderIndex - b.orderIndex) -} - -const formatDefaultValue = (type: string, value: any): string => { - if (value === null || value === undefined) { - return '' - } - if (type === 'boolean') { - return String(value === true || String(value).toLowerCase() === 'true') - } - return String(value) -} - const submitEdition = async () => { if (!product.value) { return @@ -875,7 +660,12 @@ const submitEdition = async () => { const result = await updateProduct(product.value.id, payload) if (result.success && result.data?.id) { product.value = result.data - const failedFields = await saveCustomFieldValues(result.data.id) + const failedFields = await _saveCustomFieldValues( + 'product', + result.data.id, + [], + { customFieldInputs, upsertCustomFieldValue, updateCustomFieldValue, toast }, + ) if (failedFields.length) { toast.showError(`Impossible d'enregistrer ${failedFields.length} champ(s): ${failedFields.join(', ')}`) return @@ -890,46 +680,6 @@ const submitEdition = async () => { } } -const saveCustomFieldValues = async (productId: string) => { - const failed: string[] = [] - for (const field of customFieldInputs.value) { - const value = field.value ?? '' - if (field.customFieldValueId) { - const result = await updateCustomFieldValue(field.customFieldValueId, { value }) - if (!result.success) { - failed.push(field.name) - } - continue - } - - const metadata = field.customFieldId - ? undefined - : { customFieldName: field.name, customFieldType: field.type, customFieldRequired: field.required } - - const result = await upsertCustomFieldValue( - field.customFieldId, - 'product', - productId, - String(value ?? ''), - metadata, - ) - - if (!result.success) { - failed.push(field.name) - } else { - const createdValue = result.data - if (createdValue?.id) { - field.customFieldValueId = createdValue.id - } - const resolvedId = createdValue?.customField?.id || field.customFieldId - if (resolvedId) { - field.customFieldId = resolvedId - } - } - } - return failed -} - onMounted(async () => { await loadProduct() }) diff --git a/app/pages/product/create.vue b/app/pages/product/create.vue index 6b950ff..d088ada 100644 --- a/app/pages/product/create.vue +++ b/app/pages/product/create.vue @@ -249,6 +249,10 @@ import { formatProductStructurePreview, normalizeProductStructureForSave } from import { uniqueConstructeurIds } from '~/shared/constructeurUtils' import type { ProductModelStructure } from '~/shared/types/inventory' import type { ModelType } from '~/services/modelTypes' +import { + type CustomFieldInput, + normalizeCustomFieldInputs as normalizeCustomFieldInputsFromUtils, +} from '~/shared/utils/customFieldFormUtils' interface ProductCatalogType extends ModelType { structure: ProductModelStructure | null @@ -276,17 +280,6 @@ const creationForm = reactive({ const selectedDocuments = ref([]) const uploadingDocuments = ref(false) -interface CustomFieldInput { - id: string | null - name: string - type: string - required: boolean - options: string[] - value: string - customFieldId: string | null - orderIndex: number -} - const customFieldInputs = ref([]) const loadingTypes = computed(() => loadingProductTypes.value) @@ -337,7 +330,7 @@ watch(selectedType, (type) => { if (!creationForm.name) { creationForm.name = type.name } - customFieldInputs.value = normalizeCustomFieldInputs(normalizeProductStructureForSave(type.structure)) + customFieldInputs.value = normalizeCustomFieldInputsFromUtils(normalizeProductStructureForSave(type.structure)) }) const requiredCustomFieldsFilled = computed(() => @@ -362,49 +355,6 @@ const canSubmit = computed(() => Boolean( const fieldKey = (field: CustomFieldInput, index: number) => field.customFieldId || field.id || `${field.name}-${index}` -const normalizeCustomFieldInputs = (structure: ProductModelStructure | null): CustomFieldInput[] => { - if (!structure || typeof structure !== 'object') { - return [] - } - const fields = Array.isArray(structure.customFields) ? structure.customFields : [] - return fields - .map((field, index) => normalizeCustomField(field, index)) - .filter((field): field is CustomFieldInput => field !== null) - .sort((a, b) => a.orderIndex - b.orderIndex) -} - -const normalizeCustomField = (rawField: any, fallbackIndex = 0): CustomFieldInput | null => { - if (!rawField || typeof rawField !== 'object') { - return null - } - const name = typeof rawField.name === 'string' ? rawField.name.trim() : '' - if (!name) { - return null - } - const type = typeof rawField.type === 'string' ? rawField.type : 'text' - const required = !!rawField.required - const options = Array.isArray(rawField.options) - ? rawField.options.filter((option: unknown): option is string => typeof option === 'string') - : [] - const defaultSource = rawField.defaultValue ?? rawField.value ?? rawField.default ?? null - const value = formatDefaultValue(type, defaultSource) - const id = typeof rawField.id === 'string' ? rawField.id : null - const customFieldId = typeof rawField.customFieldId === 'string' ? rawField.customFieldId : id - const orderIndex = typeof rawField.orderIndex === 'number' ? rawField.orderIndex : fallbackIndex - - return { id, name, type, required, options, value, customFieldId, orderIndex } -} - -const formatDefaultValue = (type: string, defaultValue: any): string => { - if (defaultValue === null || defaultValue === undefined) { - return '' - } - if (type === 'boolean') { - return String(defaultValue === true || String(defaultValue).toLowerCase() === 'true') - } - return String(defaultValue) -} - const clearForm = () => { creationForm.name = '' creationForm.reference = '' diff --git a/app/services/modelTypes.ts b/app/services/modelTypes.ts index 504b96f..182ac5a 100644 --- a/app/services/modelTypes.ts +++ b/app/services/modelTypes.ts @@ -75,10 +75,10 @@ function resolveBaseUrl() { return runtimeConfig.public.apiBaseUrl || ''; } -function createOptions(options: FetchOptions = {}) { +function createOptions(options: Record = {}): Record { return { baseURL: resolveBaseUrl(), - credentials: 'include' as const, + credentials: 'include', ...options, }; } diff --git a/app/shared/apiRelations.ts b/app/shared/apiRelations.ts index 3a1b1ac..bd5d291 100644 --- a/app/shared/apiRelations.ts +++ b/app/shared/apiRelations.ts @@ -23,7 +23,7 @@ export const extractRelationId = (value: unknown): string | null => { } if (trimmed.includes('/')) { const parts = trimmed.split('/').filter(Boolean); - return parts.length ? parts[parts.length - 1] : null; + return parts.length ? (parts[parts.length - 1] ?? null) : null; } return trimmed; } diff --git a/app/shared/constructeurUtils.ts b/app/shared/constructeurUtils.ts index 1ec3733..c25cbad 100644 --- a/app/shared/constructeurUtils.ts +++ b/app/shared/constructeurUtils.ts @@ -20,7 +20,7 @@ const toStringId = (value: unknown): string | null => { } if (trimmed.includes('/')) { const parts = trimmed.split('/').filter(Boolean); - return parts.length ? parts[parts.length - 1] : null; + return parts.length ? (parts[parts.length - 1] ?? null) : null; } return trimmed; }; diff --git a/app/shared/modelUtils.ts b/app/shared/modelUtils.ts index 8e0fcef..0da7b3f 100644 --- a/app/shared/modelUtils.ts +++ b/app/shared/modelUtils.ts @@ -138,8 +138,8 @@ const sanitizeCustomFields = (fields: any[]): ComponentModelCustomField[] => { if (!options && typeof field?.optionsText === 'string') { const parsedFromText = field.optionsText .split(/\r?\n/) - .map((option) => option.trim()) - .filter((option) => option.length > 0) + .map((option: string) => option.trim()) + .filter((option: string) => option.length > 0) options = parsedFromText.length ? parsedFromText : undefined } } @@ -917,8 +917,8 @@ const sanitizePieceCustomFields = (fields: any[]): PieceModelCustomField[] => { : '' const parsed = rawOptions .split(/\r?\n/) - .map((option) => option.trim()) - .filter((option) => option.length > 0) + .map((option: string) => option.trim()) + .filter((option: string) => option.length > 0) options = parsed.length > 0 ? parsed : undefined } @@ -944,7 +944,7 @@ export const normalizePieceStructureForSave = (input: any): PieceModelStructure ) return { ...Object.fromEntries(restEntries), - products: sanitizePieceProducts(source.products), + products: sanitizePieceProducts(source.products || []), customFields: sanitizePieceCustomFields(source.customFields), } } @@ -974,7 +974,7 @@ export const hydratePieceStructureForEditor = (input: any): PieceModelStructureF ...Object.fromEntries( Object.entries(source).filter(([key]) => key !== 'customFields' && key !== 'products'), ), - products: hydrateProducts(source.products) as PieceModelProduct[], + products: hydrateProducts(source.products || []) as PieceModelProduct[], customFields: hydratePieceCustomFields(source.customFields), } return payload diff --git a/app/shared/types/inventory.ts b/app/shared/types/inventory.ts index c0d3504..b462f91 100644 --- a/app/shared/types/inventory.ts +++ b/app/shared/types/inventory.ts @@ -10,6 +10,8 @@ export interface ComponentModelCustomField { id?: string customFieldId?: string orderIndex?: number + key?: string + value?: unknown } export interface ComponentModelPiece { @@ -52,6 +54,9 @@ export interface PieceModelCustomField { required: boolean options?: string[] orderIndex?: number + key?: string + value?: unknown + defaultValue?: string | null } export interface PieceModelProduct { @@ -184,7 +189,7 @@ const validateStructureNode = ( : [] const subcomponents: ComponentModelStructureNode[] = [] - rawSubcomponents.forEach((subValue, index) => { + rawSubcomponents.forEach((subValue: unknown, index: number) => { const parsed = validateStructureNode(subValue, issues, `${path}.subcomponents[${index}]`) if (parsed) { subcomponents.push(parsed) @@ -260,6 +265,7 @@ export const componentModelStructureValidator = { ...node, customFields, pieces, + products: ((node as unknown) as Record).products as ComponentModelProduct[] ?? [], }, } }, diff --git a/app/shared/utils/customFieldFormUtils.ts b/app/shared/utils/customFieldFormUtils.ts new file mode 100644 index 0000000..ea962ea --- /dev/null +++ b/app/shared/utils/customFieldFormUtils.ts @@ -0,0 +1,367 @@ +/** + * Custom field form normalization, merge, and persistence utilities. + * + * Extracted from pages/component/create.vue, component/[id]/edit.vue, + * pieces/create.vue, pieces/[id]/edit.vue, product/[id]/edit.vue. + * + * Every create/edit page was shipping its own copy of these helpers – + * this module unifies them behind a single, entity-agnostic API. + */ + +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + +export interface CustomFieldInput { + id: string | null + name: string + type: string + required: boolean + options: string[] + value: string + customFieldId: string | null + customFieldValueId: string | null + orderIndex: number +} + +export interface SaveCustomFieldDeps { + customFieldInputs: { value: CustomFieldInput[] } + upsertCustomFieldValue: ( + definitionId: string | null, + entityType: string, + entityId: string, + value: string, + metadata?: Record, + ) => Promise<{ success: boolean; data?: any }> + updateCustomFieldValue: ( + id: string, + payload: { value: string }, + ) => Promise<{ success: boolean }> + toast: { showError: (msg: string) => void } +} + +// --------------------------------------------------------------------------- +// Primitive helpers +// --------------------------------------------------------------------------- + +export const toFieldString = (value: unknown): string => { + if (value === null || value === undefined) return '' + if (typeof value === 'string') return value + if (typeof value === 'number' || typeof value === 'boolean') return String(value) + return '' +} + +export const fieldKey = (field: CustomFieldInput, index: number): string => + field.customFieldValueId || field.id || `${field.name}-${index}` + +// --------------------------------------------------------------------------- +// Field resolution helpers +// --------------------------------------------------------------------------- + +export const resolveFieldName = (field: any): string => { + if (typeof field?.name === 'string' && field.name.trim()) return field.name.trim() + if (typeof field?.key === 'string' && field.key.trim()) return field.key.trim() + if (typeof field?.label === 'string' && field.label.trim()) return field.label.trim() + return '' +} + +export const resolveFieldType = (field: any): string => { + const allowed = ['text', 'number', 'select', 'boolean', 'date'] + const rawType = + typeof field?.type === 'string' + ? field.type + : typeof field?.value?.type === 'string' + ? field.value.type + : '' + const value = rawType.toLowerCase() + return allowed.includes(value) ? value : 'text' +} + +export const resolveRequiredFlag = (field: any): boolean => { + if (typeof field?.required === 'boolean') return field.required + const nested = field?.value?.required + if (typeof nested === 'boolean') return nested + if (typeof nested === 'string') { + const normalized = nested.toLowerCase() + return normalized === 'true' || normalized === '1' + } + return false +} + +export const resolveOptions = (field: any): string[] => { + const sources = [field?.options, field?.value?.options, field?.value?.choices] + for (const source of sources) { + if (Array.isArray(source)) { + const mapped = source + .map((option: unknown) => { + if (option === null || option === undefined) return '' + if (typeof option === 'string') return option.trim() + if (typeof option === 'object') { + const record = (option || {}) as Record + for (const key of ['value', 'label', 'name']) { + const candidate = record[key] + if (typeof candidate === 'string' && candidate.trim().length > 0) return candidate.trim() + } + } + const fallback = String(option).trim() + return fallback === '[object Object]' ? '' : fallback + }) + .filter((o) => o.length > 0) + if (mapped.length) return mapped + } + } + return [] +} + +export const resolveDefaultValue = (field: any): any => { + if (!field || typeof field !== 'object') return null + if (field.defaultValue !== undefined && field.defaultValue !== null) return field.defaultValue + if (field.value !== undefined && field.value !== null && typeof field.value !== 'object') return field.value + if (field.default !== undefined && field.default !== null) return field.default + if (field.value && typeof field.value === 'object') { + if (field.value.defaultValue !== undefined && field.value.defaultValue !== null) return field.value.defaultValue + if (field.value.value !== undefined && field.value.value !== null && typeof field.value.value !== 'object') return field.value.value + } + return null +} + +export const formatDefaultValue = (type: string, defaultValue: any): string => { + if (defaultValue === null || defaultValue === undefined) return '' + if (typeof defaultValue === 'object') { + if (defaultValue === null) return '' + if ('defaultValue' in (defaultValue as Record)) { + return formatDefaultValue(type, (defaultValue as Record).defaultValue) + } + if ('value' in (defaultValue as Record)) { + return formatDefaultValue(type, (defaultValue as Record).value) + } + return '' + } + if (type === 'boolean') { + const normalized = String(defaultValue).toLowerCase() + if (normalized === 'true' || normalized === '1') return 'true' + if (normalized === 'false' || normalized === '0') return 'false' + return '' + } + return String(defaultValue) +} + +// --------------------------------------------------------------------------- +// Normalize a single raw custom-field definition into CustomFieldInput +// --------------------------------------------------------------------------- + +export const normalizeCustomField = (rawField: any, fallbackIndex = 0): CustomFieldInput | null => { + if (!rawField || typeof rawField !== 'object') return null + const name = resolveFieldName(rawField) + if (!name) return null + const type = resolveFieldType(rawField) + const required = resolveRequiredFlag(rawField) + const options = resolveOptions(rawField) + const defaultSource = resolveDefaultValue(rawField) + const value = formatDefaultValue(type, defaultSource) + const id = typeof rawField.id === 'string' ? rawField.id : null + const customFieldId = typeof rawField.customFieldId === 'string' ? rawField.customFieldId : id + const customFieldValueId = typeof rawField.customFieldValueId === 'string' ? rawField.customFieldValueId : null + const orderIndex = typeof rawField.orderIndex === 'number' ? rawField.orderIndex : fallbackIndex + return { id, name, type, required, options, value, customFieldId, customFieldValueId, orderIndex } +} + +// --------------------------------------------------------------------------- +// Normalize ALL custom-field definitions from a structure +// --------------------------------------------------------------------------- + +export const normalizeCustomFieldInputs = (structure: any): CustomFieldInput[] => { + if (!structure || typeof structure !== 'object') return [] + const fields = Array.isArray(structure.customFields) ? structure.customFields : [] + return fields + .map((field: any, index: number) => normalizeCustomField(field, index)) + .filter((field: CustomFieldInput | null): field is CustomFieldInput => field !== null) + .sort((a: CustomFieldInput, b: CustomFieldInput) => a.orderIndex - b.orderIndex) +} + +// --------------------------------------------------------------------------- +// Extract stored value from a persisted custom-field entry +// --------------------------------------------------------------------------- + +export const extractStoredCustomFieldValue = (entry: any): any => { + if (entry === null || entry === undefined) return '' + if (typeof entry === 'string' || typeof entry === 'number' || typeof entry === 'boolean') return entry + if (typeof entry !== 'object') return String(entry) + + const direct = entry.value + if (direct !== undefined && direct !== null) { + if (typeof direct === 'object') { + if (direct === null) return '' + if ('value' in direct && direct.value !== undefined && direct.value !== null) return direct.value + if ('defaultValue' in direct && direct.defaultValue !== undefined && direct.defaultValue !== null) return direct.defaultValue + return '' + } + return direct + } + if (entry.defaultValue !== undefined && entry.defaultValue !== null) return entry.defaultValue + if (entry.customFieldValue?.value !== undefined && entry.customFieldValue?.value !== null) return entry.customFieldValue.value + return '' +} + +// --------------------------------------------------------------------------- +// Build inputs for edit pages (merge definitions + stored values) +// --------------------------------------------------------------------------- + +export const buildCustomFieldInputs = ( + structure: any, + values: any[] | null | undefined, +): CustomFieldInput[] => { + const definitions = normalizeCustomFieldInputs(structure) + const valueList = Array.isArray(values) ? values : [] + + const mapById = new Map() + const mapByName = new Map() + + valueList.forEach((entry) => { + if (!entry || typeof entry !== 'object') return + const fieldId = entry.customField?.id || entry.customFieldId || null + if (fieldId) mapById.set(fieldId, entry) + const fieldName = entry.customField?.name || entry.name || entry.key || null + if (fieldName) mapByName.set(fieldName, entry) + }) + + return definitions + .map((definition) => { + const definitionId = definition.customFieldId || definition.id || null + const matched = (definitionId ? mapById.get(definitionId) : null) || mapByName.get(definition.name) + + if (!matched) { + return { + ...definition, + customFieldId: definition.customFieldId || definition.id, + customFieldValueId: null, + orderIndex: definition.orderIndex, + } + } + + const resolvedValue = extractStoredCustomFieldValue(matched) + return { + ...definition, + customFieldId: matched.customField?.id || definition.customFieldId || definition.id, + customFieldValueId: matched.id ?? null, + value: formatDefaultValue(definition.type, resolvedValue), + orderIndex: Math.min( + definition.orderIndex ?? 0, + typeof matched.customField?.orderIndex === 'number' + ? matched.customField.orderIndex + : definition.orderIndex ?? 0, + ), + } + }) + .sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)) +} + +// --------------------------------------------------------------------------- +// Validation helpers +// --------------------------------------------------------------------------- + +export const buildCustomFieldMetadata = (field: CustomFieldInput): Record => ({ + customFieldName: field.name, + customFieldType: field.type, + customFieldRequired: field.required, + customFieldOptions: field.options, +}) + +export const shouldPersistField = (field: CustomFieldInput): boolean => { + if (field.type === 'boolean') return field.value === 'true' || field.value === 'false' + return toFieldString(field.value).trim() !== '' +} + +export const formatValueForPersistence = (field: CustomFieldInput): string => { + if (field.type === 'boolean') return field.value === 'true' ? 'true' : 'false' + return toFieldString(field.value).trim() +} + +export const requiredCustomFieldsFilled = (inputs: CustomFieldInput[]): boolean => + inputs.every((field) => { + if (!field.required) return true + if (field.type === 'boolean') return field.value === 'true' || field.value === 'false' + return toFieldString(field.value).trim() !== '' + }) + +// --------------------------------------------------------------------------- +// Persistence +// --------------------------------------------------------------------------- + +/** + * Save custom-field values for an entity. + * + * @param entityType - API entity slug ('composant' | 'piece' | 'product') + * @param entityId - ID of the created/updated entity + * @param definitionSources - arrays of raw definition objects to build a name→id map + * @param deps - injected composable references + * @returns list of field names that failed to save (empty = all OK) + */ +export const saveCustomFieldValues = async ( + entityType: string, + entityId: string, + definitionSources: any[][], + deps: SaveCustomFieldDeps, +): Promise => { + if (!entityId) return [] + + const definitionMap = new Map() + const registerDefinitions = (fields: any[]) => { + if (!Array.isArray(fields)) return + fields.forEach((field) => { + if (!field || typeof field !== 'object') return + const name = typeof field.name === 'string' ? field.name : null + const id = typeof field.id === 'string' ? field.id : null + if (name && id && !definitionMap.has(name)) definitionMap.set(name, id) + }) + } + + definitionSources.forEach(registerDefinitions) + + const resolveDefinitionId = (field: CustomFieldInput) => { + if (field.customFieldId) return field.customFieldId + if (field.id) return field.id + return definitionMap.get(field.name) ?? null + } + + const failed: string[] = [] + + for (const field of deps.customFieldInputs.value) { + if (!shouldPersistField(field)) continue + + const definitionId = resolveDefinitionId(field) + const metadata = definitionId ? undefined : buildCustomFieldMetadata(field) + const value = formatValueForPersistence(field) + + if (field.customFieldValueId) { + const result = await deps.updateCustomFieldValue(field.customFieldValueId, { value }) + if (!result.success) { + deps.toast.showError(`Impossible de mettre à jour le champ personnalisé "${field.name}"`) + failed.push(field.name) + } else if (definitionId && !field.customFieldId) { + field.customFieldId = definitionId + } + continue + } + + const result = await deps.upsertCustomFieldValue( + definitionId, + entityType, + entityId, + value, + metadata, + ) + + if (!result.success) { + deps.toast.showError(`Impossible d'enregistrer le champ personnalisé "${field.name}"`) + failed.push(field.name) + } else { + const createdValue = result.data + if (createdValue?.id) field.customFieldValueId = createdValue.id + const resolvedId = createdValue?.customField?.id || definitionId + if (resolvedId) field.customFieldId = resolvedId + } + } + + return failed +} diff --git a/app/shared/utils/customFieldUtils.ts b/app/shared/utils/customFieldUtils.ts index 7500edc..28eaf4c 100644 --- a/app/shared/utils/customFieldUtils.ts +++ b/app/shared/utils/customFieldUtils.ts @@ -173,6 +173,20 @@ export interface NormalizedCustomFieldDefinition { orderIndex: number } +export interface NormalizedCustomFieldEntry { + customFieldValueId: unknown + id: string | undefined + customFieldId: string | null + name: string + type: string + required: boolean + options: string[] + optionsText: string + defaultValue: unknown + value: string + readOnly: boolean +} + export const normalizeCustomFieldDefinitionEntry = ( definition: Record = {}, fallbackIndex = 0, @@ -237,8 +251,8 @@ export const mergeCustomFieldValuesWithDefinitions = ( valueEntries: Record[] = [], ...definitionSources: unknown[][] ): Record[] => { - const normalizedValues = (Array.isArray(valueEntries) ? valueEntries : []) - .map((entry) => { + const normalizedValues: Record[] = (Array.isArray(valueEntries) ? valueEntries : []) + .map((entry): Record | null => { if (!entry || typeof entry !== 'object') return null const normalizedDefinition = normalizeCustomFieldDefinitionEntry( ((entry as Record).customField || entry) as Record, @@ -265,7 +279,7 @@ export const mergeCustomFieldValuesWithDefinitions = ( defaultValue: normalizedDefinition.defaultValue ?? '', value, readOnly: !!(entry as Record)?.readOnly, - } + } as Record }) .filter((entry): entry is Record => entry !== null) diff --git a/app/shared/utils/documentDisplayUtils.ts b/app/shared/utils/documentDisplayUtils.ts new file mode 100644 index 0000000..ec8eeac --- /dev/null +++ b/app/shared/utils/documentDisplayUtils.ts @@ -0,0 +1,65 @@ +/** + * Document display & preview helpers for edit pages. + * + * Extracted from pages/component/[id]/edit.vue, pieces/[id]/edit.vue, + * product/[id]/edit.vue – each had an identical copy of these utilities. + */ + +import { getFileIcon } from '~/utils/fileIcons' +import { canPreviewDocument, isImageDocument, isPdfDocument } from '~/utils/documentPreview' + +export const PDF_PREVIEW_MAX_BYTES = 5 * 1024 * 1024 + +export const formatSize = (size: number | null | undefined): string => { + if (size === null || size === undefined) return '—' + if (size === 0) return '0 B' + const units = ['B', 'KB', 'MB', 'GB'] + const index = Math.min(units.length - 1, Math.floor(Math.log(size) / Math.log(1024))) + const formatted = size / Math.pow(1024, index) + return `${formatted.toFixed(1)} ${units[index]}` +} + +export const shouldInlinePdf = (doc: any): boolean => { + if (!doc || !isPdfDocument(doc) || !doc.path) return false + if (typeof doc.size === 'number' && doc.size > PDF_PREVIEW_MAX_BYTES) return false + return true +} + +export const appendPdfViewerParams = (src: string): string => { + if (!src || src.startsWith('data:')) return src || '' + if (src.includes('#')) return `${src}&toolbar=0&navpanes=0` + return `${src}#toolbar=0&navpanes=0` +} + +export const documentPreviewSrc = (doc: any): string => { + if (!doc?.path) return '' + if (isPdfDocument(doc)) return appendPdfViewerParams(doc.path) + return doc.path +} + +export const documentThumbnailClass = (doc: any): string => { + if (shouldInlinePdf(doc) || (isImageDocument(doc) && doc?.path)) return 'h-24 w-20' + return 'h-16 w-16' +} + +export interface FileIconResult { + component: unknown + colorClass: string + label: string +} + +export const documentIcon = (doc: any): FileIconResult => + getFileIcon({ name: doc?.filename || doc?.name, mime: doc?.mimeType }) + +export const downloadDocument = (doc: any): void => { + if (!doc?.path) return + const target = String(doc.path) + if (target.startsWith('data:')) { + const link = document.createElement('a') + link.href = target + link.download = doc.filename || doc.name || 'document' + link.click() + return + } + window.open(target, '_blank') +} diff --git a/app/shared/utils/historyDisplayUtils.ts b/app/shared/utils/historyDisplayUtils.ts new file mode 100644 index 0000000..b768b79 --- /dev/null +++ b/app/shared/utils/historyDisplayUtils.ts @@ -0,0 +1,78 @@ +/** + * History display utilities for edit pages. + * + * Extracted from pages/component/[id]/edit.vue, pieces/[id]/edit.vue, + * product/[id]/edit.vue – each had an identical copy. + */ + +// --------------------------------------------------------------------------- +// Formatters +// --------------------------------------------------------------------------- + +export const historyActionLabel = (action: string): string => { + if (action === 'create') return 'Création' + if (action === 'delete') return 'Suppression' + return 'Modification' +} + +const historyDateFormatter = new Intl.DateTimeFormat('fr-FR', { + dateStyle: 'medium', + timeStyle: 'short', +}) + +export const formatHistoryDate = (value: string): string => { + const date = new Date(value) + if (Number.isNaN(date.getTime())) return value + return historyDateFormatter.format(date) +} + +export const formatHistoryValue = (value: unknown): string => { + if (value === null || value === undefined || value === '') return '—' + if (Array.isArray(value)) { + if (value.length === 0) return '—' + return value.map((item) => formatHistoryValue(item)).join(', ') + } + if (typeof value === 'object') { + const maybeRecord = value as Record + const name = typeof maybeRecord.name === 'string' ? maybeRecord.name : null + const id = typeof maybeRecord.id === 'string' ? maybeRecord.id : null + if (name && id) return `${name} (#${id})` + if (name) return name + if (id) return `#${id}` + try { + return JSON.stringify(value) + } catch { + return String(value) + } + } + return String(value) +} + +// --------------------------------------------------------------------------- +// Diff entries +// --------------------------------------------------------------------------- + +interface DiffChange { + from?: unknown + to?: unknown +} + +export interface HistoryDiffEntry { + field: string + label: string + fromLabel: string + toLabel: string +} + +export const historyDiffEntries = ( + entry: { diff?: Record | null }, + fieldLabels: Record, +): HistoryDiffEntry[] => { + const diff = entry.diff ?? {} + return Object.entries(diff).map(([field, change]) => ({ + field, + label: fieldLabels[field] ?? field, + fromLabel: formatHistoryValue(change?.from), + toLabel: formatHistoryValue(change?.to), + })) +} diff --git a/app/types/icons.d.ts b/app/types/icons.d.ts new file mode 100644 index 0000000..c76cac1 --- /dev/null +++ b/app/types/icons.d.ts @@ -0,0 +1,14 @@ +// Type declarations for unplugin-icons +// This allows TypeScript to understand icon imports from ~icons/* + +declare module '~icons/*' { + import type { FunctionalComponent, SVGAttributes } from 'vue' + const component: FunctionalComponent + export default component +} + +declare module '~icons/lucide/*' { + import type { FunctionalComponent, SVGAttributes } from 'vue' + const component: FunctionalComponent + export default component +} diff --git a/app/utils/events.ts b/app/utils/events.ts new file mode 100644 index 0000000..d501d93 --- /dev/null +++ b/app/utils/events.ts @@ -0,0 +1,41 @@ +/** + * Type-safe event handlers for form inputs. + * These helpers extract values from DOM events in a way that satisfies TypeScript. + */ + +/** + * Extract the string value from an input event. + */ +export const getInputValue = (event: Event): string => { + const target = event.target as HTMLInputElement | null + return target?.value ?? '' +} + +/** + * Extract the numeric value from an input event. + */ +export const getInputNumber = (event: Event): number => { + const target = event.target as HTMLInputElement | null + const value = target?.value ?? '' + const parsed = parseFloat(value) + return Number.isNaN(parsed) ? 0 : parsed +} + +/** + * Extract the checked state from a checkbox event. + */ +export const getCheckboxValue = (event: Event): boolean => { + const target = event.target as HTMLInputElement | null + return target?.checked ?? false +} + +/** + * Extract an optional numeric value from an input event (empty string = undefined). + */ +export const getOptionalNumber = (event: Event): number | undefined => { + const target = event.target as HTMLInputElement | null + const value = target?.value ?? '' + if (value.trim() === '') return undefined + const parsed = parseFloat(value) + return Number.isNaN(parsed) ? undefined : parsed +} diff --git a/app/utils/formatters/email.ts b/app/utils/formatters/email.ts index f9978d9..21d7c5b 100644 --- a/app/utils/formatters/email.ts +++ b/app/utils/formatters/email.ts @@ -20,8 +20,10 @@ export const maskEmail = (rawValue: string): string => { return '' } - const [localPart, domain] = value.split('@') - if (!domain) { + const parts = value.split('@') + const localPart = parts[0] ?? '' + const domain = parts[1] + if (!domain || !localPart) { return value } @@ -29,7 +31,7 @@ export const maskEmail = (rawValue: string): string => { return `${localPart[0] ?? ''}·@${domain}` } - const start = localPart[0] + const start = localPart[0] ?? '' const end = localPart.slice(-1) const masked = '·'.repeat(Math.max(0, localPart.length - 2)) diff --git a/package-lock.json b/package-lock.json index fffcc3e..423ec18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@iconify-json/lucide": "^1.2.68", "@nuxt/eslint-config": "^1.9.0", "@rushstack/eslint-patch": "^1.12.0", + "@types/node": "^25.2.1", "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.44.1", "eslint": "^9.36.0", @@ -92,7 +93,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -2087,7 +2087,6 @@ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "license": "MIT", - "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -4054,6 +4053,16 @@ "devOptional": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.1.tgz", + "integrity": "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, "node_modules/@types/parse-path": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/parse-path/-/parse-path-7.0.3.tgz", @@ -4102,7 +4111,6 @@ "integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.44.1", "@typescript-eslint/types": "8.44.1", @@ -4784,7 +4792,6 @@ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz", "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==", "license": "MIT", - "peer": true, "dependencies": { "@babel/parser": "^7.28.4", "@vue/compiler-core": "3.5.22", @@ -5004,7 +5011,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5422,7 +5428,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001741", @@ -6782,7 +6787,6 @@ "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -10094,7 +10098,6 @@ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -10141,7 +10144,6 @@ "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.87.0.tgz", "integrity": "sha512-uc47XrtHwkBoES4HFgwgfH9sqwAtJXgAIBq4fFBMZ4hWmgVZoExyn+L4g4VuaecVKXkz1bvlaHcfwHAJPQb5Gw==", "license": "MIT", - "peer": true, "dependencies": { "@oxc-project/types": "^0.87.0" }, @@ -10496,7 +10498,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -10936,7 +10937,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -12481,7 +12481,6 @@ "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", @@ -12701,7 +12700,6 @@ "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -12749,6 +12747,13 @@ "@types/estree": "^1.0.0" } }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "devOptional": true, + "license": "MIT" + }, "node_modules/unenv": { "version": "2.0.0-rc.21", "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.21.tgz", @@ -13052,7 +13057,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "napi-postinstall": "^0.3.0" }, @@ -13299,7 +13303,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.7.tgz", "integrity": "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==", "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -13625,7 +13628,6 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.22.tgz", "integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==", "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.22", "@vue/compiler-sfc": "3.5.22", @@ -13663,7 +13665,6 @@ "integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "debug": "^4.4.0", "eslint-scope": "^8.2.0", @@ -13687,7 +13688,6 @@ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", "license": "MIT", - "peer": true, "dependencies": { "@vue/devtools-api": "^6.6.4" }, diff --git a/package.json b/package.json index c0be962..e3cea3a 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@iconify-json/lucide": "^1.2.68", "@nuxt/eslint-config": "^1.9.0", "@rushstack/eslint-patch": "^1.12.0", + "@types/node": "^25.2.1", "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.44.1", "eslint": "^9.36.0", From 78718b85ae3acae6ce395f08dee119346600705c Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 9 Feb 2026 11:13:09 +0100 Subject: [PATCH 134/274] refactor(composables): migrate JS composables to TypeScript (F3.2) Convert 7 composables from JS to TS with proper type annotations: useApi, useCustomFields, useProfileSession, useProfiles, useToast, useMachineTypesApi, useMachines. Remove deprecated stubs useComponentModels.js and usePieceModels.js. Co-Authored-By: Claude Opus 4.6 --- app/composables/useApi.js | 105 -------------- app/composables/useApi.ts | 128 ++++++++++++++++++ app/composables/useComponentModels.js | 47 ------- ...{useCustomFields.js => useCustomFields.ts} | 61 +++++---- ...chineTypesApi.js => useMachineTypesApi.ts} | 115 ++++++++-------- .../{useMachines.js => useMachines.ts} | 117 ++++++++-------- app/composables/usePieceModels.js | 47 ------- ...ProfileSession.js => useProfileSession.ts} | 42 +++--- app/composables/useProfiles.js | 67 --------- app/composables/useProfiles.ts | 74 ++++++++++ app/composables/{useToast.js => useToast.ts} | 37 +++-- 11 files changed, 396 insertions(+), 444 deletions(-) delete mode 100644 app/composables/useApi.js create mode 100644 app/composables/useApi.ts delete mode 100644 app/composables/useComponentModels.js rename app/composables/{useCustomFields.js => useCustomFields.ts} (58%) rename app/composables/{useMachineTypesApi.js => useMachineTypesApi.ts} (55%) rename app/composables/{useMachines.js => useMachines.ts} (61%) delete mode 100644 app/composables/usePieceModels.js rename app/composables/{useProfileSession.js => useProfileSession.ts} (53%) delete mode 100644 app/composables/useProfiles.js create mode 100644 app/composables/useProfiles.ts rename app/composables/{useToast.js => useToast.ts} (51%) diff --git a/app/composables/useApi.js b/app/composables/useApi.js deleted file mode 100644 index 14d4ec2..0000000 --- a/app/composables/useApi.js +++ /dev/null @@ -1,105 +0,0 @@ -import { useToast } from './useToast' - -export function useApi () { - const { showSuccess, showError, showInfo } = useToast() - const { public: publicConfig } = useRuntimeConfig() - const API_BASE_URL = publicConfig.apiBaseUrl || 'http://localhost:3000' - const parsedApiTimeout = Number(publicConfig.apiTimeout ?? 30000) - const API_TIMEOUT = Number.isNaN(parsedApiTimeout) ? 30000 : parsedApiTimeout - - const apiCall = async (endpoint, options = {}) => { - const url = `${API_BASE_URL}${endpoint}` - const defaultOptions = { - credentials: 'include', - headers: { - 'Content-Type': 'application/json' - } - } - - // Ajouter un timeout à la requête - const controller = new AbortController() - const timeoutId = setTimeout(() => controller.abort(), API_TIMEOUT) - - try { - const response = await fetch(url, { - ...defaultOptions, - ...options, - headers: { - ...defaultOptions.headers, - ...options.headers - }, - signal: controller.signal - }) - - clearTimeout(timeoutId) - - if (response.ok) { - let data = null - if (response.status !== 204) { - const contentType = response.headers.get('content-type') || '' - if (contentType.includes('application/json') || contentType.includes('application/ld+json') || contentType.includes('+json')) { - const text = await response.text() - data = text ? JSON.parse(text) : null - } else { - const text = await response.text() - data = text || null - } - } - return { success: true, data } - } else { - const contentType = response.headers.get('content-type') || '' - let errorData = {} - if (contentType.includes('application/json')) { - errorData = await response.json().catch(() => ({})) - } else { - const text = await response.text().catch(() => '') - errorData = text ? { message: text } : {} - } - const errorMessage = errorData.message || `Erreur ${response.status}: ${response.statusText}` - showError(errorMessage) - return { success: false, error: errorMessage, status: response.status } - } - } catch (error) { - clearTimeout(timeoutId) - const errorMessage = error.name === 'AbortError' ? 'Timeout de la requête' : error.message || 'Erreur réseau' - showError(`Erreur réseau: ${errorMessage}`) - return { success: false, error: errorMessage } - } - } - - const get = async (endpoint) => { - return apiCall(endpoint, { method: 'GET' }) - } - - const post = async (endpoint, data) => { - return apiCall(endpoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/ld+json' - }, - body: JSON.stringify(data) - }) - } - - const patch = async (endpoint, data) => { - return apiCall(endpoint, { - method: 'PATCH', - headers: { - 'Content-Type': 'application/merge-patch+json' - }, - body: JSON.stringify(data) - }) - } - - const del = async (endpoint) => { - return apiCall(endpoint, { method: 'DELETE' }) - } - - return { - apiCall, - get, - post, - patch, - delete: del - } -} diff --git a/app/composables/useApi.ts b/app/composables/useApi.ts new file mode 100644 index 0000000..d9e2378 --- /dev/null +++ b/app/composables/useApi.ts @@ -0,0 +1,128 @@ +import { useToast } from './useToast' + +export interface ApiResponse { + success: boolean + data?: T + error?: string + status?: number +} + +interface ApiCallOptions extends RequestInit { + headers?: Record +} + +export function useApi() { + const { showError } = useToast() + const { public: publicConfig } = useRuntimeConfig() + const API_BASE_URL = (publicConfig.apiBaseUrl as string) || 'http://localhost:3000' + const parsedApiTimeout = Number(publicConfig.apiTimeout ?? 30000) + const API_TIMEOUT = Number.isNaN(parsedApiTimeout) ? 30000 : parsedApiTimeout + + const apiCall = async (endpoint: string, options: ApiCallOptions = {}): Promise> => { + const url = `${API_BASE_URL}${endpoint}` + const defaultOptions: ApiCallOptions = { + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + }, + } + + // Ajouter un timeout à la requête + const controller = new AbortController() + const timeoutId = setTimeout(() => controller.abort(), API_TIMEOUT) + + try { + const response = await fetch(url, { + ...defaultOptions, + ...options, + headers: { + ...defaultOptions.headers, + ...options.headers, + }, + signal: controller.signal, + }) + + clearTimeout(timeoutId) + + if (response.ok) { + let data: T | null = null + if (response.status !== 204) { + const contentType = response.headers.get('content-type') || '' + if (contentType.includes('application/json') || contentType.includes('application/ld+json') || contentType.includes('+json')) { + const text = await response.text() + data = text ? JSON.parse(text) : null + } else { + const text = await response.text() + data = (text || null) as T | null + } + } + return { success: true, data: data as T } + } else { + const contentType = response.headers.get('content-type') || '' + let errorData: Record = {} + if (contentType.includes('application/json')) { + errorData = await response.json().catch(() => ({})) + } else { + const text = await response.text().catch(() => '') + errorData = text ? { message: text } : {} + } + const errorMessage = (errorData.message as string) || `Erreur ${response.status}: ${response.statusText}` + showError(errorMessage) + return { success: false, error: errorMessage, status: response.status } + } + } catch (error) { + clearTimeout(timeoutId) + const err = error as Error & { name?: string } + const errorMessage = err.name === 'AbortError' ? 'Timeout de la requête' : err.message || 'Erreur réseau' + showError(`Erreur réseau: ${errorMessage}`) + return { success: false, error: errorMessage } + } + } + + const get = async (endpoint: string): Promise> => { + return apiCall(endpoint, { method: 'GET' }) + } + + const post = async (endpoint: string, data?: unknown): Promise> => { + return apiCall(endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/ld+json', + }, + body: data !== undefined ? JSON.stringify(data) : undefined, + }) + } + + const patch = async (endpoint: string, data?: unknown): Promise> => { + return apiCall(endpoint, { + method: 'PATCH', + headers: { + 'Content-Type': 'application/merge-patch+json', + }, + body: data !== undefined ? JSON.stringify(data) : undefined, + }) + } + + const put = async (endpoint: string, data?: unknown): Promise> => { + return apiCall(endpoint, { + method: 'PUT', + headers: { + 'Content-Type': 'application/ld+json', + }, + body: data !== undefined ? JSON.stringify(data) : undefined, + }) + } + + const del = async (endpoint: string): Promise> => { + return apiCall(endpoint, { method: 'DELETE' }) + } + + return { + apiCall, + get, + post, + patch, + put, + delete: del, + } +} diff --git a/app/composables/useComponentModels.js b/app/composables/useComponentModels.js deleted file mode 100644 index 1a4a1f9..0000000 --- a/app/composables/useComponentModels.js +++ /dev/null @@ -1,47 +0,0 @@ -import { ref, computed } from 'vue' - -let hasWarned = false - -const warnDeprecated = () => { - if (hasWarned) return - if (process.dev) { - console.warn('[useComponentModels] Ce composable est conservé pour compatibilité mais les modèles ont été remplacés par les catégories enrichies de squelette. Utilisez useComponentTypes / useComposants à la place.') - } - hasWarned = true -} - -const buildUnsupportedResult = () => ({ - success: false, - error: 'Les modèles de composants ont été retirés. Gérez les squelettes via les catégories et utilisez les requirements machine pour instancier des composants.' -}) - -export function useComponentModels () { - warnDeprecated() - - const componentModelsBuckets = ref({}) - const loadingComponentModels = ref(false) - - const componentModels = computed(() => []) - - const noLongerSupported = async () => { - warnDeprecated() - return buildUnsupportedResult() - } - - const getComponentModels = () => componentModels.value - const getComponentModelsForType = () => [] - const isComponentModelLoading = () => loadingComponentModels.value - - return { - componentModels, - componentModelsBuckets, - loadingComponentModels, - loadComponentModels: noLongerSupported, - createComponentModel: noLongerSupported, - updateComponentModel: noLongerSupported, - deleteComponentModel: noLongerSupported, - getComponentModels, - getComponentModelsForType, - isComponentModelLoading - } -} diff --git a/app/composables/useCustomFields.js b/app/composables/useCustomFields.ts similarity index 58% rename from app/composables/useCustomFields.js rename to app/composables/useCustomFields.ts index faa6d50..132a1a9 100644 --- a/app/composables/useCustomFields.js +++ b/app/composables/useCustomFields.ts @@ -1,66 +1,75 @@ import { ref } from 'vue' -import { useApi } from './useApi' +import { useApi, type ApiResponse } from './useApi' -export function useCustomFields () { +export interface CustomFieldValue { + id: string + customFieldId: string + entityType: string + entityId: string + value: unknown + [key: string]: unknown +} + +export function useCustomFields() { const { apiCall } = useApi() - const customFieldValues = ref([]) + const customFieldValues = ref([]) const loading = ref(false) // Créer une valeur de champ personnalisé - const createCustomFieldValue = async (customFieldValueData) => { + const createCustomFieldValue = async (customFieldValueData: Record): Promise => { try { const result = await apiCall('/custom-fields/values', { method: 'POST', - body: JSON.stringify(customFieldValueData) + body: JSON.stringify(customFieldValueData), }) return result } catch (error) { console.error('Erreur lors de la création de la valeur de champ personnalisé:', error) - return { success: false, error } + return { success: false, error: (error as Error).message } } } // Obtenir les valeurs de champs personnalisés pour une entité - const getCustomFieldValuesByEntity = async (entityType, entityId) => { + const getCustomFieldValuesByEntity = async (entityType: string, entityId: string): Promise => { try { loading.value = true const result = await apiCall(`/custom-fields/values/${entityType}/${entityId}`, { - method: 'GET' + method: 'GET', }) if (result.success) { - customFieldValues.value = result.data + customFieldValues.value = result.data as CustomFieldValue[] } return result } catch (error) { console.error('Erreur lors de la récupération des valeurs de champs personnalisés:', error) - return { success: false, error } + return { success: false, error: (error as Error).message } } finally { loading.value = false } } // Mettre à jour une valeur de champ personnalisé - const updateCustomFieldValue = async (id, updateData) => { + const updateCustomFieldValue = async (id: string, updateData: Record): Promise => { try { const result = await apiCall(`/custom-fields/values/${id}`, { method: 'PATCH', - body: JSON.stringify(updateData) + body: JSON.stringify(updateData), }) return result } catch (error) { console.error('Erreur lors de la mise à jour de la valeur de champ personnalisé:', error) - return { success: false, error } + return { success: false, error: (error as Error).message } } } // Créer ou mettre à jour une valeur de champ personnalisé const upsertCustomFieldValue = async ( - customFieldId, - entityType, - entityId, - value, - metadata = {}, - ) => { + customFieldId: string | null, + entityType: string, + entityId: string, + value: unknown, + metadata: Record = {}, + ): Promise => { try { const result = await apiCall('/custom-fields/values/upsert', { method: 'POST', @@ -69,26 +78,26 @@ export function useCustomFields () { entityType, entityId, value, - ...metadata - }) + ...metadata, + }), }) return result } catch (error) { console.error('Erreur lors de la création/mise à jour de la valeur de champ personnalisé:', error) - return { success: false, error } + return { success: false, error: (error as Error).message } } } // Supprimer une valeur de champ personnalisé - const deleteCustomFieldValue = async (id) => { + const deleteCustomFieldValue = async (id: string): Promise => { try { const result = await apiCall(`/custom-fields/values/${id}`, { - method: 'DELETE' + method: 'DELETE', }) return result } catch (error) { console.error('Erreur lors de la suppression de la valeur de champ personnalisé:', error) - return { success: false, error } + return { success: false, error: (error as Error).message } } } @@ -99,6 +108,6 @@ export function useCustomFields () { getCustomFieldValuesByEntity, updateCustomFieldValue, upsertCustomFieldValue, - deleteCustomFieldValue + deleteCustomFieldValue, } } diff --git a/app/composables/useMachineTypesApi.js b/app/composables/useMachineTypesApi.ts similarity index 55% rename from app/composables/useMachineTypesApi.js rename to app/composables/useMachineTypesApi.ts index 5712f60..3e5a867 100644 --- a/app/composables/useMachineTypesApi.js +++ b/app/composables/useMachineTypesApi.ts @@ -1,80 +1,76 @@ import { ref } from 'vue' import { useToast } from './useToast' -import { useApi } from './useApi' +import { useApi, type ApiResponse } from './useApi' import { extractRelationId } from '~/shared/apiRelations' +import { extractCollection } from '~/shared/utils/apiHelpers' -const machineTypes = ref([]) +export interface MachineTypeRequirement { + id?: string + label?: string + minCount?: number + maxCount?: number + required?: boolean + [key: string]: unknown +} + +export interface MachineType { + id: string + name: string + componentRequirements: MachineTypeRequirement[] + pieceRequirements: MachineTypeRequirement[] + productRequirements: MachineTypeRequirement[] + [key: string]: unknown +} + +const machineTypes = ref([]) const loading = ref(false) -const normalizeRequirementList = (value, relationKey) => { +const normalizeRequirementList = (value: unknown, relationKey: string): MachineTypeRequirement[] => { if (!Array.isArray(value)) { return [] } - return value.map((entry, index) => { + return value.map((entry: Record, _index: number) => { if (!entry || typeof entry !== 'object') { return entry } const normalized = { ...entry } const relationField = relationKey.replace('Id', '') const relationValue = normalized[relationField] - console.log(`[normalizeRequirementList] Entry ${index}:`, { - relationKey, - relationField, - hasRelationKey: !!normalized[relationKey], - relationValue, - relationValueType: typeof relationValue - }) if (relationKey && !normalized[relationKey]) { const relationId = extractRelationId(relationValue) - console.log(`[normalizeRequirementList] Extracted ID:`, relationId) if (relationId) { normalized[relationKey] = relationId } } - console.log(`[normalizeRequirementList] Normalized entry:`, normalized) - return normalized + return normalized as MachineTypeRequirement }) } -const normalizeMachineType = (type) => { +const normalizeMachineType = (type: Record): MachineType | null => { if (!type || typeof type !== 'object') { - return type + return null } return { ...type, componentRequirements: normalizeRequirementList(type.componentRequirements, 'typeComposantId'), pieceRequirements: normalizeRequirementList(type.pieceRequirements, 'typePieceId'), productRequirements: normalizeRequirementList(type.productRequirements, 'typeProductId'), - } + } as MachineType } -const extractCollection = (payload) => { - if (Array.isArray(payload)) { - return payload - } - if (Array.isArray(payload?.member)) { - return payload.member - } - if (Array.isArray(payload?.['hydra:member'])) { - return payload['hydra:member'] - } - if (Array.isArray(payload?.data)) { - return payload.data - } - return [] -} - -export function useMachineTypesApi () { - const { showSuccess, showError, showInfo } = useToast() +export function useMachineTypesApi() { + const { showSuccess, showInfo } = useToast() const { get, post, put, delete: del } = useApi() - const loadMachineTypes = async () => { + const loadMachineTypes = async (): Promise => { loading.value = true try { const result = await get('/type_machines') if (result.success) { const items = extractCollection(result.data) - machineTypes.value = items.map(normalizeMachineType) + machineTypes.value = items + .map((item) => normalizeMachineType(item as Record)) + .filter((item): item is MachineType => item !== null) showInfo(`Chargement de ${machineTypes.value.length} type(s) de machine réussi`) } } catch (error) { @@ -84,31 +80,32 @@ export function useMachineTypesApi () { } } - const createMachineType = async (typeData) => { + const createMachineType = async (typeData: Partial): Promise => { loading.value = true try { const result = await post('/type_machines', typeData) if (result.success) { - machineTypes.value.push(normalizeMachineType(result.data)) + const normalized = normalizeMachineType(result.data as Record) + if (normalized) machineTypes.value.push(normalized) showSuccess(`Type de machine "${typeData.name}" créé avec succès`) } return result } catch (error) { console.error('Erreur lors de la création du type de machine:', error) - return { success: false, error: error.message } + return { success: false, error: (error as Error).message } } finally { loading.value = false } } - const updateMachineType = async (id, typeData) => { + const updateMachineType = async (id: string, typeData: Partial): Promise => { loading.value = true try { const result = await put(`/type_machines/${id}`, typeData) if (result.success) { - const normalized = normalizeMachineType(result.data) - const index = machineTypes.value.findIndex(type => type.id === id) - if (index !== -1) { + const normalized = normalizeMachineType(result.data as Record) + const index = machineTypes.value.findIndex((type) => type.id === id) + if (index !== -1 && normalized) { machineTypes.value[index] = normalized } showSuccess(`Type de machine "${typeData.name}" mis à jour avec succès`) @@ -116,34 +113,34 @@ export function useMachineTypesApi () { return result } catch (error) { console.error('Erreur lors de la mise à jour du type de machine:', error) - return { success: false, error: error.message } + return { success: false, error: (error as Error).message } } finally { loading.value = false } } - const deleteMachineType = async (id) => { + const deleteMachineType = async (id: string): Promise => { loading.value = true try { const result = await del(`/type_machines/${id}`) if (result.success) { - const deletedType = machineTypes.value.find(type => type.id === id) - machineTypes.value = machineTypes.value.filter(type => type.id !== id) + const deletedType = machineTypes.value.find((type) => type.id === id) + machineTypes.value = machineTypes.value.filter((type) => type.id !== id) showSuccess(`Type de machine "${deletedType?.name || 'inconnu'}" supprimé avec succès`) } return result } catch (error) { console.error('Erreur lors de la suppression du type de machine:', error) - return { success: false, error: error.message } + return { success: false, error: (error as Error).message } } finally { loading.value = false } } - const getMachineTypeById = async (id, forceRefresh = false) => { + const getMachineTypeById = async (id: string, forceRefresh = false): Promise => { // D'abord chercher dans le cache local (sauf si forceRefresh) if (!forceRefresh) { - const localType = machineTypes.value.find(type => type.id === id) + const localType = machineTypes.value.find((type) => type.id === id) if (localType) { return { success: true, data: localType } } @@ -153,12 +150,12 @@ export function useMachineTypesApi () { try { const result = await get(`/type_machines/${id}`) if (result.success) { - const normalized = normalizeMachineType(result.data) + const normalized = normalizeMachineType(result.data as Record) // Mettre à jour le cache local - const index = machineTypes.value.findIndex(type => type.id === id) - if (index !== -1) { + const index = machineTypes.value.findIndex((type) => type.id === id) + if (index !== -1 && normalized) { machineTypes.value[index] = normalized - } else { + } else if (normalized) { machineTypes.value.push(normalized) } return { success: true, data: normalized } @@ -166,12 +163,12 @@ export function useMachineTypesApi () { return result } catch (error) { console.error('Erreur lors de la récupération du type de machine:', error) - return { success: false, error: error.message } + return { success: false, error: (error as Error).message } } } - const getMachineTypes = () => machineTypes.value - const isLoading = () => loading.value + const getMachineTypes = (): MachineType[] => machineTypes.value + const isLoading = (): boolean => loading.value return { machineTypes, @@ -182,6 +179,6 @@ export function useMachineTypesApi () { deleteMachineType, getMachineTypeById, getMachineTypes, - isLoading + isLoading, } } diff --git a/app/composables/useMachines.js b/app/composables/useMachines.ts similarity index 61% rename from app/composables/useMachines.js rename to app/composables/useMachines.ts index 35141df..48ff8f4 100644 --- a/app/composables/useMachines.js +++ b/app/composables/useMachines.ts @@ -1,13 +1,24 @@ import { ref } from 'vue' import { useToast } from './useToast' -import { useApi } from './useApi' +import { useApi, type ApiResponse } from './useApi' import { buildConstructeurRequestPayload } from '~/shared/constructeurUtils' import { extractRelationId, normalizeRelationIds } from '~/shared/apiRelations' +import { extractCollection } from '~/shared/utils/apiHelpers' -const machines = ref([]) +export interface Machine { + id: string + name?: string + siteId?: string | null + typeMachineId?: string | null + componentLinks?: unknown[] + pieceLinks?: unknown[] + [key: string]: unknown +} + +const machines = ref([]) const loading = ref(false) -const resolveLinkCollection = (source, keys) => { +const resolveLinkCollection = (source: Record, keys: string[]): unknown[] | undefined => { if (!source || typeof source !== 'object') { return undefined } @@ -22,16 +33,17 @@ const resolveLinkCollection = (source, keys) => { return undefined } -const normalizeMachineResponse = (payload) => { +const normalizeMachineResponse = (payload: unknown): Machine | null => { if (!payload || typeof payload !== 'object') { return null } - const container = payload.machine && typeof payload.machine === 'object' - ? payload.machine - : payload + const raw = payload as Record + const container = raw.machine && typeof raw.machine === 'object' + ? raw.machine as Record + : raw - const normalized = { ...container } + const normalized: Record = { ...container } if (!normalized.siteId) { const siteId = extractRelationId(container.site) @@ -47,42 +59,32 @@ const normalizeMachineResponse = (payload) => { } } - const componentLinks = resolveLinkCollection(payload, ['componentLinks', 'machineComponentLinks']) ?? + const componentLinks = resolveLinkCollection(raw, ['componentLinks', 'machineComponentLinks']) ?? resolveLinkCollection(container, ['componentLinks', 'machineComponentLinks']) ?? [] - const pieceLinks = resolveLinkCollection(payload, ['pieceLinks', 'machinePieceLinks']) ?? + const pieceLinks = resolveLinkCollection(raw, ['pieceLinks', 'machinePieceLinks']) ?? resolveLinkCollection(container, ['pieceLinks', 'machinePieceLinks']) ?? [] normalized.componentLinks = componentLinks normalized.pieceLinks = pieceLinks - return normalized + return normalized as Machine } -export function useMachines () { +export function useMachines() { const { showSuccess, showError, showInfo } = useToast() const { get, post, patch, delete: del } = useApi() - const loadMachines = async () => { + const loadMachines = async (): Promise => { loading.value = true try { const result = await get('/machines') if (result.success) { - const machineList = Array.isArray(result.data) - ? result.data - : Array.isArray(result.data?.member) - ? result.data.member - : Array.isArray(result.data?.['hydra:member']) - ? result.data['hydra:member'] - : Array.isArray(result.data?.machines) - ? result.data.machines - : Array.isArray(result.data?.data) - ? result.data.data - : [] + const machineList = extractCollection(result.data) const normalized = machineList .map((item) => normalizeMachineResponse(item)) - .filter(Boolean) + .filter((item): item is Machine => item !== null) machines.value = normalized showInfo(`Chargement de ${normalized.length} machine(s) réussi`) } @@ -93,14 +95,14 @@ export function useMachines () { } } - const createMachine = async (machineData) => { + const createMachine = async (machineData: Partial): Promise => { loading.value = true try { const normalizedPayload = normalizeRelationIds(buildConstructeurRequestPayload(machineData)) const result = await post('/machines', normalizedPayload) if (result.success) { const createdMachine = normalizeMachineResponse(result.data) || - normalizeMachineResponse(result.data?.machine) || + normalizeMachineResponse((result.data as Record)?.machine) || null if (createdMachine) { machines.value.push(createdMachine) @@ -111,34 +113,31 @@ export function useMachines () { return result } catch (error) { console.error('Erreur lors de la création de la machine:', error) - return { success: false, error: error.message } + return { success: false, error: (error as Error).message } } finally { loading.value = false } } - const createMachineFromType = async (machineData, typeMachine) => { - // Créer la machine avec la structure héritée du type + const createMachineFromType = async (machineData: Partial, typeMachine: { id: string }): Promise => { const machineWithStructure = { ...machineData, - typeMachineId: typeMachine.id - // La structure sera automatiquement héritée du type - // Les composants et pièces seront créés automatiquement + typeMachineId: typeMachine.id, } return await createMachine(machineWithStructure) } - const updateMachineData = async (id, machineData) => { + const updateMachineData = async (id: string, machineData: Partial): Promise => { loading.value = true try { const normalizedPayload = normalizeRelationIds(buildConstructeurRequestPayload(machineData)) const result = await patch(`/machines/${id}`, normalizedPayload) if (result.success) { const updatedMachine = normalizeMachineResponse(result.data) || - normalizeMachineResponse(result.data?.machine) || + normalizeMachineResponse((result.data as Record)?.machine) || null - const index = machines.value.findIndex(machine => machine.id === id) + const index = machines.value.findIndex((machine) => machine.id === id) if (index !== -1 && updatedMachine) { machines.value[index] = { ...machines.value[index], @@ -150,13 +149,13 @@ export function useMachines () { return result } catch (error) { console.error('Erreur lors de la mise à jour de la machine:', error) - return { success: false, error: error.message } + return { success: false, error: (error as Error).message } } finally { loading.value = false } } - const reconfigureSkeleton = async (machineId, payload) => { + const reconfigureSkeleton = async (machineId: string, payload: unknown): Promise => { if (!machineId) { return { success: false, error: 'Identifiant de machine manquant' } } @@ -165,28 +164,28 @@ export function useMachines () { try { const result = await patch(`/machines/${machineId}/skeleton`, payload) if (result.success) { - const index = machines.value.findIndex(machine => machine.id === machineId) + const index = machines.value.findIndex((machine) => machine.id === machineId) if (index !== -1) { const updatedMachine = normalizeMachineResponse(result.data) || - normalizeMachineResponse(result.data?.machine) || + normalizeMachineResponse((result.data as Record)?.machine) || machines.value[index] machines.value[index] = { ...machines.value[index], - ...(updatedMachine || {}), - } + ...updatedMachine, + } as Machine } showSuccess('Structure de la machine mise à jour avec succès') } return result } catch (error) { console.error('Erreur lors de la reconfiguration du squelette de la machine:', error) - return { success: false, error: error.message } + return { success: false, error: (error as Error).message } } finally { loading.value = false } } - const addMissingCustomFields = async (machineId, { showToast: shouldShowToast = true } = {}) => { + const addMissingCustomFields = async (machineId: string, { showToast: shouldShowToast = true } = {}): Promise => { if (!machineId) { const error = 'Identifiant de machine manquant' if (shouldShowToast) { @@ -206,46 +205,46 @@ export function useMachines () { } return result } catch (error) { - console.error('Erreur lors de l’ajout des champs personnalisés manquants:', error) + console.error('Erreur lors de l\'ajout des champs personnalisés manquants:', error) if (shouldShowToast) { showError('Erreur lors de la complétion des champs personnalisés') } - return { success: false, error: error.message } + return { success: false, error: (error as Error).message } } } - const deleteMachine = async (id) => { + const deleteMachine = async (id: string): Promise => { loading.value = true try { const result = await del(`/machines/${id}`) if (result.success) { - const deletedMachine = machines.value.find(machine => machine.id === id) - machines.value = machines.value.filter(machine => machine.id !== id) + const deletedMachine = machines.value.find((machine) => machine.id === id) + machines.value = machines.value.filter((machine) => machine.id !== id) showSuccess(`Machine "${deletedMachine?.name || 'inconnu'}" supprimée avec succès`) } return result } catch (error) { console.error('Erreur lors de la suppression de la machine:', error) - return { success: false, error: error.message } + return { success: false, error: (error as Error).message } } finally { loading.value = false } } - const getMachineById = (id) => { - return machines.value.find(machine => machine.id === id) + const getMachineById = (id: string): Machine | undefined => { + return machines.value.find((machine) => machine.id === id) } - const getMachinesBySite = (siteId) => { - return machines.value.filter(machine => machine.siteId === siteId) + const getMachinesBySite = (siteId: string): Machine[] => { + return machines.value.filter((machine) => machine.siteId === siteId) } - const getMachinesByType = (typeMachineId) => { - return machines.value.filter(machine => machine.typeMachineId === typeMachineId) + const getMachinesByType = (typeMachineId: string): Machine[] => { + return machines.value.filter((machine) => machine.typeMachineId === typeMachineId) } - const getMachines = () => machines.value - const isLoading = () => loading.value + const getMachines = (): Machine[] => machines.value + const isLoading = (): boolean => loading.value return { machines, @@ -261,6 +260,6 @@ export function useMachines () { getMachinesByType, getMachines, isLoading, - addMissingCustomFields + addMissingCustomFields, } } diff --git a/app/composables/usePieceModels.js b/app/composables/usePieceModels.js deleted file mode 100644 index b6d5e0c..0000000 --- a/app/composables/usePieceModels.js +++ /dev/null @@ -1,47 +0,0 @@ -import { ref, computed } from 'vue' - -let hasWarned = false - -const warnDeprecated = () => { - if (hasWarned) return - if (process.dev) { - console.warn('[usePieceModels] Ce composable est conservé pour compatibilité mais les modèles ont été remplacés par les catégories enrichies de squelette. Utilisez usePieceTypes / usePieces à la place.') - } - hasWarned = true -} - -const buildUnsupportedResult = () => ({ - success: false, - error: 'Les modèles de pièces ont été retirés. Gérez les squelettes via les catégories et utilisez les requirements machine pour instancier des pièces.' -}) - -export function usePieceModels () { - warnDeprecated() - - const pieceModelsBuckets = ref({}) - const loadingPieceModels = ref(false) - - const pieceModels = computed(() => []) - - const noLongerSupported = async () => { - warnDeprecated() - return buildUnsupportedResult() - } - - const getPieceModels = () => pieceModels.value - const getPieceModelsForType = () => [] - const isPieceModelLoading = () => loadingPieceModels.value - - return { - pieceModels, - pieceModelsBuckets, - loadingPieceModels, - loadPieceModels: noLongerSupported, - createPieceModel: noLongerSupported, - updatePieceModel: noLongerSupported, - deletePieceModel: noLongerSupported, - getPieceModels, - getPieceModelsForType, - isPieceModelLoading - } -} diff --git a/app/composables/useProfileSession.js b/app/composables/useProfileSession.ts similarity index 53% rename from app/composables/useProfileSession.js rename to app/composables/useProfileSession.ts index 83be2f2..0d4c257 100644 --- a/app/composables/useProfileSession.js +++ b/app/composables/useProfileSession.ts @@ -1,35 +1,37 @@ import { useState, useRequestHeaders, useRuntimeConfig } from '#imports' +import type { Profile } from './useProfiles' -const buildUrl = (path) => { +const buildUrl = (path: string): string => { const config = useRuntimeConfig() - const baseUrl = process.server - ? (config.apiBaseUrl || config.public.apiBaseUrl || '') - : (config.public.apiBaseUrl || '') + const baseUrl = import.meta.server + ? ((config.apiBaseUrl as string) || (config.public.apiBaseUrl as string) || '') + : ((config.public.apiBaseUrl as string) || '') const base = baseUrl.replace(/\/$/, '') return `${base}${path}` } -export function useProfileSession () { - const activeProfile = useState('profileSession:active', () => null) - const sessionLoaded = useState('profileSession:loaded', () => false) - const loading = useState('profileSession:loading', () => false) +export function useProfileSession() { + const activeProfile = useState('profileSession:active', () => null) + const sessionLoaded = useState('profileSession:loaded', () => false) + const loading = useState('profileSession:loading', () => false) - const getSessionHeaders = () => { - if (!process.server) { return undefined } + const getSessionHeaders = (): Record | undefined => { + if (!import.meta.server) { return undefined } const headers = useRequestHeaders(['cookie']) return headers?.cookie ? { cookie: headers.cookie } : undefined } - const fetchCurrentProfile = async () => { + const fetchCurrentProfile = async (): Promise => { loading.value = true try { - activeProfile.value = await $fetch(buildUrl('/session/profile'), { + activeProfile.value = await $fetch(buildUrl('/session/profile'), { method: 'GET', credentials: 'include', - headers: getSessionHeaders() + headers: getSessionHeaders(), }) } catch (error) { - if (error?.status === 401) { + const err = error as { status?: number } + if (err?.status === 401) { activeProfile.value = null } else { console.error('Erreur lors du chargement du profil actif', error) @@ -42,29 +44,29 @@ export function useProfileSession () { return activeProfile.value } - const ensureSession = () => { + const ensureSession = (): Promise => { if (!sessionLoaded.value) { return fetchCurrentProfile() } return Promise.resolve(activeProfile.value) } - const activateProfile = async (profileId) => { + const activateProfile = async (profileId: string): Promise => { await $fetch(buildUrl('/session/profile'), { method: 'POST', credentials: 'include', body: { profileId }, - headers: getSessionHeaders() + headers: getSessionHeaders(), }) await fetchCurrentProfile() } - const logout = async () => { + const logout = async (): Promise => { try { await $fetch(buildUrl('/session/profile'), { method: 'DELETE', credentials: 'include', - headers: getSessionHeaders() + headers: getSessionHeaders(), }) } finally { activeProfile.value = null @@ -79,6 +81,6 @@ export function useProfileSession () { ensureSession, fetchCurrentProfile, activateProfile, - logout + logout, } } diff --git a/app/composables/useProfiles.js b/app/composables/useProfiles.js deleted file mode 100644 index ad1c80d..0000000 --- a/app/composables/useProfiles.js +++ /dev/null @@ -1,67 +0,0 @@ -import { useState, useRequestHeaders, useRuntimeConfig } from '#imports' - -const buildUrl = (path) => { - const config = useRuntimeConfig() - const base = config.public.apiBaseUrl?.replace(/\/$/, '') || '' - return `${base}${path}` -} - -export function useProfiles () { - const profiles = useState('profiles:list', () => []) - const loadingProfiles = useState('profiles:loading', () => false) - const profilesLoaded = useState('profiles:loaded', () => false) - - const getSessionHeaders = () => { - if (!process.server) { return undefined } - const headers = useRequestHeaders(['cookie']) - return headers?.cookie ? { cookie: headers.cookie } : undefined - } - - const fetchProfiles = async () => { - loadingProfiles.value = true - try { - profiles.value = await $fetch(buildUrl('/session/profiles'), { - method: 'GET', - credentials: 'include', - headers: getSessionHeaders() - }) - profilesLoaded.value = true - } catch (error) { - console.error('Erreur lors du chargement des profils', error) - profiles.value = [] - profilesLoaded.value = false - } finally { - loadingProfiles.value = false - } - return profiles.value - } - - const createProfile = async ({ firstName, lastName }) => { - const profile = await $fetch(buildUrl('/session/profiles'), { - method: 'POST', - credentials: 'include', - body: { firstName, lastName }, - headers: getSessionHeaders() - }) - await fetchProfiles() - return profile - } - - const deleteProfile = async (profileId) => { - await $fetch(buildUrl(`/session/profiles/${profileId}`), { - method: 'DELETE', - credentials: 'include', - headers: getSessionHeaders() - }) - await fetchProfiles() - } - - return { - profiles, - loadingProfiles, - profilesLoaded, - fetchProfiles, - createProfile, - deleteProfile - } -} diff --git a/app/composables/useProfiles.ts b/app/composables/useProfiles.ts new file mode 100644 index 0000000..945ec4c --- /dev/null +++ b/app/composables/useProfiles.ts @@ -0,0 +1,74 @@ +import { useState, useRequestHeaders, useRuntimeConfig } from '#imports' + +export interface Profile { + id: string + firstName: string + lastName: string + [key: string]: unknown +} + +const buildUrl = (path: string): string => { + const config = useRuntimeConfig() + const base = (config.public.apiBaseUrl as string)?.replace(/\/$/, '') || '' + return `${base}${path}` +} + +export function useProfiles() { + const profiles = useState('profiles:list', () => []) + const loadingProfiles = useState('profiles:loading', () => false) + const profilesLoaded = useState('profiles:loaded', () => false) + + const getSessionHeaders = (): Record | undefined => { + if (!import.meta.server) { return undefined } + const headers = useRequestHeaders(['cookie']) + return headers?.cookie ? { cookie: headers.cookie } : undefined + } + + const fetchProfiles = async (): Promise => { + loadingProfiles.value = true + try { + profiles.value = await $fetch(buildUrl('/session/profiles'), { + method: 'GET', + credentials: 'include', + headers: getSessionHeaders(), + }) + profilesLoaded.value = true + } catch (error) { + console.error('Erreur lors du chargement des profils', error) + profiles.value = [] + profilesLoaded.value = false + } finally { + loadingProfiles.value = false + } + return profiles.value + } + + const createProfile = async ({ firstName, lastName }: { firstName: string; lastName: string }): Promise => { + const profile = await $fetch(buildUrl('/session/profiles'), { + method: 'POST', + credentials: 'include', + body: { firstName, lastName }, + headers: getSessionHeaders(), + }) + await fetchProfiles() + return profile + } + + const deleteProfile = async (profileId: string): Promise => { + await $fetch(buildUrl(`/session/profiles/${profileId}`), { + method: 'DELETE', + credentials: 'include', + headers: getSessionHeaders(), + }) + await fetchProfiles() + } + + return { + profiles, + loadingProfiles, + profilesLoaded, + fetchProfiles, + createProfile, + deleteProfile, + } +} diff --git a/app/composables/useToast.js b/app/composables/useToast.ts similarity index 51% rename from app/composables/useToast.js rename to app/composables/useToast.ts index 94bd036..a27dcc5 100644 --- a/app/composables/useToast.js +++ b/app/composables/useToast.ts @@ -1,17 +1,26 @@ import { ref } from 'vue' -const toasts = ref([]) +export type ToastType = 'success' | 'error' | 'warning' | 'info' + +export interface Toast { + id: number + message: string + type: ToastType + visible: boolean +} + +const toasts = ref([]) const MAX_TOASTS = 3 let nextId = 1 -export function useToast () { - const showToast = (message, type = 'info', duration = 3500) => { +export function useToast() { + const showToast = (message: string, type: ToastType = 'info', duration = 3500): number => { const id = nextId++ - const toast = { + const toast: Toast = { id, message, type, - visible: true + visible: true, } if (toasts.value.length >= MAX_TOASTS) { @@ -28,25 +37,25 @@ export function useToast () { return id } - const showSuccess = (message, duration = 5000) => { + const showSuccess = (message: string, duration = 5000): number => { return showToast(message, 'success', duration) } - const showError = (message, duration = 5000) => { + const showError = (message: string, duration = 5000): number => { return showToast(message, 'error', duration) } - const showWarning = (message, duration = 6000) => { + const showWarning = (message: string, duration = 6000): number => { return showToast(message, 'warning', duration) } - const showInfo = (message, duration = 5000) => { + const showInfo = (message: string, duration = 5000): number => { return showToast(message, 'info', duration) } - const removeToast = (id) => { - const index = toasts.value.findIndex(toast => toast.id === id) - if (index !== -1) { + const removeToast = (id: number): void => { + const index = toasts.value.findIndex((toast) => toast.id === id) + if (index !== -1 && toasts.value[index]) { toasts.value[index].visible = false setTimeout(() => { toasts.value.splice(index, 1) @@ -54,7 +63,7 @@ export function useToast () { } } - const clearAll = () => { + const clearAll = (): void => { toasts.value = [] } @@ -66,6 +75,6 @@ export function useToast () { showWarning, showInfo, removeToast, - clearAll + clearAll, } } From 86bb8af32d232b768b35c2c6b4c8a9986939f03f Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 9 Feb 2026 11:13:20 +0100 Subject: [PATCH 135/274] refactor(api): extract shared extractCollection helper (F2.1) Create shared/utils/apiHelpers.ts with generic extractCollection() that handles hydra:member, member, items, data, and array formats. Replace 7 local implementations in CRUD composables. Co-Authored-By: Claude Opus 4.6 --- app/composables/useComposants.ts | 18 +----------------- app/composables/useConstructeurs.ts | 18 +----------------- app/composables/useDocuments.ts | 18 +----------------- app/composables/usePieces.ts | 18 +----------------- app/composables/useProducts.ts | 18 +----------------- app/composables/useSites.ts | 20 +------------------- app/shared/utils/apiHelpers.ts | 16 ++++++++++++++++ 7 files changed, 22 insertions(+), 104 deletions(-) create mode 100644 app/shared/utils/apiHelpers.ts diff --git a/app/composables/useComposants.ts b/app/composables/useComposants.ts index e9e9bce..be1d070 100644 --- a/app/composables/useComposants.ts +++ b/app/composables/useComposants.ts @@ -4,6 +4,7 @@ import { useApi } from './useApi' import { buildConstructeurRequestPayload, uniqueConstructeurIds } from '~/shared/constructeurUtils' import { useConstructeurs, type Constructeur } from './useConstructeurs' import { extractRelationId, normalizeRelationIds } from '~/shared/apiRelations' +import { extractCollection } from '~/shared/utils/apiHelpers' export interface Composant { id: string @@ -45,23 +46,6 @@ const composants = ref([]) const total = ref(0) const loading = ref(false) -const extractCollection = (payload: unknown): Composant[] => { - if (Array.isArray(payload)) { - return payload as Composant[] - } - const p = payload as Record | null - if (Array.isArray(p?.member)) { - return p.member as Composant[] - } - if (Array.isArray(p?.['hydra:member'])) { - return p['hydra:member'] as Composant[] - } - if (Array.isArray(p?.data)) { - return p.data as Composant[] - } - return [] -} - const extractTotal = (payload: unknown, fallbackLength: number): number => { const p = payload as Record | null if (typeof p?.totalItems === 'number') { diff --git a/app/composables/useConstructeurs.ts b/app/composables/useConstructeurs.ts index 7da2c76..9e4f36c 100644 --- a/app/composables/useConstructeurs.ts +++ b/app/composables/useConstructeurs.ts @@ -1,6 +1,7 @@ import { ref } from 'vue' import { useApi } from './useApi' import { useToast } from './useToast' +import { extractCollection } from '~/shared/utils/apiHelpers' export interface Constructeur { id: string @@ -52,23 +53,6 @@ const upsertConstructeurs = (items: Constructeur[] = []) => { const getIndexedConstructeur = (id: string): Constructeur | null => constructeurs.value.find((item) => item && item.id === id) || null -const extractCollection = (payload: unknown): Constructeur[] => { - if (Array.isArray(payload)) { - return payload as Constructeur[] - } - const p = payload as Record | null - if (Array.isArray(p?.member)) { - return p.member as Constructeur[] - } - if (Array.isArray(p?.['hydra:member'])) { - return p['hydra:member'] as Constructeur[] - } - if (Array.isArray(p?.data)) { - return p.data as Constructeur[] - } - return [] -} - const pendingFetches = new Map>() export function useConstructeurs() { diff --git a/app/composables/useDocuments.ts b/app/composables/useDocuments.ts index c513b12..b34e549 100644 --- a/app/composables/useDocuments.ts +++ b/app/composables/useDocuments.ts @@ -2,6 +2,7 @@ import { ref } from 'vue' import { useApi } from './useApi' import { useToast } from './useToast' import { normalizeRelationIds } from '~/shared/apiRelations' +import { extractCollection } from '~/shared/utils/apiHelpers' export interface Document { id: string @@ -34,23 +35,6 @@ export interface DocumentResult { const documents = ref([]) const loading = ref(false) -const extractCollection = (payload: unknown): Document[] => { - if (Array.isArray(payload)) { - return payload - } - const p = payload as Record | null - if (Array.isArray(p?.member)) { - return p.member as Document[] - } - if (Array.isArray(p?.['hydra:member'])) { - return p['hydra:member'] as Document[] - } - if (Array.isArray(p?.data)) { - return p.data as Document[] - } - return [] -} - const fileToBase64 = (file: File): Promise => new Promise((resolve, reject) => { const reader = new FileReader() diff --git a/app/composables/usePieces.ts b/app/composables/usePieces.ts index 0ccab82..cd11e81 100644 --- a/app/composables/usePieces.ts +++ b/app/composables/usePieces.ts @@ -4,6 +4,7 @@ import { useApi } from './useApi' import { buildConstructeurRequestPayload, uniqueConstructeurIds } from '~/shared/constructeurUtils' import { useConstructeurs, type Constructeur } from './useConstructeurs' import { extractRelationId, normalizeRelationIds } from '~/shared/apiRelations' +import { extractCollection } from '~/shared/utils/apiHelpers' export interface Piece { id: string @@ -46,23 +47,6 @@ const pieces = ref([]) const total = ref(0) const loading = ref(false) -const extractCollection = (payload: unknown): Piece[] => { - if (Array.isArray(payload)) { - return payload as Piece[] - } - const p = payload as Record | null - if (Array.isArray(p?.member)) { - return p.member as Piece[] - } - if (Array.isArray(p?.['hydra:member'])) { - return p['hydra:member'] as Piece[] - } - if (Array.isArray(p?.data)) { - return p.data as Piece[] - } - return [] -} - const extractTotal = (payload: unknown, fallbackLength: number): number => { const p = payload as Record | null if (typeof p?.totalItems === 'number') { diff --git a/app/composables/useProducts.ts b/app/composables/useProducts.ts index 065e501..07167a0 100644 --- a/app/composables/useProducts.ts +++ b/app/composables/useProducts.ts @@ -4,6 +4,7 @@ import { useApi } from './useApi' import { buildConstructeurRequestPayload, uniqueConstructeurIds } from '~/shared/constructeurUtils' import { useConstructeurs, type Constructeur } from './useConstructeurs' import { extractRelationId, normalizeRelationIds } from '~/shared/apiRelations' +import { extractCollection } from '~/shared/utils/apiHelpers' export interface Product { id: string @@ -62,23 +63,6 @@ const replaceInCache = (item: Product): boolean => { return false } -const extractCollection = (payload: unknown): Product[] => { - if (Array.isArray(payload)) { - return payload as Product[] - } - const p = payload as Record | null - if (Array.isArray(p?.member)) { - return p.member as Product[] - } - if (Array.isArray(p?.['hydra:member'])) { - return p['hydra:member'] as Product[] - } - if (Array.isArray(p?.data)) { - return p.data as Product[] - } - return [] -} - const extractTotal = (payload: unknown, fallbackLength: number): number => { const p = payload as Record | null if (typeof p?.totalItems === 'number') { diff --git a/app/composables/useSites.ts b/app/composables/useSites.ts index 022ba56..b6e23bd 100644 --- a/app/composables/useSites.ts +++ b/app/composables/useSites.ts @@ -1,6 +1,7 @@ import { ref } from 'vue' import { useToast } from './useToast' import { useApi } from './useApi' +import { extractCollection } from '~/shared/utils/apiHelpers' export interface Site { id: string @@ -24,23 +25,6 @@ interface SiteResult { const sites = ref([]) const loading = ref(false) -const extractCollection = (payload: unknown): Site[] => { - if (Array.isArray(payload)) { - return payload as Site[] - } - const p = payload as Record | null - if (Array.isArray(p?.member)) { - return p.member as Site[] - } - if (Array.isArray(p?.['hydra:member'])) { - return p['hydra:member'] as Site[] - } - if (Array.isArray(p?.data)) { - return p.data as Site[] - } - return [] -} - export function useSites() { const { showSuccess, showInfo } = useToast() const { get, post, patch, delete: del } = useApi() @@ -49,8 +33,6 @@ export function useSites() { loading.value = true try { const result = await get('/sites') - console.log('sites api result', result) - if (result.success) { const collection = extractCollection(result.data) sites.value = collection diff --git a/app/shared/utils/apiHelpers.ts b/app/shared/utils/apiHelpers.ts new file mode 100644 index 0000000..54e9640 --- /dev/null +++ b/app/shared/utils/apiHelpers.ts @@ -0,0 +1,16 @@ +/** + * Shared API response helpers. + * + * Extracted from 10+ composables/components that each had an identical local + * copy of extractCollection (parsing hydra:member / member / data / array). + */ + +export function extractCollection(payload: unknown): T[] { + if (Array.isArray(payload)) return payload as T[] + const p = payload as Record | null + if (Array.isArray(p?.member)) return p!.member as T[] + if (Array.isArray(p?.['hydra:member'])) return p!['hydra:member'] as T[] + if (Array.isArray(p?.items)) return p!.items as T[] + if (Array.isArray(p?.data)) return p!.data as T[] + return [] +} From 399ec1f7b406e102bbf18d039d5b5a8f71df2f9e Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 9 Feb 2026 11:13:31 +0100 Subject: [PATCH 136/274] refactor(composables): merge 3 history composables into generic (F2.2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create useEntityHistory.ts with parameterized entity type. Rewrite useComponentHistory, usePieceHistory, useProductHistory as thin backward-compatible wrappers (67→13 LOC each). Co-Authored-By: Claude Opus 4.6 --- app/composables/useComponentHistory.ts | 75 ++++---------------------- app/composables/useEntityHistory.ts | 69 ++++++++++++++++++++++++ app/composables/usePieceHistory.ts | 75 ++++---------------------- app/composables/useProductHistory.ts | 75 ++++---------------------- 4 files changed, 99 insertions(+), 195 deletions(-) create mode 100644 app/composables/useEntityHistory.ts diff --git a/app/composables/useComponentHistory.ts b/app/composables/useComponentHistory.ts index 314c1ba..620eb36 100644 --- a/app/composables/useComponentHistory.ts +++ b/app/composables/useComponentHistory.ts @@ -1,67 +1,12 @@ -import { ref } from 'vue' -import { useApi } from '~/composables/useApi' +/** + * Backward-compatible wrapper around useEntityHistory. + * Real logic lives in useEntityHistory.ts. + */ +import { useEntityHistory, type EntityHistoryActor, type EntityHistoryEntry } from './useEntityHistory' -export type ComponentHistoryActor = { - id: string - label: string +export type ComponentHistoryActor = EntityHistoryActor +export type ComponentHistoryEntry = EntityHistoryEntry + +export function useComponentHistory() { + return useEntityHistory('composant') } - -export type ComponentHistoryEntry = { - id: string - action: 'create' | 'update' | 'delete' | string - createdAt: string - actor: ComponentHistoryActor | null - diff: Record | null - snapshot: Record | null -} - -const extractItems = (payload: any): ComponentHistoryEntry[] => { - if (Array.isArray(payload?.items)) { - return payload.items - } - if (Array.isArray(payload?.member)) { - return payload.member - } - if (Array.isArray(payload?.['hydra:member'])) { - return payload['hydra:member'] - } - return [] -} - -export function useComponentHistory () { - const { get } = useApi() - - const history = ref([]) - const loading = ref(false) - const error = ref(null) - - const loadHistory = async (componentId: string) => { - loading.value = true - error.value = null - try { - const result = await get(`/composants/${componentId}/history`) - if (!result.success) { - error.value = result.error ?? 'Impossible de charger l’historique.' - history.value = [] - return result - } - history.value = extractItems(result.data) as ComponentHistoryEntry[] - return { success: true, data: history.value } - } catch (err: any) { - const message = err?.message ?? 'Erreur inconnue' - error.value = message - history.value = [] - return { success: false, error: message } - } finally { - loading.value = false - } - } - - return { - history, - loading, - error, - loadHistory, - } -} - diff --git a/app/composables/useEntityHistory.ts b/app/composables/useEntityHistory.ts new file mode 100644 index 0000000..12b0a5e --- /dev/null +++ b/app/composables/useEntityHistory.ts @@ -0,0 +1,69 @@ +/** + * Generic entity history composable. + * + * Replaces useComponentHistory, usePieceHistory, useProductHistory which were + * 99% identical (only the API endpoint differed). + */ + +import { ref } from 'vue' +import { useApi } from '~/composables/useApi' + +export type EntityHistoryActor = { + id: string + label: string +} + +export type EntityHistoryEntry = { + id: string + action: 'create' | 'update' | 'delete' | string + createdAt: string + actor: EntityHistoryActor | null + diff: Record | null + snapshot: Record | null +} + +const ENTITY_ENDPOINTS: Record = { + composant: '/composants', + piece: '/pieces', + product: '/products', +} + +const extractItems = (payload: any): EntityHistoryEntry[] => { + if (Array.isArray(payload?.items)) return payload.items + if (Array.isArray(payload?.member)) return payload.member + if (Array.isArray(payload?.['hydra:member'])) return payload['hydra:member'] + return [] +} + +export function useEntityHistory(entityType: 'composant' | 'piece' | 'product') { + const { get } = useApi() + const basePath = ENTITY_ENDPOINTS[entityType] + + const history = ref([]) + const loading = ref(false) + const error = ref(null) + + const loadHistory = async (entityId: string) => { + loading.value = true + error.value = null + try { + const result = await get(`${basePath}/${entityId}/history`) + if (!result.success) { + error.value = result.error ?? 'Impossible de charger l\'historique.' + history.value = [] + return result + } + history.value = extractItems(result.data) + return { success: true, data: history.value } + } catch (err: any) { + const message = err?.message ?? 'Erreur inconnue' + error.value = message + history.value = [] + return { success: false, error: message } + } finally { + loading.value = false + } + } + + return { history, loading, error, loadHistory } +} diff --git a/app/composables/usePieceHistory.ts b/app/composables/usePieceHistory.ts index 33fd9ae..7f4e607 100644 --- a/app/composables/usePieceHistory.ts +++ b/app/composables/usePieceHistory.ts @@ -1,67 +1,12 @@ -import { ref } from 'vue' -import { useApi } from '~/composables/useApi' +/** + * Backward-compatible wrapper around useEntityHistory. + * Real logic lives in useEntityHistory.ts. + */ +import { useEntityHistory, type EntityHistoryActor, type EntityHistoryEntry } from './useEntityHistory' -export type PieceHistoryActor = { - id: string - label: string +export type PieceHistoryActor = EntityHistoryActor +export type PieceHistoryEntry = EntityHistoryEntry + +export function usePieceHistory() { + return useEntityHistory('piece') } - -export type PieceHistoryEntry = { - id: string - action: 'create' | 'update' | 'delete' | string - createdAt: string - actor: PieceHistoryActor | null - diff: Record | null - snapshot: Record | null -} - -const extractItems = (payload: any): PieceHistoryEntry[] => { - if (Array.isArray(payload?.items)) { - return payload.items - } - if (Array.isArray(payload?.member)) { - return payload.member - } - if (Array.isArray(payload?.['hydra:member'])) { - return payload['hydra:member'] - } - return [] -} - -export function usePieceHistory () { - const { get } = useApi() - - const history = ref([]) - const loading = ref(false) - const error = ref(null) - - const loadHistory = async (pieceId: string) => { - loading.value = true - error.value = null - try { - const result = await get(`/pieces/${pieceId}/history`) - if (!result.success) { - error.value = result.error ?? 'Impossible de charger l’historique.' - history.value = [] - return result - } - history.value = extractItems(result.data) as PieceHistoryEntry[] - return { success: true, data: history.value } - } catch (err: any) { - const message = err?.message ?? 'Erreur inconnue' - error.value = message - history.value = [] - return { success: false, error: message } - } finally { - loading.value = false - } - } - - return { - history, - loading, - error, - loadHistory, - } -} - diff --git a/app/composables/useProductHistory.ts b/app/composables/useProductHistory.ts index 8923cf0..aa45d20 100644 --- a/app/composables/useProductHistory.ts +++ b/app/composables/useProductHistory.ts @@ -1,67 +1,12 @@ -import { ref } from 'vue' -import { useApi } from '~/composables/useApi' +/** + * Backward-compatible wrapper around useEntityHistory. + * Real logic lives in useEntityHistory.ts. + */ +import { useEntityHistory, type EntityHistoryActor, type EntityHistoryEntry } from './useEntityHistory' -export type ProductHistoryActor = { - id: string - label: string +export type ProductHistoryActor = EntityHistoryActor +export type ProductHistoryEntry = EntityHistoryEntry + +export function useProductHistory() { + return useEntityHistory('product') } - -export type ProductHistoryEntry = { - id: string - action: 'create' | 'update' | 'delete' | string - createdAt: string - actor: ProductHistoryActor | null - diff: Record | null - snapshot: Record | null -} - -const extractItems = (payload: any): ProductHistoryEntry[] => { - if (Array.isArray(payload?.items)) { - return payload.items - } - if (Array.isArray(payload?.member)) { - return payload.member - } - if (Array.isArray(payload?.['hydra:member'])) { - return payload['hydra:member'] - } - return [] -} - -export function useProductHistory () { - const { get } = useApi() - - const history = ref([]) - const loading = ref(false) - const error = ref(null) - - const loadHistory = async (productId: string) => { - loading.value = true - error.value = null - try { - const result = await get(`/products/${productId}/history`) - if (!result.success) { - error.value = result.error ?? 'Impossible de charger l’historique.' - history.value = [] - return result - } - history.value = extractItems(result.data) as ProductHistoryEntry[] - return { success: true, data: history.value } - } catch (err: any) { - const message = err?.message ?? 'Erreur inconnue' - error.value = message - history.value = [] - return { success: false, error: message } - } finally { - loading.value = false - } - } - - return { - history, - loading, - error, - loadHistory, - } -} - From a6664ce9a2d5b84b8cb5fc994850c98649ea39be Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 9 Feb 2026 11:13:39 +0100 Subject: [PATCH 137/274] refactor(composables): merge 3 type composables into generic (F2.3) Create useEntityTypes.ts with CRUD + singleton state by category. Rewrite useComponentTypes, usePieceTypes, useProductTypes as thin wrappers that rename fields for backward compatibility. Co-Authored-By: Claude Opus 4.6 --- app/composables/useComponentTypes.ts | 173 +++------------------------ app/composables/useEntityTypes.ts | 171 ++++++++++++++++++++++++++ app/composables/usePieceTypes.ts | 173 +++------------------------ app/composables/useProductTypes.ts | 166 +++---------------------- 4 files changed, 226 insertions(+), 457 deletions(-) create mode 100644 app/composables/useEntityTypes.ts diff --git a/app/composables/useComponentTypes.ts b/app/composables/useComponentTypes.ts index cd0f9bd..147acdc 100644 --- a/app/composables/useComponentTypes.ts +++ b/app/composables/useComponentTypes.ts @@ -1,164 +1,29 @@ -import { ref } from 'vue' -import { useToast } from './useToast' -import { listModelTypes, createModelType, updateModelType, deleteModelType, type ModelType } from '~/services/modelTypes' +/** + * Backward-compatible wrapper around useEntityTypes. + * Preserves the original API surface (renamed fields) so consumers need no changes. + */ +import { useEntityTypes, type EntityType } from './useEntityTypes' import type { ComponentModelStructure } from '~/shared/types/inventory' +import type { Ref } from 'vue' -export interface ComponentType extends ModelType { +export interface ComponentType extends EntityType { structure: ComponentModelStructure | null - description?: string | null } -interface ComponentTypePayload { - name: string - code?: string - description?: string | null - notes?: string | null - structure?: ComponentModelStructure | null -} - -interface ComponentTypeResult { - success: boolean - data?: ComponentType | ComponentType[] - error?: string -} - -const componentTypes = ref([]) -const loadingComponentTypes = ref(false) - export function useComponentTypes() { - const { showSuccess, showError } = useToast() - - const generateCodeFromName = (name: string): string => { - return (name || '') - .normalize('NFD') - .replace(/[\u0300-\u036F]/g, '') - .toLowerCase() - .replace(/[^a-z0-9]+/g, '-') - .replace(/^-+|-+$/g, '') - .replace(/-+/g, '-') || 'type' - } - - const loadComponentTypes = async (): Promise => { - loadingComponentTypes.value = true - try { - const data = await listModelTypes({ - category: 'COMPONENT', - sort: 'name', - dir: 'asc', - limit: 200, - }) - - componentTypes.value = data.items.map((item) => ({ - ...item, - structure: item.structure as ComponentModelStructure | null, - description: item.description ?? item.notes ?? null, - })) - - return { success: true, data: componentTypes.value } - } catch (error) { - const err = error as Error & { message?: string } - const message = err?.message || 'Erreur inconnue' - showError(`Impossible de charger les types de composant: ${message}`) - return { success: false, error: message } - } finally { - loadingComponentTypes.value = false - } - } - - const createComponentType = async (payload: ComponentTypePayload): Promise => { - loadingComponentTypes.value = true - try { - const data = await createModelType({ - name: payload.name, - code: payload.code || generateCodeFromName(payload.name), - category: 'COMPONENT', - notes: payload.description ?? payload.notes ?? undefined, - description: payload.description ?? undefined, - structure: payload.structure ?? undefined, - }) - - const normalized: ComponentType = { - ...data, - structure: data.structure as ComponentModelStructure | null, - description: data.description ?? data.notes ?? null, - } - - componentTypes.value.push(normalized) - showSuccess(`Type de composant "${data.name}" créé`) - - return { success: true, data: normalized } - } catch (error) { - const err = error as Error & { data?: { message?: string }; message?: string } - const message = err?.data?.message || err?.message || 'Erreur inconnue' - showError(`Erreur lors de la création du type de composant: ${message}`) - return { success: false, error: message } - } finally { - loadingComponentTypes.value = false - } - } - - const updateComponentType = async (id: string, payload: ComponentTypePayload): Promise => { - loadingComponentTypes.value = true - try { - const data = await updateModelType(id, { - name: payload.name, - description: payload.description ?? undefined, - notes: payload.notes ?? undefined, - code: payload.code, - structure: payload.structure ?? undefined, - }) - - const normalized: ComponentType = { - ...data, - structure: data.structure as ComponentModelStructure | null, - description: data.description ?? data.notes ?? null, - } - - const index = componentTypes.value.findIndex((type) => type.id === id) - if (index !== -1) { - componentTypes.value[index] = normalized - } - showSuccess(`Type de composant "${data.name}" mis à jour`) - - return { success: true, data: normalized } - } catch (error) { - const err = error as Error & { data?: { message?: string }; message?: string } - const message = err?.data?.message || err?.message || 'Erreur inconnue' - showError(`Erreur lors de la mise à jour du type de composant: ${message}`) - return { success: false, error: message } - } finally { - loadingComponentTypes.value = false - } - } - - const deleteComponentType = async (id: string): Promise => { - loadingComponentTypes.value = true - try { - await deleteModelType(id) - componentTypes.value = componentTypes.value.filter((type) => type.id !== id) - showSuccess('Type de composant supprimé') - return { success: true } - } catch (error) { - const err = error as Error & { data?: { message?: string }; message?: string } - const message = err?.data?.message || err?.message || 'Erreur inconnue' - showError(`Erreur lors de la suppression du type de composant: ${message}`) - return { success: false, error: message } - } finally { - loadingComponentTypes.value = false - } - } - - const getComponentTypes = () => componentTypes.value - const isComponentTypeLoading = () => loadingComponentTypes.value + const { types, loading, loadTypes, createType, updateType, deleteType } = useEntityTypes({ + category: 'COMPONENT', + label: 'composant', + }) return { - componentTypes, - loadingComponentTypes, - loadComponentTypes, - createComponentType, - updateComponentType, - deleteComponentType, - getComponentTypes, - isComponentTypeLoading, + componentTypes: types as Ref, + loadingComponentTypes: loading, + loadComponentTypes: loadTypes, + createComponentType: createType, + updateComponentType: updateType, + deleteComponentType: deleteType, + getComponentTypes: () => types.value as ComponentType[], + isComponentTypeLoading: () => loading.value, } } diff --git a/app/composables/useEntityTypes.ts b/app/composables/useEntityTypes.ts new file mode 100644 index 0000000..f6dfc21 --- /dev/null +++ b/app/composables/useEntityTypes.ts @@ -0,0 +1,171 @@ +/** + * Generic entity types composable. + * + * Replaces useComponentTypes, usePieceTypes, useProductTypes which were + * 95%+ identical (only the category string and labels differed). + */ + +import { ref, type Ref } from 'vue' +import { useToast } from './useToast' +import { + listModelTypes, + createModelType, + updateModelType, + deleteModelType, + type ModelType, + type ModelCategory, +} from '~/services/modelTypes' + +export interface EntityType extends ModelType { + description?: string | null +} + +interface EntityTypePayload { + name: string + code?: string + description?: string | null + notes?: string | null + structure?: any +} + +interface EntityTypeResult { + success: boolean + data?: EntityType | EntityType[] + error?: string +} + +interface EntityTypeConfig { + category: ModelCategory + label: string // e.g. 'composant', 'pièce', 'produit' +} + +const generateCodeFromName = (name: string): string => { + return (name || '') + .normalize('NFD') + .replace(/[\u0300-\u036F]/g, '') + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, '') + .replace(/-+/g, '-') || 'type' +} + +// Shared state per category (module-level singletons) +const stateByCategory: Record; loading: Ref }> = {} + +function getOrCreateState(category: ModelCategory) { + if (!stateByCategory[category]) { + stateByCategory[category] = { + types: ref([]), + loading: ref(false), + } + } + return stateByCategory[category] +} + +export function useEntityTypes(config: EntityTypeConfig) { + const { category, label } = config + const { showSuccess, showError } = useToast() + const state = getOrCreateState(category) + + const normalizeItem = (item: ModelType): EntityType => ({ + ...item, + description: item.description ?? item.notes ?? null, + }) + + const loadTypes = async (): Promise => { + state.loading.value = true + try { + const data = await listModelTypes({ + category, + sort: 'name', + dir: 'asc', + limit: 200, + }) + state.types.value = data.items.map(normalizeItem) + return { success: true, data: state.types.value } + } catch (error) { + const err = error as Error & { message?: string } + const message = err?.message || 'Erreur inconnue' + showError(`Impossible de charger les types de ${label}: ${message}`) + return { success: false, error: message } + } finally { + state.loading.value = false + } + } + + const createType = async (payload: EntityTypePayload): Promise => { + state.loading.value = true + try { + const data = await createModelType({ + name: payload.name, + code: payload.code || generateCodeFromName(payload.name), + category, + notes: payload.description ?? payload.notes ?? undefined, + description: payload.description ?? undefined, + structure: payload.structure ?? undefined, + }) + const normalized = normalizeItem(data) + state.types.value.push(normalized) + showSuccess(`Type de ${label} "${data.name}" créé`) + return { success: true, data: normalized } + } catch (error) { + const err = error as Error & { data?: { message?: string }; message?: string } + const message = err?.data?.message || err?.message || 'Erreur inconnue' + showError(`Erreur lors de la création du type de ${label}: ${message}`) + return { success: false, error: message } + } finally { + state.loading.value = false + } + } + + const updateType = async (id: string, payload: EntityTypePayload): Promise => { + state.loading.value = true + try { + const data = await updateModelType(id, { + name: payload.name, + description: payload.description ?? undefined, + notes: payload.notes ?? undefined, + code: payload.code, + structure: payload.structure ?? undefined, + }) + const normalized = normalizeItem(data) + const index = state.types.value.findIndex((t) => t.id === id) + if (index !== -1) state.types.value[index] = normalized + showSuccess(`Type de ${label} "${data.name}" mis à jour`) + return { success: true, data: normalized } + } catch (error) { + const err = error as Error & { data?: { message?: string }; message?: string } + const message = err?.data?.message || err?.message || 'Erreur inconnue' + showError(`Erreur lors de la mise à jour du type de ${label}: ${message}`) + return { success: false, error: message } + } finally { + state.loading.value = false + } + } + + const deleteType = async (id: string): Promise => { + state.loading.value = true + try { + await deleteModelType(id) + state.types.value = state.types.value.filter((t) => t.id !== id) + showSuccess(`Type de ${label} supprimé`) + return { success: true } + } catch (error) { + const err = error as Error & { data?: { message?: string }; message?: string } + const message = err?.data?.message || err?.message || 'Erreur inconnue' + showError(`Erreur lors de la suppression du type de ${label}: ${message}`) + return { success: false, error: message } + } finally { + state.loading.value = false + } + } + + return { + types: state.types, + loading: state.loading, + loadTypes, + createType, + updateType, + deleteType, + } +} diff --git a/app/composables/usePieceTypes.ts b/app/composables/usePieceTypes.ts index b44898f..6347833 100644 --- a/app/composables/usePieceTypes.ts +++ b/app/composables/usePieceTypes.ts @@ -1,164 +1,29 @@ -import { ref } from 'vue' -import { useToast } from './useToast' -import { listModelTypes, createModelType, updateModelType, deleteModelType, type ModelType } from '~/services/modelTypes' +/** + * Backward-compatible wrapper around useEntityTypes. + * Preserves the original API surface (renamed fields) so consumers need no changes. + */ +import { useEntityTypes, type EntityType } from './useEntityTypes' import type { PieceModelStructure } from '~/shared/types/inventory' +import type { Ref } from 'vue' -export interface PieceType extends ModelType { +export interface PieceType extends EntityType { structure: PieceModelStructure | null - description?: string | null } -interface PieceTypePayload { - name: string - code?: string - description?: string | null - notes?: string | null - structure?: PieceModelStructure | null -} - -interface PieceTypeResult { - success: boolean - data?: PieceType | PieceType[] - error?: string -} - -const pieceTypes = ref([]) -const loadingPieceTypes = ref(false) - export function usePieceTypes() { - const { showSuccess, showError } = useToast() - - const generateCodeFromName = (name: string): string => { - return (name || '') - .normalize('NFD') - .replace(/[\u0300-\u036F]/g, '') - .toLowerCase() - .replace(/[^a-z0-9]+/g, '-') - .replace(/^-+|-+$/g, '') - .replace(/-+/g, '-') || 'type' - } - - const loadPieceTypes = async (): Promise => { - loadingPieceTypes.value = true - try { - const data = await listModelTypes({ - category: 'PIECE', - sort: 'name', - dir: 'asc', - limit: 200, - }) - - pieceTypes.value = data.items.map((item) => ({ - ...item, - structure: item.structure as PieceModelStructure | null, - description: item.description ?? item.notes ?? null, - })) - - return { success: true, data: pieceTypes.value } - } catch (error) { - const err = error as Error & { message?: string } - const message = err?.message || 'Erreur inconnue' - showError(`Impossible de charger les types de pièce: ${message}`) - return { success: false, error: message } - } finally { - loadingPieceTypes.value = false - } - } - - const createPieceType = async (payload: PieceTypePayload): Promise => { - loadingPieceTypes.value = true - try { - const data = await createModelType({ - name: payload.name, - code: payload.code || generateCodeFromName(payload.name), - category: 'PIECE', - notes: payload.description ?? payload.notes ?? undefined, - description: payload.description ?? undefined, - structure: payload.structure ?? undefined, - }) - - const normalized: PieceType = { - ...data, - structure: data.structure as PieceModelStructure | null, - description: data.description ?? data.notes ?? null, - } - - pieceTypes.value.push(normalized) - showSuccess(`Type de pièce "${data.name}" créé`) - - return { success: true, data: normalized } - } catch (error) { - const err = error as Error & { data?: { message?: string }; message?: string } - const message = err?.data?.message || err?.message || 'Erreur inconnue' - showError(`Erreur lors de la création du type de pièce: ${message}`) - return { success: false, error: message } - } finally { - loadingPieceTypes.value = false - } - } - - const updatePieceType = async (id: string, payload: PieceTypePayload): Promise => { - loadingPieceTypes.value = true - try { - const data = await updateModelType(id, { - name: payload.name, - description: payload.description ?? undefined, - notes: payload.notes ?? undefined, - code: payload.code, - structure: payload.structure ?? undefined, - }) - - const normalized: PieceType = { - ...data, - structure: data.structure as PieceModelStructure | null, - description: data.description ?? data.notes ?? null, - } - - const index = pieceTypes.value.findIndex((type) => type.id === id) - if (index !== -1) { - pieceTypes.value[index] = normalized - } - showSuccess(`Type de pièce "${data.name}" mis à jour`) - - return { success: true, data: normalized } - } catch (error) { - const err = error as Error & { data?: { message?: string }; message?: string } - const message = err?.data?.message || err?.message || 'Erreur inconnue' - showError(`Erreur lors de la mise à jour du type de pièce: ${message}`) - return { success: false, error: message } - } finally { - loadingPieceTypes.value = false - } - } - - const deletePieceType = async (id: string): Promise => { - loadingPieceTypes.value = true - try { - await deleteModelType(id) - pieceTypes.value = pieceTypes.value.filter((type) => type.id !== id) - showSuccess('Type de pièce supprimé') - return { success: true } - } catch (error) { - const err = error as Error & { data?: { message?: string }; message?: string } - const message = err?.data?.message || err?.message || 'Erreur inconnue' - showError(`Erreur lors de la suppression du type de pièce: ${message}`) - return { success: false, error: message } - } finally { - loadingPieceTypes.value = false - } - } - - const getPieceTypes = () => pieceTypes.value - const isPieceTypeLoading = () => loadingPieceTypes.value + const { types, loading, loadTypes, createType, updateType, deleteType } = useEntityTypes({ + category: 'PIECE', + label: 'pièce', + }) return { - pieceTypes, - loadingPieceTypes, - loadPieceTypes, - createPieceType, - updatePieceType, - deletePieceType, - getPieceTypes, - isPieceTypeLoading, + pieceTypes: types as Ref, + loadingPieceTypes: loading, + loadPieceTypes: loadTypes, + createPieceType: createType, + updatePieceType: updateType, + deletePieceType: deleteType, + getPieceTypes: () => types.value as PieceType[], + isPieceTypeLoading: () => loading.value, } } diff --git a/app/composables/useProductTypes.ts b/app/composables/useProductTypes.ts index 7489fe7..5c8904f 100644 --- a/app/composables/useProductTypes.ts +++ b/app/composables/useProductTypes.ts @@ -1,159 +1,27 @@ -import { ref } from 'vue' -import { useToast } from './useToast' -import { listModelTypes, createModelType, updateModelType, deleteModelType, type ModelType } from '~/services/modelTypes' +/** + * Backward-compatible wrapper around useEntityTypes. + * Preserves the original API surface (renamed fields) so consumers need no changes. + */ +import { useEntityTypes, type EntityType } from './useEntityTypes' import type { ProductModelStructure } from '~/shared/types/inventory' +import type { Ref } from 'vue' -export interface ProductType extends ModelType { +export interface ProductType extends EntityType { structure: ProductModelStructure | null - description?: string | null } -interface ProductTypePayload { - name: string - code?: string - description?: string | null - notes?: string | null - structure?: ProductModelStructure | null -} - -interface ProductTypeResult { - success: boolean - data?: ProductType | ProductType[] - error?: string -} - -const productTypes = ref([]) -const loadingProductTypes = ref(false) - export function useProductTypes() { - const { showSuccess, showError } = useToast() - - const generateCodeFromName = (name: string): string => { - return (name || '') - .normalize('NFD') - .replace(/[\u0300-\u036F]/g, '') - .toLowerCase() - .replace(/[^a-z0-9]+/g, '-') - .replace(/^-+|-+$/g, '') - .replace(/-+/g, '-') || 'type' - } - - const loadProductTypes = async (): Promise => { - loadingProductTypes.value = true - try { - const data = await listModelTypes({ - category: 'PRODUCT', - sort: 'name', - dir: 'asc', - limit: 200, - }) - - productTypes.value = data.items.map((item) => ({ - ...item, - structure: item.structure as ProductModelStructure | null, - description: item.description ?? item.notes ?? null, - })) - - return { success: true, data: productTypes.value } - } catch (error) { - const err = error as Error & { message?: string } - const message = err?.message || 'Erreur inconnue' - showError(`Impossible de charger les types de produit: ${message}`) - return { success: false, error: message } - } finally { - loadingProductTypes.value = false - } - } - - const createProductType = async (payload: ProductTypePayload): Promise => { - loadingProductTypes.value = true - try { - const data = await createModelType({ - name: payload.name, - code: payload.code || generateCodeFromName(payload.name), - category: 'PRODUCT', - notes: payload.description ?? payload.notes ?? undefined, - description: payload.description ?? undefined, - structure: payload.structure ?? undefined, - }) - - const normalized: ProductType = { - ...data, - structure: data.structure as ProductModelStructure | null, - description: data.description ?? data.notes ?? null, - } - - productTypes.value.push(normalized) - showSuccess(`Type de produit "${data.name}" créé`) - - return { success: true, data: normalized } - } catch (error) { - const err = error as Error & { data?: { message?: string }; message?: string } - const message = err?.data?.message || err?.message || 'Erreur inconnue' - showError(`Erreur lors de la création du type de produit: ${message}`) - return { success: false, error: message } - } finally { - loadingProductTypes.value = false - } - } - - const updateProductType = async (id: string, payload: ProductTypePayload): Promise => { - loadingProductTypes.value = true - try { - const data = await updateModelType(id, { - name: payload.name, - description: payload.description ?? undefined, - notes: payload.notes ?? undefined, - code: payload.code, - structure: payload.structure ?? undefined, - }) - - const normalized: ProductType = { - ...data, - structure: data.structure as ProductModelStructure | null, - description: data.description ?? data.notes ?? null, - } - - const index = productTypes.value.findIndex((type) => type.id === id) - if (index !== -1) { - productTypes.value[index] = normalized - } - showSuccess(`Type de produit "${data.name}" mis à jour`) - - return { success: true, data: normalized } - } catch (error) { - const err = error as Error & { data?: { message?: string }; message?: string } - const message = err?.data?.message || err?.message || 'Erreur inconnue' - showError(`Erreur lors de la mise à jour du type de produit: ${message}`) - return { success: false, error: message } - } finally { - loadingProductTypes.value = false - } - } - - const deleteProductType = async (id: string): Promise => { - loadingProductTypes.value = true - try { - await deleteModelType(id) - productTypes.value = productTypes.value.filter((type) => type.id !== id) - showSuccess('Type de produit supprimé') - return { success: true } - } catch (error) { - const err = error as Error & { data?: { message?: string }; message?: string } - const message = err?.data?.message || err?.message || 'Erreur inconnue' - showError(`Erreur lors de la suppression du type de produit: ${message}`) - return { success: false, error: message } - } finally { - loadingProductTypes.value = false - } - } + const { types, loading, loadTypes, createType, updateType, deleteType } = useEntityTypes({ + category: 'PRODUCT', + label: 'produit', + }) return { - productTypes, - loadingProductTypes, - loadProductTypes, - createProductType, - updateProductType, - deleteProductType, + productTypes: types as Ref, + loadingProductTypes: loading, + loadProductTypes: loadTypes, + createProductType: createType, + updateProductType: updateType, + deleteProductType: deleteType, } } From efe1fd2a733a0a300abb3a50850dc219ab898150 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 9 Feb 2026 11:13:50 +0100 Subject: [PATCH 138/274] refactor(types): eliminate explicit any casts across components (F3.3) Extend ComponentModelPiece/Product with optional typePiece/typeProduct nested objects. Replace 12 'as any' casts in assignment node, convert Promise to Promise, use Record at API boundaries. ~15 casts eliminated. Co-Authored-By: Claude Opus 4.6 --- .../ComponentModelStructureEditor.vue | 6 +-- .../ComponentStructureAssignmentNode.vue | 37 ++++--------- app/components/model-types/ManagementView.vue | 53 ++++++++----------- app/components/model-types/ModelTypeForm.vue | 5 +- app/shared/types/inventory.ts | 11 ++-- 5 files changed, 46 insertions(+), 66 deletions(-) diff --git a/app/components/ComponentModelStructureEditor.vue b/app/components/ComponentModelStructureEditor.vue index 14869e2..40b6905 100644 --- a/app/components/ComponentModelStructureEditor.vue +++ b/app/components/ComponentModelStructureEditor.vue @@ -115,7 +115,7 @@ const applyCustomFieldOptions = (node: Record | null | undefined) = } if (Array.isArray(node.customFields)) { - node.customFields = node.customFields.map((field: any) => { + node.customFields = node.customFields.map((field: Record) => { if (!field || typeof field !== 'object') { return field } @@ -145,7 +145,7 @@ const applyCustomFieldOptions = (node: Record | null | undefined) = } if (Array.isArray(node.subcomponents)) { - node.subcomponents = node.subcomponents.map((sub: any) => { + node.subcomponents = node.subcomponents.map((sub: Record) => { if (!sub || typeof sub !== 'object') { return sub } @@ -246,7 +246,7 @@ watch( ) onMounted(async () => { - const loaders: Promise[] = [] + const loaders: Promise[] = [] if (!availablePieceTypes.value.length) { loaders.push(loadPieceTypes()) } diff --git a/app/components/ComponentStructureAssignmentNode.vue b/app/components/ComponentStructureAssignmentNode.vue index 2d6b86c..c9f3037 100644 --- a/app/components/ComponentStructureAssignmentNode.vue +++ b/app/components/ComponentStructureAssignmentNode.vue @@ -137,6 +137,7 @@ import { computed, ref, watch } from 'vue'; import SearchSelect from '~/components/common/SearchSelect.vue'; import { useApi } from '~/composables/useApi'; +import { extractCollection } from '~/shared/utils/apiHelpers'; import type { ComponentModelPiece, ComponentModelProduct, @@ -243,22 +244,6 @@ const pieceLoadingByPath = ref>({}); const productLoadingByPath = ref>({}); const componentLoadingByPath = ref>({}); -const extractCollection = (payload: any): any[] => { - if (Array.isArray(payload)) { - return payload; - } - if (Array.isArray(payload?.member)) { - return payload.member; - } - if (Array.isArray(payload?.['hydra:member'])) { - return payload['hydra:member']; - } - if (Array.isArray(payload?.data)) { - return payload.data; - } - return []; -}; - const setLoading = (target: Record, key: string, value: boolean) => { target[key] = value; }; @@ -362,7 +347,7 @@ const fetchPieceOptions = async (assignment: StructurePieceAssignment, term = '' const definition = assignment.definition || {}; const requiredTypeId = - definition.typePieceId || (definition as any).typePiece?.id || null; + definition.typePieceId || definition.typePiece?.id || null; const params = new URLSearchParams(); params.set('itemsPerPage', '50'); @@ -392,7 +377,7 @@ const fetchProductOptions = async (assignment: StructureProductAssignment, term const definition = assignment.definition || {}; const requiredTypeId = - definition.typeProductId || (definition as any).typeProduct?.id || null; + definition.typeProductId || definition.typeProduct?.id || null; const params = new URLSearchParams(); params.set('itemsPerPage', '50'); @@ -447,14 +432,14 @@ const describePieceRequirement = (assignment: StructurePieceAssignment) => { addPart(definition.role); const explicitLabel = definition.typePieceLabel || - (definition as any).typePiece?.name || + definition.typePiece?.name || (definition.typePieceId ? props.pieceTypeLabelMap[definition.typePieceId] : null) || fallbackType?.name; addPart(explicitLabel); const family = definition.familyCode || - (definition as any).typePiece?.code || + definition.typePiece?.code || fallbackType?.code || null; if (family) { @@ -483,7 +468,7 @@ const getProductOptions = (assignment: StructureProductAssignment) => { const definition = assignment.definition; const requiredTypeId = definition.typeProductId || - (definition as any).typeProduct?.id || + definition.typeProduct?.id || definition.familyCode || null; @@ -494,7 +479,7 @@ const getProductOptions = (assignment: StructureProductAssignment) => { if (!requiredTypeId) { return true; } - if (definition.typeProductId || (definition as any).typeProduct?.id) { + if (definition.typeProductId || definition.typeProduct?.id) { return ( product.typeProductId === requiredTypeId || product.typeProduct?.id === requiredTypeId @@ -550,14 +535,14 @@ const describeProductRequirement = (assignment: StructureProductAssignment) => { addPart(definition.role); const explicitLabel = definition.typeProductLabel || - (definition as any).typeProduct?.name || + definition.typeProduct?.name || (definition.typeProductId ? props.productTypeLabelMap[definition.typeProductId] : null) || fallbackType?.name; addPart(explicitLabel); const family = definition.familyCode || - (definition as any).typeProduct?.code || + definition.typeProduct?.code || fallbackType?.code || null; if (family) { @@ -617,7 +602,7 @@ const getPieceOptions = (assignment: StructurePieceAssignment) => { const definition = assignment.definition; const requiredTypeId = definition.typePieceId || - (definition as any).typePiece?.id || + definition.typePiece?.id || definition.familyCode || null; @@ -628,7 +613,7 @@ const getPieceOptions = (assignment: StructurePieceAssignment) => { if (!requiredTypeId) { return true; } - if (definition.typePieceId || (definition as any).typePiece?.id) { + if (definition.typePieceId || definition.typePiece?.id) { return ( piece.typePieceId === requiredTypeId || piece.typePiece?.id === requiredTypeId diff --git a/app/components/model-types/ManagementView.vue b/app/components/model-types/ManagementView.vue index c88b553..4261cf9 100644 --- a/app/components/model-types/ManagementView.vue +++ b/app/components/model-types/ManagementView.vue @@ -97,6 +97,7 @@ import { useHead, useRouter } from "#imports"; import ModelTypesToolbar from "~/components/model-types/Toolbar.vue"; import ModelTypesTable from "~/components/model-types/Table.vue"; import { useApi } from "~/composables/useApi"; +import { extractCollection } from "~/shared/utils/apiHelpers"; import { deleteModelType, listModelTypes, @@ -153,7 +154,7 @@ useHead(() => ({ const extractErrorMessage = (error: unknown) => { if (error && typeof error === "object") { const maybeFetchError = error as { - data?: any; + data?: Record; statusMessage?: string; message?: string; }; @@ -208,8 +209,8 @@ const refresh = async ({ total.value = response.total; offset.value = response.offset; limit.value = response.limit; - } catch (error: any) { - if (error?.name === "AbortError") { + } catch (error: unknown) { + if (error && typeof error === "object" && (error as { name?: string }).name === "AbortError") { return; } showError(extractErrorMessage(error)); @@ -292,10 +293,12 @@ const openEditPage = (item: ModelType) => { }); }; +const { confirm } = useConfirm() + const confirmDelete = async (item: ModelType) => { - const confirmed = window.confirm( - "Supprimer ce type ? Cette action est irréversible." - ); + const confirmed = await confirm({ + message: 'Supprimer ce type ? Cette action est irréversible.', + }); if (!confirmed) { return; } @@ -363,22 +366,6 @@ const relatedModalSubtitle = computed(() => { return `${count} ${labels.plural} liés.`; }); -const extractCollection = (payload: any): any[] => { - if (Array.isArray(payload)) { - return payload; - } - if (Array.isArray(payload?.member)) { - return payload.member; - } - if (Array.isArray(payload?.["hydra:member"])) { - return payload["hydra:member"]; - } - if (Array.isArray(payload?.items)) { - return payload.items; - } - return []; -}; - const buildModelTypeIri = (id: string) => `/api/model_types/${id}`; const resolveRelatedConfig = (category: ModelCategory) => { @@ -401,22 +388,26 @@ const resolveRelatedEditBasePath = (category: ModelCategory) => { return "/product"; }; -const mapRelatedEntry = (item: any): RelatedEntry | null => { - if (!item || typeof item !== "object" || typeof item.id !== "string") { +const mapRelatedEntry = (item: unknown): RelatedEntry | null => { + if (!item || typeof item !== "object") { + return null; + } + const record = item as Record; + if (typeof record.id !== "string") { return null; } const name = - typeof item.name === "string" && item.name.trim() - ? item.name + typeof record.name === "string" && record.name.trim() + ? record.name : "Sans nom"; const reference = - typeof item.reference === "string" && item.reference.trim() - ? item.reference - : typeof item.code === "string" && item.code.trim() - ? item.code + typeof record.reference === "string" && record.reference.trim() + ? record.reference + : typeof record.code === "string" && record.code.trim() + ? record.code : null; return { - id: item.id, + id: record.id, name, reference, }; diff --git a/app/components/model-types/ModelTypeForm.vue b/app/components/model-types/ModelTypeForm.vue index b4ca544..a6ac478 100644 --- a/app/components/model-types/ModelTypeForm.vue +++ b/app/components/model-types/ModelTypeForm.vue @@ -278,10 +278,11 @@ const resetForm = () => { ? incoming.code : generateCodeFromName(form.name) form.category = incoming.category ?? props.initialCategory + const incomingRecord = incoming as Record form.notes = typeof incoming.notes === 'string' ? incoming.notes - : typeof (incoming as any).description === 'string' - ? (incoming as any).description + : typeof incomingRecord.description === 'string' + ? incomingRecord.description : '' errors.name = undefined diff --git a/app/shared/types/inventory.ts b/app/shared/types/inventory.ts index b462f91..a99b335 100644 --- a/app/shared/types/inventory.ts +++ b/app/shared/types/inventory.ts @@ -17,6 +17,7 @@ export interface ComponentModelCustomField { export interface ComponentModelPiece { typePieceId?: string typePieceLabel?: string + typePiece?: { id?: string; name?: string; code?: string } | null reference?: string familyCode?: string role?: string @@ -25,6 +26,7 @@ export interface ComponentModelPiece { export interface ComponentModelProduct { typeProductId?: string typeProductLabel?: string + typeProduct?: { id?: string; name?: string; code?: string } | null reference?: string familyCode?: string role?: string @@ -33,6 +35,7 @@ export interface ComponentModelProduct { export interface ComponentModelStructureNode { typeComposantId?: string typeComposantLabel?: string + typeComposant?: { id?: string; name?: string } modelId?: string familyCode?: string alias?: string @@ -151,8 +154,8 @@ const validatePiece = ( const typePieceId = ensureString(value.typePieceId) const typePieceLabel = ensureString(value.typePieceLabel) const reference = ensureString(value.reference) - const familyCode = ensureString((value as any).familyCode) - const role = ensureString((value as any).role) + const familyCode = ensureString(value.familyCode) + const role = ensureString(value.role) if (!typePieceId && !typePieceLabel && !reference && !familyCode) { issues.push(`${path}: au moins un identifiant, une famille ou une référence de pièce est requis`) @@ -184,8 +187,8 @@ const validateStructureNode = ( const familyCode = ensureString(value.familyCode) const alias = ensureString(value.alias) - const rawSubcomponents = Array.isArray((value as any).subcomponents) - ? (value as any).subcomponents + const rawSubcomponents = Array.isArray(value.subcomponents) + ? value.subcomponents : [] const subcomponents: ComponentModelStructureNode[] = [] From 3436cd0b90ebbd6e55b6ba1f5f9a6d034e637d59 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 9 Feb 2026 11:14:05 +0100 Subject: [PATCH 139/274] chore: remove 19 debug console.log statements (F4.2) Remove all console.log/warn/debug/info from production code across 6 files. Keep console.error for legitimate error handling (72 instances). Co-Authored-By: Claude Opus 4.6 --- app/components/TypeEditPieceRequirementsSection.vue | 8 +------- app/components/common/SearchSelect.vue | 3 +-- app/pages/type/[id].vue | 10 ---------- app/pages/type/edit/[id].vue | 7 ------- 4 files changed, 2 insertions(+), 26 deletions(-) diff --git a/app/components/TypeEditPieceRequirementsSection.vue b/app/components/TypeEditPieceRequirementsSection.vue index 9d530f0..1ba9486 100644 --- a/app/components/TypeEditPieceRequirementsSection.vue +++ b/app/components/TypeEditPieceRequirementsSection.vue @@ -12,7 +12,7 @@ diff --git a/app/components/common/SearchSelect.vue b/app/components/common/SearchSelect.vue index c56de77..0299d20 100644 --- a/app/components/common/SearchSelect.vue +++ b/app/components/common/SearchSelect.vue @@ -184,8 +184,7 @@ watch( watch( baseOptions, - (newOptions) => { - console.log('[SearchSelect] baseOptions changed, count:', newOptions.length, 'modelValue:', props.modelValue, 'selectedOption:', selectedOption.value?.id) + (_newOptions) => { if (!openDropdown.value && selectedOption.value) { searchTerm.value = resolveLabel(selectedOption.value) } diff --git a/app/pages/type/[id].vue b/app/pages/type/[id].vue index cdaf9b5..a5aa53a 100644 --- a/app/pages/type/[id].vue +++ b/app/pages/type/[id].vue @@ -185,25 +185,16 @@ const toDisplayCount = (value, fallback) => { onMounted(async () => { try { const typeId = route.params.id - console.log('=== TYPE DETAIL PAGE LOADING ===') - console.log('Loading type with ID:', typeId) - console.log('Full route params:', route.params) - if (!typeId) { - console.error('No type ID provided in route') showError('Aucun identifiant de type fourni') loading.value = false return } const result = await getMachineTypeById(typeId) - console.log('API Result:', result) - if (result.success) { type.value = result.data - console.log('Type loaded successfully:', type.value) } else { - console.error('Failed to load type:', result.error) showError('Type non trouvé') } } catch (error) { @@ -211,7 +202,6 @@ onMounted(async () => { showError('Erreur lors du chargement') } finally { loading.value = false - console.log('Loading finished, loading.value:', loading.value) } }) diff --git a/app/pages/type/edit/[id].vue b/app/pages/type/edit/[id].vue index df14c07..c01807e 100644 --- a/app/pages/type/edit/[id].vue +++ b/app/pages/type/edit/[id].vue @@ -206,15 +206,9 @@ const saveChanges = async () => { onMounted(async () => { try { const typeId = route.params.id - console.log('=== EDIT TYPE PAGE LOADING ===') - console.log('Loading type with ID:', typeId) - const result = await getMachineTypeById(typeId, true) - console.log('API Result:', result) - if (result.success) { type.value = result.data - console.log('Type loaded successfully:', type.value) // Initialiser les données éditées editedType.value = { @@ -236,7 +230,6 @@ onMounted(async () => { showError('Erreur lors du chargement') } finally { loading.value = false - console.log('Loading finished, loading.value:', loading.value) } }) From 786b1d91f645f7a9ff9b351aa42adba1162f354d Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 9 Feb 2026 11:14:15 +0100 Subject: [PATCH 140/274] refactor(model): split modelUtils.ts into 3 thematic modules (F5.1) Split 1017 LOC monolith into: - shared/model/componentStructure.ts (~590 LOC) - shared/model/pieceProductStructure.ts (~155 LOC) - shared/model/definitionOverrides.ts (~50 LOC) Rewrite modelUtils.ts as 37 LOC barrel re-export for backward compat. All 11 consumer files unchanged. Co-Authored-By: Claude Opus 4.6 --- app/shared/model/componentStructure.ts | 794 ++++++++++++++++ app/shared/model/definitionOverrides.ts | 49 + app/shared/model/pieceProductStructure.ts | 177 ++++ app/shared/modelUtils.ts | 1053 +-------------------- 4 files changed, 1056 insertions(+), 1017 deletions(-) create mode 100644 app/shared/model/componentStructure.ts create mode 100644 app/shared/model/definitionOverrides.ts create mode 100644 app/shared/model/pieceProductStructure.ts diff --git a/app/shared/model/componentStructure.ts b/app/shared/model/componentStructure.ts new file mode 100644 index 0000000..d4192f4 --- /dev/null +++ b/app/shared/model/componentStructure.ts @@ -0,0 +1,794 @@ +import { + createEmptyComponentModelStructure, + type ComponentModelCustomFieldType, + type ComponentModelCustomField, + type ComponentModelPiece, + type ComponentModelProduct, + type ComponentModelStructure, + type ComponentModelStructureNode, +} from '../types/inventory' + +export const isPlainObject = (value: unknown): value is Record => { + return value !== null && typeof value === 'object' && !Array.isArray(value) +} + +export interface ModelStructurePreview { + customFields: number + pieces: number + products: number + subcomponents: number +} + +export const defaultStructure = (): ComponentModelStructure => ({ + ...createEmptyComponentModelStructure(), +}) + +const ensureStructureShape = (input: any): ComponentModelStructure => { + const base = createEmptyComponentModelStructure() + if (!isPlainObject(input)) { + return base + } + + const clone: ComponentModelStructure = { + ...base, + customFields: Array.isArray((input as any).customFields) ? (input as any).customFields : [], + pieces: Array.isArray((input as any).pieces) ? (input as any).pieces : [], + products: Array.isArray((input as any).products) ? (input as any).products : [], + subcomponents: Array.isArray((input as any).subcomponents) + ? (input as any).subcomponents + : Array.isArray((input as any).subComponents) + ? (input as any).subComponents + : [], + typeComposantId: typeof (input as any).typeComposantId === 'string' ? (input as any).typeComposantId : undefined, + typeComposantLabel: typeof (input as any).typeComposantLabel === 'string' + ? (input as any).typeComposantLabel + : undefined, + modelId: typeof (input as any).modelId === 'string' ? (input as any).modelId : undefined, + familyCode: typeof (input as any).familyCode === 'string' ? (input as any).familyCode : undefined, + alias: typeof (input as any).alias === 'string' ? (input as any).alias : undefined, + } + + return clone +} + +export const cloneStructure = (input: any): ComponentModelStructure => { + try { + const cloned = JSON.parse(JSON.stringify(input ?? defaultStructure())) + return ensureStructureShape(cloned) + } catch (_error) { + return defaultStructure() + } +} + +export const toStringArray = (input: unknown): string[] | undefined => { + if (!Array.isArray(input)) { + return undefined + } + const parsed = input + .map((value) => { + if (typeof value === 'string') { + return value.trim() + } + if (value === null || value === undefined) { + return '' + } + return String(value).trim() + }) + .filter((value) => value.length > 0) + return parsed.length ? parsed : undefined +} + +export const extractFieldValueObject = (field: any): Record => { + if (isPlainObject(field?.value)) { + return field.value as Record + } + return {} +} + +export const sanitizeCustomFields = (fields: any[]): ComponentModelCustomField[] => { + if (!Array.isArray(fields)) { + return [] + } + + return fields + .map((field, index) => { + const rawName = + typeof field?.name === 'string' + ? field.name + : typeof field?.key === 'string' + ? field.key + : '' + const name = rawName.trim() + if (!name) { + return null + } + + const valueObject = extractFieldValueObject(field) + + const candidateType = + typeof field?.type === 'string' && field.type + ? field.type + : typeof valueObject?.type === 'string' + ? valueObject.type + : '' + const allowedTypes: ComponentModelCustomFieldType[] = ['text', 'number', 'select', 'boolean', 'date'] + const type = allowedTypes.includes(candidateType as ComponentModelCustomFieldType) + ? (candidateType as ComponentModelCustomFieldType) + : 'text' + + const required = + typeof valueObject?.required === 'boolean' ? valueObject.required : !!field?.required + + let options: string[] | undefined + if (type === 'select') { + options = + toStringArray(valueObject?.options) || + toStringArray((valueObject as any)?.choices) || + toStringArray(field?.options) + + if (!options && typeof field?.optionsText === 'string') { + const parsedFromText = field.optionsText + .split(/\r?\n/) + .map((option: string) => option.trim()) + .filter((option: string) => option.length > 0) + options = parsedFromText.length ? parsedFromText : undefined + } + } + + const result: ComponentModelCustomField = { name, type, required } + if (options) { + result.options = options + } + const defaultCandidate = + field?.defaultValue ?? valueObject?.defaultValue ?? field?.value ?? field?.default ?? null + const resolvedDefault = (() => { + if (defaultCandidate === undefined || defaultCandidate === null) { + return undefined + } + if (typeof defaultCandidate === 'object') { + if (defaultCandidate === null) { + return undefined + } + if ('defaultValue' in (defaultCandidate as Record)) { + return (defaultCandidate as Record).defaultValue + } + if ('value' in (defaultCandidate as Record)) { + return (defaultCandidate as Record).value + } + return undefined + } + return defaultCandidate + })() + if (resolvedDefault !== undefined && resolvedDefault !== null && resolvedDefault !== '') { + result.defaultValue = String(resolvedDefault) + } + const id = typeof field?.id === 'string' ? field.id : undefined + if (id) { + result.id = id + } + const customFieldId = typeof field?.customFieldId === 'string' ? field.customFieldId : undefined + if (customFieldId) { + result.customFieldId = customFieldId + } + const orderIndex = typeof field?.orderIndex === 'number' ? field.orderIndex : index + result.orderIndex = orderIndex + return result + }) + .filter((field): field is ComponentModelCustomField => !!field) +} + +export const sanitizePieces = (pieces: any[]): ComponentModelPiece[] => { + if (!Array.isArray(pieces)) { + return [] + } + + return pieces + .map((piece) => { + const rawTypePieceId = typeof piece?.typePieceId === 'string' + ? piece.typePieceId.trim() + : typeof piece?.typePiece?.id === 'string' + ? piece.typePiece.id.trim() + : '' + const typePieceId = rawTypePieceId.length > 0 ? rawTypePieceId : undefined + + const rawTypePieceLabel = typeof piece?.typePieceLabel === 'string' + ? piece.typePieceLabel.trim() + : typeof piece?.typePiece?.name === 'string' + ? piece.typePiece.name.trim() + : '' + const typePieceLabel = rawTypePieceLabel.length > 0 ? rawTypePieceLabel : undefined + + const reference = typeof piece?.reference === 'string' && piece.reference.trim().length > 0 + ? piece.reference.trim() + : undefined + + const rawFamilyCode = typeof piece?.familyCode === 'string' + ? piece.familyCode.trim() + : typeof piece?.typePiece?.code === 'string' + ? piece.typePiece.code.trim() + : '' + const familyCode = rawFamilyCode.length > 0 ? rawFamilyCode : undefined + + const rawRole = typeof piece?.role === 'string' ? piece.role.trim() : '' + const role = rawRole.length > 0 ? rawRole : undefined + + if (!typePieceId && !typePieceLabel && !reference && !familyCode) { + return null + } + + const result: ComponentModelPiece = {} + if (role) { + result.role = role + } + if (familyCode) { + result.familyCode = familyCode + } + if (reference !== undefined) { + result.reference = reference + } + if (typePieceId) { + result.typePieceId = typePieceId + } + if (typePieceLabel) { + result.typePieceLabel = typePieceLabel + } + return result + }) + .filter((piece): piece is ComponentModelPiece => !!piece) +} + +export const sanitizeProducts = (products: any[]): ComponentModelProduct[] => { + if (!Array.isArray(products)) { + return [] + } + + return products + .map((product) => { + const rawTypeProductId = typeof product?.typeProductId === 'string' + ? product.typeProductId.trim() + : typeof product?.typeProduct?.id === 'string' + ? product.typeProduct.id.trim() + : '' + const typeProductId = rawTypeProductId.length > 0 ? rawTypeProductId : undefined + + const rawTypeProductLabel = typeof product?.typeProductLabel === 'string' + ? product.typeProductLabel.trim() + : typeof product?.typeProduct?.name === 'string' + ? product.typeProduct.name.trim() + : '' + const typeProductLabel = rawTypeProductLabel.length > 0 ? rawTypeProductLabel : undefined + + const reference = typeof product?.reference === 'string' && product.reference.trim().length > 0 + ? product.reference.trim() + : undefined + + const rawFamilyCode = typeof product?.familyCode === 'string' + ? product.familyCode.trim() + : typeof product?.typeProduct?.code === 'string' + ? product.typeProduct.code.trim() + : '' + const familyCode = rawFamilyCode.length > 0 ? rawFamilyCode : undefined + + const rawRole = typeof product?.role === 'string' ? product.role.trim() : '' + const role = rawRole.length > 0 ? rawRole : undefined + + if (!typeProductId && !typeProductLabel && !reference && !familyCode) { + return null + } + + const result: ComponentModelProduct = {} + if (role) { + result.role = role + } + if (familyCode) { + result.familyCode = familyCode + } + if (reference !== undefined) { + result.reference = reference + } + if (typeProductId) { + result.typeProductId = typeProductId + } + if (typeProductLabel) { + result.typeProductLabel = typeProductLabel + } + return result + }) + .filter((product): product is ComponentModelProduct => !!product) +} + +const sanitizeSubcomponents = (components: any[]): ComponentModelStructureNode[] => { + if (!Array.isArray(components)) { + return [] + } + + return components + .map((component) => { + const rawTypeComposantId = typeof component?.typeComposantId === 'string' + ? component.typeComposantId.trim() + : typeof component?.typeComposant?.id === 'string' + ? component.typeComposant.id.trim() + : '' + const typeComposantId = rawTypeComposantId.length > 0 ? rawTypeComposantId : undefined + + const modelId = typeof component?.modelId === 'string' && component.modelId.trim().length > 0 + ? component.modelId.trim() + : undefined + + const familyCode = typeof component?.familyCode === 'string' && component.familyCode.trim().length > 0 + ? component.familyCode.trim() + : undefined + + const alias = typeof component?.alias === 'string' && component.alias.trim().length > 0 + ? component.alias.trim() + : undefined + + if (!typeComposantId && !modelId && !familyCode) { + return null + } + + const result: ComponentModelStructureNode = { + subcomponents: sanitizeSubcomponents( + Array.isArray(component?.subcomponents) + ? component.subcomponents + : component?.subComponents, + ), + } + + if (typeComposantId) { + result.typeComposantId = typeComposantId + } + const typeComposantLabel = typeof component?.typeComposantLabel === 'string' + ? component.typeComposantLabel.trim() + : typeof component?.typeComposant?.name === 'string' + ? component.typeComposant.name.trim() + : '' + if (typeComposantLabel) { + result.typeComposantLabel = typeComposantLabel + } + if (modelId) { + result.modelId = modelId + } + if (familyCode) { + result.familyCode = familyCode + } + if (alias) { + result.alias = alias + } + + return result + }) + .filter((component): component is ComponentModelStructureNode => !!component) +} + +const hydrateCustomFields = (fields: any[]): any[] => { + if (!Array.isArray(fields)) { + return [] + } + + return fields.map((field, index) => { + const valueObject = extractFieldValueObject(field) + const name = typeof field?.name === 'string' + ? field.name + : typeof field?.key === 'string' + ? field.key + : '' + + const candidateType = + typeof field?.type === 'string' && field.type + ? field.type + : typeof valueObject?.type === 'string' + ? valueObject.type + : '' + const allowedTypes: ComponentModelCustomFieldType[] = ['text', 'number', 'select', 'boolean', 'date'] + const type = allowedTypes.includes(candidateType as ComponentModelCustomFieldType) + ? (candidateType as ComponentModelCustomFieldType) + : 'text' + + const required = + typeof field?.required === 'boolean' + ? field.required + : typeof valueObject?.required === 'boolean' + ? valueObject.required + : false + + const options = + toStringArray(field?.options) || + toStringArray(valueObject?.options) || + toStringArray((valueObject as any)?.choices) || + [] + + const optionsText = typeof field?.optionsText === 'string' + ? field.optionsText + : options.length + ? options.join('\n') + : '' + + const defaultCandidate = + field?.defaultValue ?? valueObject?.defaultValue ?? field?.value ?? field?.default ?? null + const resolvedDefault = (() => { + if (defaultCandidate === undefined || defaultCandidate === null) { + return undefined + } + if (typeof defaultCandidate === 'object') { + if (defaultCandidate === null) { + return undefined + } + if ('defaultValue' in (defaultCandidate as Record)) { + return (defaultCandidate as Record).defaultValue + } + if ('value' in (defaultCandidate as Record)) { + return (defaultCandidate as Record).value + } + return undefined + } + return defaultCandidate + })() + const defaultValue = + resolvedDefault !== undefined && resolvedDefault !== null && resolvedDefault !== '' + ? String(resolvedDefault) + : '' + + const id = typeof field?.id === 'string' ? field.id : undefined + const customFieldId = typeof field?.customFieldId === 'string' ? field.customFieldId : undefined + const orderIndex = typeof field?.orderIndex === 'number' ? field.orderIndex : index + + return { + name, + type, + required, + options, + optionsText, + defaultValue, + id, + customFieldId, + orderIndex, + } + }) +} + +const hydratePieces = (pieces: any[]): ComponentModelPiece[] => { + if (!Array.isArray(pieces)) { + return [] + } + + return pieces.map((piece) => ({ + typePieceId: piece?.typePieceId ?? piece?.typePiece?.id ?? '', + typePieceLabel: piece?.typePieceLabel ?? piece?.typePiece?.name ?? '', + reference: piece?.reference ?? '', + familyCode: piece?.familyCode ?? piece?.typePiece?.code ?? '', + role: piece?.role ?? '', + })) +} + +export const hydrateProducts = (products: any[]): ComponentModelProduct[] => { + if (!Array.isArray(products)) { + return [] + } + + return products.map((product) => ({ + typeProductId: product?.typeProductId ?? product?.typeProduct?.id ?? '', + typeProductLabel: product?.typeProductLabel ?? product?.typeProduct?.name ?? '', + reference: product?.reference ?? '', + familyCode: product?.familyCode ?? product?.typeProduct?.code ?? '', + role: product?.role ?? '', + })) +} + +const hydrateSubcomponents = (components: any[]): ComponentModelStructureNode[] => { + if (!Array.isArray(components)) { + return [] + } + + return components.map((component) => ({ + typeComposantId: component?.typeComposantId ?? component?.typeComposant?.id ?? '', + typeComposantLabel: component?.typeComposantLabel ?? component?.typeComposant?.name ?? '', + modelId: component?.modelId ?? '', + familyCode: component?.familyCode ?? component?.typeComposant?.code ?? '', + alias: component?.alias ?? component?.name ?? '', + subcomponents: hydrateSubcomponents( + Array.isArray(component?.subcomponents) + ? component.subcomponents + : component?.subComponents, + ), + })) +} + +export const normalizeStructureForEditor = (input: any): ComponentModelStructure => { + const source = cloneStructure(input) + + const sanitizedCustomFields = sanitizeCustomFields(source.customFields) + const customFields = sanitizedCustomFields.map((field) => { + const options = Array.isArray(field.options) ? [...field.options] : [] + const optionsText = options.length ? options.join('\n') : '' + const defaultValue = + field.defaultValue !== undefined && field.defaultValue !== null && field.defaultValue !== '' + ? String(field.defaultValue) + : null + const copy: ComponentModelCustomField = { + name: field.name, + type: field.type, + required: field.required, + options, + defaultValue, + optionsText, + id: field.id, + customFieldId: field.customFieldId, + } + return copy + }) + + const result: ComponentModelStructure = { + customFields: customFields as ComponentModelCustomField[], + pieces: sanitizePieces(source.pieces), + products: sanitizeProducts(source.products), + subcomponents: hydrateSubcomponents(source.subcomponents), + } + + if (typeof source.typeComposantId === 'string' && source.typeComposantId.length > 0) { + result.typeComposantId = source.typeComposantId + } + if (typeof source.typeComposantLabel === 'string' && source.typeComposantLabel.length > 0) { + result.typeComposantLabel = source.typeComposantLabel + } + if (typeof source.modelId === 'string' && source.modelId.length > 0) { + result.modelId = source.modelId + } + if (typeof source.familyCode === 'string' && source.familyCode.length > 0) { + result.familyCode = source.familyCode + } + if (typeof source.alias === 'string' && source.alias.length > 0) { + result.alias = source.alias + } + + return result +} + +export const normalizeStructureForSave = (input: any): any => { + const source = cloneStructure(input) + + const sanitizedCustomFields = sanitizeCustomFields(source.customFields) + const backendCustomFields = sanitizedCustomFields.map((field) => { + const value: Record = { + type: field.type, + required: !!field.required, + } + if (field.options && field.options.length) { + value.options = field.options + } + if (field.defaultValue !== undefined && field.defaultValue !== null && field.defaultValue !== '') { + value.defaultValue = field.defaultValue + } + const payload: Record = { + key: field.name, + value, + } + if (field.id) { + payload.id = field.id + } + if (field.customFieldId) { + payload.customFieldId = field.customFieldId + } + return payload + }) as any + + const backendPieces = sanitizePieces(source.pieces).map((piece) => { + const payload: Record = {} + if ((piece as any).familyCode) { + payload.familyCode = (piece as any).familyCode + } + if (piece.typePieceId) { + payload.typePieceId = piece.typePieceId + } + if (piece.typePieceLabel) { + payload.typePieceLabel = piece.typePieceLabel + } + if (piece.reference) { + payload.reference = piece.reference + } + return payload + }) as any + + const backendProducts = sanitizeProducts(source.products).map((product) => { + const payload: Record = {} + if ((product as any).familyCode) { + payload.familyCode = (product as any).familyCode + } + if (product.typeProductId) { + payload.typeProductId = product.typeProductId + } + if (product.role) { + payload.role = product.role + } + return payload + }) as any + + const mapSubcomponentForSave = (subcomponent: ComponentModelStructureNode): any => { + const payload: Record = {} + if (subcomponent.typeComposantId) { + payload.typeComposantId = subcomponent.typeComposantId + } + if (subcomponent.modelId) { + payload.modelId = subcomponent.modelId + } + if (subcomponent.familyCode) { + payload.familyCode = subcomponent.familyCode + } + if (subcomponent.alias) { + payload.alias = subcomponent.alias + } + if (Array.isArray(subcomponent.subcomponents) && subcomponent.subcomponents.length) { + payload.subcomponents = subcomponent.subcomponents.map(mapSubcomponentForSave) + } + return payload + } + + const backendSubcomponents = sanitizeSubcomponents(source.subcomponents).map(mapSubcomponentForSave) as any + + const result: ComponentModelStructure = { + customFields: backendCustomFields, + pieces: backendPieces, + products: backendProducts, + subcomponents: backendSubcomponents, + } + + if (typeof source.typeComposantId === 'string' && source.typeComposantId.length > 0) { + (result as any).typeComposantId = source.typeComposantId + } + if (typeof source.typeComposantLabel === 'string' && source.typeComposantLabel.length > 0) { + (result as any).typeComposantLabel = source.typeComposantLabel + } + if (typeof source.modelId === 'string' && source.modelId.length > 0) { + (result as any).modelId = source.modelId + } + if (typeof source.familyCode === 'string' && source.familyCode.length > 0) { + (result as any).familyCode = source.familyCode + } + if (typeof source.alias === 'string' && source.alias.length > 0) { + (result as any).alias = source.alias + } + + return result +} + +export const hydrateStructureForEditor = (input: any): ComponentModelStructure => { + const source = cloneStructure(input) + return { + customFields: hydrateCustomFields(source.customFields), + pieces: hydratePieces(source.pieces), + products: hydrateProducts(source.products), + subcomponents: hydrateSubcomponents( + Array.isArray(source.subcomponents) ? source.subcomponents : (source as any).subComponents, + ), + typeComposantId: source.typeComposantId ?? '', + typeComposantLabel: source.typeComposantLabel ?? '', + modelId: source.modelId ?? '', + familyCode: source.familyCode ?? '', + alias: source.alias ?? '', + } +} + +const mapComponentCustomFields = (fields: any[]) => { + if (!Array.isArray(fields)) { + return [] + } + return hydrateCustomFields(fields).map((field, index) => { + const defaultValue = + field?.defaultValue !== undefined && field?.defaultValue !== null && field?.defaultValue !== '' + ? field.defaultValue + : null + return { + name: typeof field?.name === 'string' ? field.name : '', + type: field?.type ?? 'text', + required: !!field?.required, + options: Array.isArray(field?.options) ? field.options : [], + optionsText: typeof field?.optionsText === 'string' ? field.optionsText : '', + defaultValue, + id: typeof (field as any)?.id === 'string' ? (field as any).id : undefined, + customFieldId: + typeof (field as any)?.customFieldId === 'string' + ? (field as any).customFieldId + : undefined, + orderIndex: typeof field?.orderIndex === 'number' ? field.orderIndex : index, + } + }) +} + +const mapComponentPieces = (pieces: any[]): ComponentModelPiece[] => { + if (!Array.isArray(pieces)) { + return [] + } + return pieces.map((piece) => ({ + reference: piece?.reference ?? '', + typePieceId: piece?.typePieceId ?? piece?.typePiece?.id ?? '', + typePieceLabel: piece?.typePieceLabel ?? piece?.typePiece?.name ?? '', + familyCode: piece?.familyCode ?? piece?.typePiece?.code ?? '', + role: piece?.role ?? '', + })) +} + +const mapComponentProducts = (products: any[]): ComponentModelProduct[] => { + if (!Array.isArray(products)) { + return [] + } + return products.map((product) => ({ + reference: product?.reference ?? '', + typeProductId: product?.typeProductId ?? product?.typeProduct?.id ?? '', + typeProductLabel: product?.typeProductLabel ?? product?.typeProduct?.name ?? '', + familyCode: product?.familyCode ?? product?.typeProduct?.code ?? '', + role: product?.role ?? '', + })) +} + +const mapSubcomponents = (components: any[]): ComponentModelStructureNode[] => { + if (!Array.isArray(components)) { + return [] + } + return components.map((component) => ({ + typeComposantId: component?.typeComposantId ?? component?.typeComposant?.id ?? '', + typeComposantLabel: component?.typeComposantLabel ?? component?.typeComposant?.name ?? '', + modelId: component?.modelId ?? '', + familyCode: component?.familyCode ?? component?.typeComposant?.code ?? '', + alias: component?.alias ?? component?.name ?? '', + subcomponents: mapSubcomponents( + Array.isArray(component?.subcomponents) + ? component.subcomponents + : component?.subComponents, + ), + })) +} + +export const extractStructureFromComponent = (component: any) => { + if (!component) { + return defaultStructure() + } + + const raw = { + customFields: mapComponentCustomFields(component.customFields), + pieces: mapComponentPieces(component.pieces), + products: mapComponentProducts(component.products), + subcomponents: mapSubcomponents( + Array.isArray(component?.subcomponents) + ? component.subcomponents + : component?.subComponents, + ), + typeComposantId: component?.typeComposantId ?? component?.typeComposant?.id ?? '', + typeComposantLabel: component?.typeComposant?.name ?? component?.typeComposantLabel ?? '', + modelId: component?.modelId ?? '', + familyCode: component?.familyCode ?? component?.typeComposant?.code ?? '', + alias: component?.alias ?? component?.name ?? '', + } + + return normalizeStructureForEditor(raw) +} + +export const computeStructureStats = (structure: any): ModelStructurePreview => { + if (!structure || typeof structure !== 'object') { + return { customFields: 0, pieces: 0, products: 0, subcomponents: 0 } + } + + return { + customFields: Array.isArray(structure.customFields) ? structure.customFields.length : 0, + pieces: Array.isArray(structure.pieces) ? structure.pieces.length : 0, + products: Array.isArray(structure.products) ? structure.products.length : 0, + subcomponents: Array.isArray(structure.subcomponents) + ? structure.subcomponents.length + : Array.isArray(structure.subComponents) + ? structure.subComponents.length + : 0, + } +} + +export const formatStructurePreview = (structure: any) => { + const stats = computeStructureStats(structure) + if (!stats.customFields && !stats.pieces && !stats.products && !stats.subcomponents) { + return 'Structure vide' + } + + const segments: string[] = [] + if (stats.customFields) segments.push(`${stats.customFields} champ(s)`) + if (stats.pieces) segments.push(`${stats.pieces} pièce(s)`) + if (stats.products) segments.push(`${stats.products} produit(s)`) + if (stats.subcomponents) segments.push(`${stats.subcomponents} sous-composant(s)`) + return segments.join(' • ') +} diff --git a/app/shared/model/definitionOverrides.ts b/app/shared/model/definitionOverrides.ts new file mode 100644 index 0000000..b309f52 --- /dev/null +++ b/app/shared/model/definitionOverrides.ts @@ -0,0 +1,49 @@ +import { uniqueConstructeurIds } from '../constructeurUtils' + +export interface DefinitionOverridePayload { + name?: string + reference?: string + constructeurIds?: string[] + prix?: number +} + +export const sanitizeDefinitionOverrides = (definition: any): DefinitionOverridePayload | null => { + if (!definition || typeof definition !== 'object') { + return null + } + + const payload: DefinitionOverridePayload = {} + + if (typeof definition.name === 'string') { + const name = definition.name.trim() + if (name.length > 0) { + payload.name = name + } + } + + if (typeof definition.reference === 'string') { + const reference = definition.reference.trim() + if (reference.length > 0) { + payload.reference = reference + } + } + + const constructeurIds = uniqueConstructeurIds( + definition.constructeurIds, + definition.constructeurId, + definition.constructeur, + definition.constructeurs, + ) + if (constructeurIds.length) { + payload.constructeurIds = constructeurIds + } + + if (definition.prix !== undefined && definition.prix !== null && definition.prix !== '') { + const parsed = Number(definition.prix) + if (!Number.isNaN(parsed)) { + payload.prix = parsed + } + } + + return Object.keys(payload).length ? payload : null +} diff --git a/app/shared/model/pieceProductStructure.ts b/app/shared/model/pieceProductStructure.ts new file mode 100644 index 0000000..a7dff65 --- /dev/null +++ b/app/shared/model/pieceProductStructure.ts @@ -0,0 +1,177 @@ +import { + createEmptyPieceModelStructure, + createEmptyProductModelStructure, + type PieceModelCustomField, + type PieceModelProduct, + type PieceModelStructure, + type PieceModelStructureEditorField, + type PieceModelStructureForEditor, + type ProductModelStructure, +} from '../types/inventory' +import { isPlainObject, sanitizeProducts, hydrateProducts } from './componentStructure' + +export const defaultPieceStructure = (): PieceModelStructure => ({ + ...createEmptyPieceModelStructure(), +}) + +export const defaultProductStructure = (): ProductModelStructure => ({ + ...createEmptyProductModelStructure(), +}) + +const ensurePieceStructureShape = (input: any): PieceModelStructure => { + const base = createEmptyPieceModelStructure() + if (!isPlainObject(input)) { + return base + } + + const clone: PieceModelStructure = { + ...base, + customFields: Array.isArray((input as any).customFields) ? (input as any).customFields : [], + products: Array.isArray((input as any).products) ? (input as any).products : [], + } + + for (const [key, value] of Object.entries(input as Record)) { + if (key === 'customFields' || key === 'products') { + continue + } + clone[key] = value + } + + return clone +} + +export const clonePieceStructure = (input: any): PieceModelStructure => { + try { + const cloned = JSON.parse(JSON.stringify(input ?? defaultPieceStructure())) + return ensurePieceStructureShape(cloned) + } catch (_error) { + return defaultPieceStructure() + } +} + +export const cloneProductStructure = (input: any): ProductModelStructure => { + return clonePieceStructure(input) +} + +const sanitizePieceCustomFields = (fields: any[]): PieceModelCustomField[] => { + if (!Array.isArray(fields)) { + return [] + } + + return fields + .map((field, index) => { + const name = typeof field?.name === 'string' ? field.name.trim() : '' + if (!name) { + return null + } + + const type = typeof field?.type === 'string' && field.type ? field.type : 'text' + const required = !!field?.required + + let options: string[] | undefined + if (type === 'select') { + const rawOptions = typeof field?.optionsText === 'string' + ? field.optionsText + : Array.isArray(field?.options) + ? field.options.join('\n') + : '' + const parsed = rawOptions + .split(/\r?\n/) + .map((option: string) => option.trim()) + .filter((option: string) => option.length > 0) + options = parsed.length > 0 ? parsed : undefined + } + + const result: PieceModelCustomField = { name, type, required } + if (options) { + result.options = options + } + const orderIndex = typeof field?.orderIndex === 'number' ? field.orderIndex : index + result.orderIndex = orderIndex + return result + }) + .filter((field): field is PieceModelCustomField => !!field) +} + +const sanitizePieceProducts = (products: any[]): PieceModelProduct[] => { + return sanitizeProducts(products) as PieceModelProduct[] +} + +export const normalizePieceStructureForSave = (input: any): PieceModelStructure => { + const source = clonePieceStructure(input) + const restEntries = Object.entries(source).filter( + ([key]) => key !== 'customFields' && key !== 'products', + ) + return { + ...Object.fromEntries(restEntries), + products: sanitizePieceProducts(source.products || []), + customFields: sanitizePieceCustomFields(source.customFields), + } +} + +const hydratePieceCustomFields = (fields: any[]): PieceModelStructureEditorField[] => { + if (!Array.isArray(fields)) { + return [] + } + + return fields.map((field, index) => ({ + name: field?.name ?? '', + type: field?.type ?? 'text', + required: !!field?.required, + options: Array.isArray(field?.options) ? field.options : undefined, + optionsText: typeof field?.optionsText === 'string' + ? field.optionsText + : Array.isArray(field?.options) + ? field.options.join('\n') + : '', + orderIndex: typeof field?.orderIndex === 'number' ? field.orderIndex : index, + })) +} + +export const hydratePieceStructureForEditor = (input: any): PieceModelStructureForEditor => { + const source = clonePieceStructure(input) + const payload: PieceModelStructureForEditor = { + ...Object.fromEntries( + Object.entries(source).filter(([key]) => key !== 'customFields' && key !== 'products'), + ), + products: hydrateProducts(source.products || []) as PieceModelProduct[], + customFields: hydratePieceCustomFields(source.customFields), + } + return payload +} + +export const formatPieceStructurePreview = (structure: any) => { + if (!structure || typeof structure !== 'object') { + return 'Aucun champ personnalisé' + } + + const customFields = Array.isArray((structure as any).customFields) + ? (structure as any).customFields.length + : 0 + const products = Array.isArray((structure as any).products) + ? (structure as any).products.length + : 0 + + if (!customFields && !products) { + return 'Aucun produit ni champ personnalisé' + } + + const segments: string[] = [] + if (products) { + segments.push(`${products} produit(s)`) + } + if (customFields) { + segments.push(`${customFields} champ(s) personnalisé(s)`) + } + + return segments.join(' · ') +} + +export const normalizeProductStructureForSave = (input: any): ProductModelStructure => + normalizePieceStructureForSave(input) + +export const hydrateProductStructureForEditor = (input: any) => + hydratePieceStructureForEditor(input) + +export const formatProductStructurePreview = (structure: any) => + formatPieceStructurePreview(structure) diff --git a/app/shared/modelUtils.ts b/app/shared/modelUtils.ts index 0da7b3f..02cf7dd 100644 --- a/app/shared/modelUtils.ts +++ b/app/shared/modelUtils.ts @@ -1,1017 +1,36 @@ -import { - createEmptyComponentModelStructure, - type ComponentModelCustomFieldType, - type ComponentModelCustomField, - type ComponentModelPiece, - type ComponentModelProduct, - type ComponentModelStructure, - type ComponentModelStructureNode, - type PieceModelCustomField, - type PieceModelProduct, - type PieceModelStructure, - type PieceModelStructureEditorField, - type PieceModelStructureForEditor, - type ProductModelStructure, - createEmptyProductModelStructure, - createEmptyPieceModelStructure, -} from './types/inventory' -import { uniqueConstructeurIds } from './constructeurUtils' - -export const isPlainObject = (value: unknown): value is Record => { - return value !== null && typeof value === 'object' && !Array.isArray(value) -} - -export interface ModelStructurePreview { - customFields: number - pieces: number - products: number - subcomponents: number -} - -export const defaultStructure = (): ComponentModelStructure => ({ - ...createEmptyComponentModelStructure(), -}) - -const ensureStructureShape = (input: any): ComponentModelStructure => { - const base = createEmptyComponentModelStructure() - if (!isPlainObject(input)) { - return base - } - - const clone: ComponentModelStructure = { - ...base, - customFields: Array.isArray((input as any).customFields) ? (input as any).customFields : [], - pieces: Array.isArray((input as any).pieces) ? (input as any).pieces : [], - products: Array.isArray((input as any).products) ? (input as any).products : [], - subcomponents: Array.isArray((input as any).subcomponents) - ? (input as any).subcomponents - : Array.isArray((input as any).subComponents) - ? (input as any).subComponents - : [], - typeComposantId: typeof (input as any).typeComposantId === 'string' ? (input as any).typeComposantId : undefined, - typeComposantLabel: typeof (input as any).typeComposantLabel === 'string' - ? (input as any).typeComposantLabel - : undefined, - modelId: typeof (input as any).modelId === 'string' ? (input as any).modelId : undefined, - familyCode: typeof (input as any).familyCode === 'string' ? (input as any).familyCode : undefined, - alias: typeof (input as any).alias === 'string' ? (input as any).alias : undefined, - } - - return clone -} - -export const cloneStructure = (input: any): ComponentModelStructure => { - try { - const cloned = JSON.parse(JSON.stringify(input ?? defaultStructure())) - return ensureStructureShape(cloned) - } catch (error) { - return defaultStructure() - } -} - -const toStringArray = (input: unknown): string[] | undefined => { - if (!Array.isArray(input)) { - return undefined - } - const parsed = input - .map((value) => { - if (typeof value === 'string') { - return value.trim() - } - if (value === null || value === undefined) { - return '' - } - return String(value).trim() - }) - .filter((value) => value.length > 0) - return parsed.length ? parsed : undefined -} - -const extractFieldValueObject = (field: any): Record => { - if (isPlainObject(field?.value)) { - return field.value as Record - } - return {} -} - -const sanitizeCustomFields = (fields: any[]): ComponentModelCustomField[] => { - if (!Array.isArray(fields)) { - return [] - } - - return fields - .map((field, index) => { - const rawName = - typeof field?.name === 'string' - ? field.name - : typeof field?.key === 'string' - ? field.key - : '' - const name = rawName.trim() - if (!name) { - return null - } - - const valueObject = extractFieldValueObject(field) - - const candidateType = - typeof field?.type === 'string' && field.type - ? field.type - : typeof valueObject?.type === 'string' - ? valueObject.type - : '' - const allowedTypes: ComponentModelCustomFieldType[] = ['text', 'number', 'select', 'boolean', 'date'] - const type = allowedTypes.includes(candidateType as ComponentModelCustomFieldType) - ? (candidateType as ComponentModelCustomFieldType) - : 'text' - - const required = - typeof valueObject?.required === 'boolean' ? valueObject.required : !!field?.required - - let options: string[] | undefined - if (type === 'select') { - options = - toStringArray(valueObject?.options) || - toStringArray((valueObject as any)?.choices) || - toStringArray(field?.options) - - if (!options && typeof field?.optionsText === 'string') { - const parsedFromText = field.optionsText - .split(/\r?\n/) - .map((option: string) => option.trim()) - .filter((option: string) => option.length > 0) - options = parsedFromText.length ? parsedFromText : undefined - } - } - - const result: ComponentModelCustomField = { name, type, required } - if (options) { - result.options = options - } - const defaultCandidate = - field?.defaultValue ?? valueObject?.defaultValue ?? field?.value ?? field?.default ?? null - const resolvedDefault = (() => { - if (defaultCandidate === undefined || defaultCandidate === null) { - return undefined - } - if (typeof defaultCandidate === 'object') { - if (defaultCandidate === null) { - return undefined - } - if ('defaultValue' in (defaultCandidate as Record)) { - return (defaultCandidate as Record).defaultValue - } - if ('value' in (defaultCandidate as Record)) { - return (defaultCandidate as Record).value - } - return undefined - } - return defaultCandidate - })() - if (resolvedDefault !== undefined && resolvedDefault !== null && resolvedDefault !== '') { - result.defaultValue = String(resolvedDefault) - } - const id = typeof field?.id === 'string' ? field.id : undefined - if (id) { - result.id = id - } - const customFieldId = typeof field?.customFieldId === 'string' ? field.customFieldId : undefined - if (customFieldId) { - result.customFieldId = customFieldId - } - const orderIndex = typeof field?.orderIndex === 'number' ? field.orderIndex : index - result.orderIndex = orderIndex - return result - }) - .filter((field): field is ComponentModelCustomField => !!field) -} - -const sanitizePieces = (pieces: any[]): ComponentModelPiece[] => { - if (!Array.isArray(pieces)) { - return [] - } - - return pieces - .map((piece) => { - const rawTypePieceId = typeof piece?.typePieceId === 'string' - ? piece.typePieceId.trim() - : typeof piece?.typePiece?.id === 'string' - ? piece.typePiece.id.trim() - : '' - const typePieceId = rawTypePieceId.length > 0 ? rawTypePieceId : undefined - - const rawTypePieceLabel = typeof piece?.typePieceLabel === 'string' - ? piece.typePieceLabel.trim() - : typeof piece?.typePiece?.name === 'string' - ? piece.typePiece.name.trim() - : '' - const typePieceLabel = rawTypePieceLabel.length > 0 ? rawTypePieceLabel : undefined - - const reference = typeof piece?.reference === 'string' && piece.reference.trim().length > 0 - ? piece.reference.trim() - : undefined - - const rawFamilyCode = typeof piece?.familyCode === 'string' - ? piece.familyCode.trim() - : typeof piece?.typePiece?.code === 'string' - ? piece.typePiece.code.trim() - : '' - const familyCode = rawFamilyCode.length > 0 ? rawFamilyCode : undefined - - const rawRole = typeof piece?.role === 'string' ? piece.role.trim() : '' - const role = rawRole.length > 0 ? rawRole : undefined - - if (!typePieceId && !typePieceLabel && !reference && !familyCode) { - return null - } - - const result: ComponentModelPiece = {} - if (role) { - result.role = role - } - if (familyCode) { - result.familyCode = familyCode - } - if (reference !== undefined) { - result.reference = reference - } - if (typePieceId) { - result.typePieceId = typePieceId - } - if (typePieceLabel) { - result.typePieceLabel = typePieceLabel - } - return result - }) - .filter((piece): piece is ComponentModelPiece => !!piece) -} - -const sanitizeProducts = (products: any[]): ComponentModelProduct[] => { - if (!Array.isArray(products)) { - return [] - } - - return products - .map((product) => { - const rawTypeProductId = typeof product?.typeProductId === 'string' - ? product.typeProductId.trim() - : typeof product?.typeProduct?.id === 'string' - ? product.typeProduct.id.trim() - : '' - const typeProductId = rawTypeProductId.length > 0 ? rawTypeProductId : undefined - - const rawTypeProductLabel = typeof product?.typeProductLabel === 'string' - ? product.typeProductLabel.trim() - : typeof product?.typeProduct?.name === 'string' - ? product.typeProduct.name.trim() - : '' - const typeProductLabel = rawTypeProductLabel.length > 0 ? rawTypeProductLabel : undefined - - const reference = typeof product?.reference === 'string' && product.reference.trim().length > 0 - ? product.reference.trim() - : undefined - - const rawFamilyCode = typeof product?.familyCode === 'string' - ? product.familyCode.trim() - : typeof product?.typeProduct?.code === 'string' - ? product.typeProduct.code.trim() - : '' - const familyCode = rawFamilyCode.length > 0 ? rawFamilyCode : undefined - - const rawRole = typeof product?.role === 'string' ? product.role.trim() : '' - const role = rawRole.length > 0 ? rawRole : undefined - - if (!typeProductId && !typeProductLabel && !reference && !familyCode) { - return null - } - - const result: ComponentModelProduct = {} - if (role) { - result.role = role - } - if (familyCode) { - result.familyCode = familyCode - } - if (reference !== undefined) { - result.reference = reference - } - if (typeProductId) { - result.typeProductId = typeProductId - } - if (typeProductLabel) { - result.typeProductLabel = typeProductLabel - } - return result - }) - .filter((product): product is ComponentModelProduct => !!product) -} - -const sanitizeSubcomponents = (components: any[]): ComponentModelStructureNode[] => { - if (!Array.isArray(components)) { - return [] - } - - return components - .map((component) => { - const rawTypeComposantId = typeof component?.typeComposantId === 'string' - ? component.typeComposantId.trim() - : typeof component?.typeComposant?.id === 'string' - ? component.typeComposant.id.trim() - : '' - const typeComposantId = rawTypeComposantId.length > 0 ? rawTypeComposantId : undefined - - const modelId = typeof component?.modelId === 'string' && component.modelId.trim().length > 0 - ? component.modelId.trim() - : undefined - - const familyCode = typeof component?.familyCode === 'string' && component.familyCode.trim().length > 0 - ? component.familyCode.trim() - : undefined - - const alias = typeof component?.alias === 'string' && component.alias.trim().length > 0 - ? component.alias.trim() - : undefined - - if (!typeComposantId && !modelId && !familyCode) { - return null - } - - const result: ComponentModelStructureNode = { - subcomponents: sanitizeSubcomponents( - Array.isArray(component?.subcomponents) - ? component.subcomponents - : component?.subComponents, - ), - } - - if (typeComposantId) { - result.typeComposantId = typeComposantId - } - const typeComposantLabel = typeof component?.typeComposantLabel === 'string' - ? component.typeComposantLabel.trim() - : typeof component?.typeComposant?.name === 'string' - ? component.typeComposant.name.trim() - : '' - if (typeComposantLabel) { - result.typeComposantLabel = typeComposantLabel - } - if (modelId) { - result.modelId = modelId - } - if (familyCode) { - result.familyCode = familyCode - } - if (alias) { - result.alias = alias - } - - return result - }) - .filter((component): component is ComponentModelStructureNode => !!component) -} - -export const normalizeStructureForEditor = (input: any): ComponentModelStructure => { - const source = cloneStructure(input) - - const sanitizedCustomFields = sanitizeCustomFields(source.customFields) - const customFields = sanitizedCustomFields.map((field) => { - const options = Array.isArray(field.options) ? [...field.options] : [] - const optionsText = options.length ? options.join('\n') : '' - const defaultValue = - field.defaultValue !== undefined && field.defaultValue !== null && field.defaultValue !== '' - ? String(field.defaultValue) - : null - const copy: ComponentModelCustomField = { - name: field.name, - type: field.type, - required: field.required, - options, - defaultValue, - optionsText, - id: field.id, - customFieldId: field.customFieldId, - } - return copy - }) - - const result: ComponentModelStructure = { - customFields: customFields as ComponentModelCustomField[], - pieces: sanitizePieces(source.pieces), - products: sanitizeProducts(source.products), - subcomponents: hydrateSubcomponents(source.subcomponents), - } - - if (typeof source.typeComposantId === 'string' && source.typeComposantId.length > 0) { - result.typeComposantId = source.typeComposantId - } - if (typeof source.typeComposantLabel === 'string' && source.typeComposantLabel.length > 0) { - result.typeComposantLabel = source.typeComposantLabel - } - if (typeof source.modelId === 'string' && source.modelId.length > 0) { - result.modelId = source.modelId - } - if (typeof source.familyCode === 'string' && source.familyCode.length > 0) { - result.familyCode = source.familyCode - } - if (typeof source.alias === 'string' && source.alias.length > 0) { - result.alias = source.alias - } - - return result -} - -export const normalizeStructureForSave = (input: any): any => { - const source = cloneStructure(input) - - const sanitizedCustomFields = sanitizeCustomFields(source.customFields) - const backendCustomFields = sanitizedCustomFields.map((field) => { - const value: Record = { - type: field.type, - required: !!field.required, - } - if (field.options && field.options.length) { - value.options = field.options - } - if (field.defaultValue !== undefined && field.defaultValue !== null && field.defaultValue !== '') { - value.defaultValue = field.defaultValue - } - const payload: Record = { - key: field.name, - value, - } - if (field.id) { - payload.id = field.id - } - if (field.customFieldId) { - payload.customFieldId = field.customFieldId - } - return payload - }) as any - - const backendPieces = sanitizePieces(source.pieces).map((piece) => { - const payload: Record = {} - if ((piece as any).familyCode) { - payload.familyCode = (piece as any).familyCode - } - if (piece.typePieceId) { - payload.typePieceId = piece.typePieceId - } - if (piece.typePieceLabel) { - payload.typePieceLabel = piece.typePieceLabel - } - if (piece.reference) { - payload.reference = piece.reference - } - return payload - }) as any - - const backendProducts = sanitizeProducts(source.products).map((product) => { - const payload: Record = {} - if ((product as any).familyCode) { - payload.familyCode = (product as any).familyCode - } - if (product.typeProductId) { - payload.typeProductId = product.typeProductId - } - if (product.role) { - payload.role = product.role - } - return payload - }) as any - - const mapSubcomponentForSave = (subcomponent: ComponentModelStructureNode): any => { - const payload: Record = {} - if (subcomponent.typeComposantId) { - payload.typeComposantId = subcomponent.typeComposantId - } - if (subcomponent.modelId) { - payload.modelId = subcomponent.modelId - } - if (subcomponent.familyCode) { - payload.familyCode = subcomponent.familyCode - } - if (subcomponent.alias) { - payload.alias = subcomponent.alias - } - if (Array.isArray(subcomponent.subcomponents) && subcomponent.subcomponents.length) { - payload.subcomponents = subcomponent.subcomponents.map(mapSubcomponentForSave) - } - return payload - } - - const backendSubcomponents = sanitizeSubcomponents(source.subcomponents).map(mapSubcomponentForSave) as any - - const result: ComponentModelStructure = { - customFields: backendCustomFields, - pieces: backendPieces, - products: backendProducts, - subcomponents: backendSubcomponents, - } - - if (typeof source.typeComposantId === 'string' && source.typeComposantId.length > 0) { - (result as any).typeComposantId = source.typeComposantId - } - if (typeof source.typeComposantLabel === 'string' && source.typeComposantLabel.length > 0) { - (result as any).typeComposantLabel = source.typeComposantLabel - } - if (typeof source.modelId === 'string' && source.modelId.length > 0) { - (result as any).modelId = source.modelId - } - if (typeof source.familyCode === 'string' && source.familyCode.length > 0) { - (result as any).familyCode = source.familyCode - } - if (typeof source.alias === 'string' && source.alias.length > 0) { - (result as any).alias = source.alias - } - - return result -} - -const hydrateCustomFields = (fields: any[]): any[] => { - if (!Array.isArray(fields)) { - return [] - } - - return fields.map((field, index) => { - const valueObject = extractFieldValueObject(field) - const name = typeof field?.name === 'string' - ? field.name - : typeof field?.key === 'string' - ? field.key - : '' - - const candidateType = - typeof field?.type === 'string' && field.type - ? field.type - : typeof valueObject?.type === 'string' - ? valueObject.type - : '' - const allowedTypes: ComponentModelCustomFieldType[] = ['text', 'number', 'select', 'boolean', 'date'] - const type = allowedTypes.includes(candidateType as ComponentModelCustomFieldType) - ? (candidateType as ComponentModelCustomFieldType) - : 'text' - - const required = - typeof field?.required === 'boolean' - ? field.required - : typeof valueObject?.required === 'boolean' - ? valueObject.required - : false - - const options = - toStringArray(field?.options) || - toStringArray(valueObject?.options) || - toStringArray((valueObject as any)?.choices) || - [] - - const optionsText = typeof field?.optionsText === 'string' - ? field.optionsText - : options.length - ? options.join('\n') - : '' - - const defaultCandidate = - field?.defaultValue ?? valueObject?.defaultValue ?? field?.value ?? field?.default ?? null - const resolvedDefault = (() => { - if (defaultCandidate === undefined || defaultCandidate === null) { - return undefined - } - if (typeof defaultCandidate === 'object') { - if (defaultCandidate === null) { - return undefined - } - if ('defaultValue' in (defaultCandidate as Record)) { - return (defaultCandidate as Record).defaultValue - } - if ('value' in (defaultCandidate as Record)) { - return (defaultCandidate as Record).value - } - return undefined - } - return defaultCandidate - })() - const defaultValue = - resolvedDefault !== undefined && resolvedDefault !== null && resolvedDefault !== '' - ? String(resolvedDefault) - : '' - - const id = typeof field?.id === 'string' ? field.id : undefined - const customFieldId = typeof field?.customFieldId === 'string' ? field.customFieldId : undefined - const orderIndex = typeof field?.orderIndex === 'number' ? field.orderIndex : index - - return { - name, - type, - required, - options, - optionsText, - defaultValue, - id, - customFieldId, - orderIndex, - } - }) -} - -const hydratePieces = (pieces: any[]): ComponentModelPiece[] => { - if (!Array.isArray(pieces)) { - return [] - } - - return pieces.map((piece) => ({ - typePieceId: piece?.typePieceId ?? piece?.typePiece?.id ?? '', - typePieceLabel: piece?.typePieceLabel ?? piece?.typePiece?.name ?? '', - reference: piece?.reference ?? '', - familyCode: piece?.familyCode ?? piece?.typePiece?.code ?? '', - role: piece?.role ?? '', - })) -} - -const hydrateProducts = (products: any[]): ComponentModelProduct[] => { - if (!Array.isArray(products)) { - return [] - } - - return products.map((product) => ({ - typeProductId: product?.typeProductId ?? product?.typeProduct?.id ?? '', - typeProductLabel: product?.typeProductLabel ?? product?.typeProduct?.name ?? '', - reference: product?.reference ?? '', - familyCode: product?.familyCode ?? product?.typeProduct?.code ?? '', - role: product?.role ?? '', - })) -} - -const hydrateSubcomponents = (components: any[]): ComponentModelStructureNode[] => { - if (!Array.isArray(components)) { - return [] - } - - return components.map((component) => ({ - typeComposantId: component?.typeComposantId ?? component?.typeComposant?.id ?? '', - typeComposantLabel: component?.typeComposantLabel ?? component?.typeComposant?.name ?? '', - modelId: component?.modelId ?? '', - familyCode: component?.familyCode ?? component?.typeComposant?.code ?? '', - alias: component?.alias ?? component?.name ?? '', - subcomponents: hydrateSubcomponents( - Array.isArray(component?.subcomponents) - ? component.subcomponents - : component?.subComponents, - ), - })) -} - -export const hydrateStructureForEditor = (input: any): ComponentModelStructure => { - const source = cloneStructure(input) - return { - customFields: hydrateCustomFields(source.customFields), - pieces: hydratePieces(source.pieces), - products: hydrateProducts(source.products), - subcomponents: hydrateSubcomponents( - Array.isArray(source.subcomponents) ? source.subcomponents : (source as any).subComponents, - ), - typeComposantId: source.typeComposantId ?? '', - typeComposantLabel: source.typeComposantLabel ?? '', - modelId: source.modelId ?? '', - familyCode: source.familyCode ?? '', - alias: source.alias ?? '', - } -} - -const mapComponentCustomFields = (fields: any[]) => { - if (!Array.isArray(fields)) { - return [] - } - return hydrateCustomFields(fields).map((field, index) => { - const defaultValue = - field?.defaultValue !== undefined && field?.defaultValue !== null && field?.defaultValue !== '' - ? field.defaultValue - : null - return { - name: typeof field?.name === 'string' ? field.name : '', - type: field?.type ?? 'text', - required: !!field?.required, - options: Array.isArray(field?.options) ? field.options : [], - optionsText: typeof field?.optionsText === 'string' ? field.optionsText : '', - defaultValue, - id: typeof (field as any)?.id === 'string' ? (field as any).id : undefined, - customFieldId: - typeof (field as any)?.customFieldId === 'string' - ? (field as any).customFieldId - : undefined, - orderIndex: typeof field?.orderIndex === 'number' ? field.orderIndex : index, - } - }) -} - -const mapComponentPieces = (pieces: any[]): ComponentModelPiece[] => { - if (!Array.isArray(pieces)) { - return [] - } - return pieces.map((piece) => ({ - reference: piece?.reference ?? '', - typePieceId: piece?.typePieceId ?? piece?.typePiece?.id ?? '', - typePieceLabel: piece?.typePieceLabel ?? piece?.typePiece?.name ?? '', - familyCode: piece?.familyCode ?? piece?.typePiece?.code ?? '', - role: piece?.role ?? '', - })) -} - -const mapComponentProducts = (products: any[]): ComponentModelProduct[] => { - if (!Array.isArray(products)) { - return [] - } - return products.map((product) => ({ - reference: product?.reference ?? '', - typeProductId: product?.typeProductId ?? product?.typeProduct?.id ?? '', - typeProductLabel: product?.typeProductLabel ?? product?.typeProduct?.name ?? '', - familyCode: product?.familyCode ?? product?.typeProduct?.code ?? '', - role: product?.role ?? '', - })) -} - -const mapSubcomponents = (components: any[]): ComponentModelStructureNode[] => { - if (!Array.isArray(components)) { - return [] - } - return components.map((component) => ({ - typeComposantId: component?.typeComposantId ?? component?.typeComposant?.id ?? '', - typeComposantLabel: component?.typeComposantLabel ?? component?.typeComposant?.name ?? '', - modelId: component?.modelId ?? '', - familyCode: component?.familyCode ?? component?.typeComposant?.code ?? '', - alias: component?.alias ?? component?.name ?? '', - subcomponents: mapSubcomponents( - Array.isArray(component?.subcomponents) - ? component.subcomponents - : component?.subComponents, - ), - })) -} - -export const extractStructureFromComponent = (component: any) => { - if (!component) { - return defaultStructure() - } - - const raw = { - customFields: mapComponentCustomFields(component.customFields), - pieces: mapComponentPieces(component.pieces), - products: mapComponentProducts(component.products), - subcomponents: mapSubcomponents( - Array.isArray(component?.subcomponents) - ? component.subcomponents - : component?.subComponents, - ), - typeComposantId: component?.typeComposantId ?? component?.typeComposant?.id ?? '', - typeComposantLabel: component?.typeComposant?.name ?? component?.typeComposantLabel ?? '', - modelId: component?.modelId ?? '', - familyCode: component?.familyCode ?? component?.typeComposant?.code ?? '', - alias: component?.alias ?? component?.name ?? '', - } - - return normalizeStructureForEditor(raw) -} - -export const computeStructureStats = (structure: any): ModelStructurePreview => { - if (!structure || typeof structure !== 'object') { - return { customFields: 0, pieces: 0, products: 0, subcomponents: 0 } - } - - return { - customFields: Array.isArray(structure.customFields) ? structure.customFields.length : 0, - pieces: Array.isArray(structure.pieces) ? structure.pieces.length : 0, - products: Array.isArray(structure.products) ? structure.products.length : 0, - subcomponents: Array.isArray(structure.subcomponents) - ? structure.subcomponents.length - : Array.isArray(structure.subComponents) - ? structure.subComponents.length - : 0, - } -} - -export const formatStructurePreview = (structure: any) => { - const stats = computeStructureStats(structure) - if (!stats.customFields && !stats.pieces && !stats.products && !stats.subcomponents) { - return 'Structure vide' - } - - const segments: string[] = [] - if (stats.customFields) segments.push(`${stats.customFields} champ(s)`) - if (stats.pieces) segments.push(`${stats.pieces} pièce(s)`) - if (stats.products) segments.push(`${stats.products} produit(s)`) - if (stats.subcomponents) segments.push(`${stats.subcomponents} sous-composant(s)`) - return segments.join(' • ') -} - -export interface DefinitionOverridePayload { - name?: string - reference?: string - constructeurIds?: string[] - prix?: number -} - -export const sanitizeDefinitionOverrides = (definition: any): DefinitionOverridePayload | null => { - if (!definition || typeof definition !== 'object') { - return null - } - - const payload: DefinitionOverridePayload = {} - - if (typeof definition.name === 'string') { - const name = definition.name.trim() - if (name.length > 0) { - payload.name = name - } - } - - if (typeof definition.reference === 'string') { - const reference = definition.reference.trim() - if (reference.length > 0) { - payload.reference = reference - } - } - - const constructeurIds = uniqueConstructeurIds( - definition.constructeurIds, - definition.constructeurId, - definition.constructeur, - definition.constructeurs, - ) - if (constructeurIds.length) { - payload.constructeurIds = constructeurIds - } - - if (definition.prix !== undefined && definition.prix !== null && definition.prix !== '') { - const parsed = Number(definition.prix) - if (!Number.isNaN(parsed)) { - payload.prix = parsed - } - } - - return Object.keys(payload).length ? payload : null -} - -export const defaultPieceStructure = (): PieceModelStructure => ({ - ...createEmptyPieceModelStructure(), -}) - -export const defaultProductStructure = (): ProductModelStructure => ({ - ...createEmptyProductModelStructure(), -}) - -const ensurePieceStructureShape = (input: any): PieceModelStructure => { - const base = createEmptyPieceModelStructure() - if (!isPlainObject(input)) { - return base - } - - const clone: PieceModelStructure = { - ...base, - customFields: Array.isArray((input as any).customFields) ? (input as any).customFields : [], - products: Array.isArray((input as any).products) ? (input as any).products : [], - } - - for (const [key, value] of Object.entries(input as Record)) { - if (key === 'customFields' || key === 'products') { - continue - } - clone[key] = value - } - - return clone -} - -export const clonePieceStructure = (input: any): PieceModelStructure => { - try { - const cloned = JSON.parse(JSON.stringify(input ?? defaultPieceStructure())) - return ensurePieceStructureShape(cloned) - } catch (error) { - return defaultPieceStructure() - } -} - -export const cloneProductStructure = (input: any): ProductModelStructure => { - return clonePieceStructure(input) -} - -const sanitizePieceCustomFields = (fields: any[]): PieceModelCustomField[] => { - if (!Array.isArray(fields)) { - return [] - } - - return fields - .map((field, index) => { - const name = typeof field?.name === 'string' ? field.name.trim() : '' - if (!name) { - return null - } - - const type = typeof field?.type === 'string' && field.type ? field.type : 'text' - const required = !!field?.required - - let options: string[] | undefined - if (type === 'select') { - const rawOptions = typeof field?.optionsText === 'string' - ? field.optionsText - : Array.isArray(field?.options) - ? field.options.join('\n') - : '' - const parsed = rawOptions - .split(/\r?\n/) - .map((option: string) => option.trim()) - .filter((option: string) => option.length > 0) - options = parsed.length > 0 ? parsed : undefined - } - - const result: PieceModelCustomField = { name, type, required } - if (options) { - result.options = options - } - const orderIndex = typeof field?.orderIndex === 'number' ? field.orderIndex : index - result.orderIndex = orderIndex - return result - }) - .filter((field): field is PieceModelCustomField => !!field) -} - -const sanitizePieceProducts = (products: any[]): PieceModelProduct[] => { - return sanitizeProducts(products) as PieceModelProduct[] -} - -export const normalizePieceStructureForSave = (input: any): PieceModelStructure => { - const source = clonePieceStructure(input) - const restEntries = Object.entries(source).filter( - ([key]) => key !== 'customFields' && key !== 'products', - ) - return { - ...Object.fromEntries(restEntries), - products: sanitizePieceProducts(source.products || []), - customFields: sanitizePieceCustomFields(source.customFields), - } -} - -const hydratePieceCustomFields = (fields: any[]): PieceModelStructureEditorField[] => { - if (!Array.isArray(fields)) { - return [] - } - - return fields.map((field, index) => ({ - name: field?.name ?? '', - type: field?.type ?? 'text', - required: !!field?.required, - options: Array.isArray(field?.options) ? field.options : undefined, - optionsText: typeof field?.optionsText === 'string' - ? field.optionsText - : Array.isArray(field?.options) - ? field.options.join('\n') - : '', - orderIndex: typeof field?.orderIndex === 'number' ? field.orderIndex : index, - })) -} - -export const hydratePieceStructureForEditor = (input: any): PieceModelStructureForEditor => { - const source = clonePieceStructure(input) - const payload: PieceModelStructureForEditor = { - ...Object.fromEntries( - Object.entries(source).filter(([key]) => key !== 'customFields' && key !== 'products'), - ), - products: hydrateProducts(source.products || []) as PieceModelProduct[], - customFields: hydratePieceCustomFields(source.customFields), - } - return payload -} - -export const formatPieceStructurePreview = (structure: any) => { - if (!structure || typeof structure !== 'object') { - return 'Aucun champ personnalisé' - } - - const customFields = Array.isArray((structure as any).customFields) - ? (structure as any).customFields.length - : 0 - const products = Array.isArray((structure as any).products) - ? (structure as any).products.length - : 0 - - if (!customFields && !products) { - return 'Aucun produit ni champ personnalisé' - } - - const segments: string[] = [] - if (products) { - segments.push(`${products} produit(s)`) - } - if (customFields) { - segments.push(`${customFields} champ(s) personnalisé(s)`) - } - - return segments.join(' · ') -} - -export const normalizeProductStructureForSave = (input: any): ProductModelStructure => - normalizePieceStructureForSave(input) - -export const hydrateProductStructureForEditor = (input: any) => - hydratePieceStructureForEditor(input) - -export const formatProductStructurePreview = (structure: any) => - formatPieceStructurePreview(structure) +export { + isPlainObject, + defaultStructure, + cloneStructure, + toStringArray, + extractFieldValueObject, + sanitizeCustomFields, + sanitizePieces, + sanitizeProducts, + hydrateProducts, + normalizeStructureForEditor, + normalizeStructureForSave, + hydrateStructureForEditor, + extractStructureFromComponent, + computeStructureStats, + formatStructurePreview, + type ModelStructurePreview, +} from './model/componentStructure' + +export { + defaultPieceStructure, + defaultProductStructure, + clonePieceStructure, + cloneProductStructure, + normalizePieceStructureForSave, + hydratePieceStructureForEditor, + formatPieceStructurePreview, + normalizeProductStructureForSave, + hydrateProductStructureForEditor, + formatProductStructurePreview, +} from './model/pieceProductStructure' + +export { + sanitizeDefinitionOverrides, + type DefinitionOverridePayload, +} from './model/definitionOverrides' From daaa1c4cb9c892449874157255fe86856970b2c7 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 9 Feb 2026 11:19:22 +0100 Subject: [PATCH 141/274] refactor(machine): decompose detail page into composables + 7 components (F1.1) Extract 2 composables (useMachineDetailData, useMachineSkeletonEditor) and 7 UI components from machine/[id].vue, reducing it from 2989 to 219 LOC. Co-Authored-By: Claude Opus 4.6 --- .../machine/MachineComponentsCard.vue | 53 + .../machine/MachineDetailHeader.vue | 76 + .../machine/MachineDocumentsCard.vue | 116 + app/components/machine/MachineInfoCard.vue | 185 + app/components/machine/MachinePiecesCard.vue | 34 + .../machine/MachineProductsCard.vue | 62 + .../machine/MachineSkeletonSummary.vue | 193 ++ app/composables/useMachineDetailData.ts | 1404 ++++++++ app/composables/useMachineSkeletonEditor.ts | 838 +++++ app/pages/machine/[id].vue | 3076 +---------------- 10 files changed, 3114 insertions(+), 2923 deletions(-) create mode 100644 app/components/machine/MachineComponentsCard.vue create mode 100644 app/components/machine/MachineDetailHeader.vue create mode 100644 app/components/machine/MachineDocumentsCard.vue create mode 100644 app/components/machine/MachineInfoCard.vue create mode 100644 app/components/machine/MachinePiecesCard.vue create mode 100644 app/components/machine/MachineProductsCard.vue create mode 100644 app/components/machine/MachineSkeletonSummary.vue create mode 100644 app/composables/useMachineDetailData.ts create mode 100644 app/composables/useMachineSkeletonEditor.ts diff --git a/app/components/machine/MachineComponentsCard.vue b/app/components/machine/MachineComponentsCard.vue new file mode 100644 index 0000000..55b3e11 --- /dev/null +++ b/app/components/machine/MachineComponentsCard.vue @@ -0,0 +1,53 @@ + + + diff --git a/app/components/machine/MachineDetailHeader.vue b/app/components/machine/MachineDetailHeader.vue new file mode 100644 index 0000000..4f54a17 --- /dev/null +++ b/app/components/machine/MachineDetailHeader.vue @@ -0,0 +1,76 @@ + + + diff --git a/app/components/machine/MachineDocumentsCard.vue b/app/components/machine/MachineDocumentsCard.vue new file mode 100644 index 0000000..8a52f7f --- /dev/null +++ b/app/components/machine/MachineDocumentsCard.vue @@ -0,0 +1,116 @@ +
Aperçu Nom Catégorie Référence
+ + {{ piece.name || 'Pièce sans nom' }} {{ piece.typePiece?.name || '—' }} {{ piece.reference || '—' }}