diff --git a/.github/workflows/build-devmode.yaml b/.github/workflows/build-devmode.yaml deleted file mode 100644 index 05da050af..000000000 --- a/.github/workflows/build-devmode.yaml +++ /dev/null @@ -1,56 +0,0 @@ -name: Build the dev mode UI - -on: - # Runs on pushes targeting the `main` branch, and only for the `frontend/dev-mode/**` path. - pull_request: - paths: - - 'frontend/dev-mode/**' - - # Allows us to run this workflow manually from the Actions tab - workflow_dispatch: - -env: - PNPM_CACHE_STORE_PATH: "" - -jobs: - build-ui: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - ## install build dependencies for frontend generation - - name: Install Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version-file: './frontend/dev-mode/.nvmrc' - - - name: Install pnpm - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - with: - package_json_file: frontend/dev-mode/package.json - run_install: false - - - name: Get pnpm store directory - shell: bash - run: | - echo "PNPM_CACHE_STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - name: Setup pnpm cache - with: - path: ${{ env.PNPM_CACHE_STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: | - cd ./frontend/dev-mode - pnpm install - - - name: Run the build - run: | - cd ./frontend/dev-mode - pnpm build diff --git a/.github/workflows/platform-release.yaml b/.github/workflows/platform-release.yaml index 9fa6e35b7..b403d6679 100644 --- a/.github/workflows/platform-release.yaml +++ b/.github/workflows/platform-release.yaml @@ -37,17 +37,6 @@ jobs: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - ## install build dependencies for frontend generation - - name: Install Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version-file: './frontend/dev-mode/.nvmrc' - - - name: Install pnpm - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - with: - package_json_file: './docs/package.json' - - name: Setup Go uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: diff --git a/.gitignore b/.gitignore index 663c46929..deb3020cc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,3 @@ kit kit.exe dist/ -pkg/lib/harness/generated/downloads/ -pkg/lib/harness/ui.tar.gz -pkg/lib/harness/llamafile -pkg/lib/harness/checksums.txt -pkg/lib/harness/llamafile.tar.gz diff --git a/AGENTS.md b/AGENTS.md index 8d698ba28..491aaadf4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -106,17 +106,6 @@ go test ./pkg/cmd/pack -v go install . ``` -### Frontend Dev Mode UI - -```bash -cd frontend/dev-mode -pnpm install -pnpm dev # Development server -pnpm build # Production build -pnpm type-check # TypeScript checking -pnpm lint # ESLint with auto-fix -``` - ### Documentation Site ```bash @@ -136,7 +125,6 @@ pnpm docs:preview # Preview built docs - **Libraries**: Core functionality in `pkg/lib/`: - `kitfile/`: Kitfile manifest parsing, validation, and generation - `repo/local/` & `repo/remote/`: Repository management for local storage and OCI registries - - `harness/`: LLM integration with llamafile for local inference - `filesystem/`: File operations, caching, and ignore patterns - `network/`: Authentication and network operations @@ -146,9 +134,8 @@ pnpm docs:preview # Preview built docs - **Kitfile**: YAML manifest format defining ModelKit contents (spec in `pkg/artifact/kitfile.md`) - **Repository Management**: Uses OCI layout for local storage, compatible with container registries -### Frontend Components +### Documentation -- **Dev Mode UI**: Vue 3 + TypeScript SPA for local LLM interaction in `frontend/dev-mode/` - **Documentation**: VitePress-based site in `docs/` with comprehensive guides and API reference ### CLI Command Pattern diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9177457d6..632bdf637 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,12 +55,6 @@ If you think there's something else you can help with please contact us in the [ go mod tidy ``` -1. Generate the dev mode harness and ui - - ```shell - go generate ./... - ``` - 1. Build the Kit CLI: Compile the source code into an executable named kit: ```shell diff --git a/cmd/root.go b/cmd/root.go index 945190759..f91e72c0a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -23,7 +23,6 @@ import ( "os" "path/filepath" - "github.com/kitops-ml/kitops/pkg/cmd/dev" "github.com/kitops-ml/kitops/pkg/cmd/diff" "github.com/kitops-ml/kitops/pkg/cmd/info" "github.com/kitops-ml/kitops/pkg/cmd/inspect" @@ -163,7 +162,6 @@ func addSubcommands(rootCmd *cobra.Command) { rootCmd.AddCommand(login.LoginCommand()) rootCmd.AddCommand(logout.LogoutCommand()) rootCmd.AddCommand(version.VersionCommand()) - rootCmd.AddCommand(dev.DevCommand()) rootCmd.AddCommand(kitinit.InitCommand()) rootCmd.AddCommand(diff.DiffCommand()) rootCmd.AddCommand(kitimport.ImportCommand()) diff --git a/docs/src/docs/deploy.md b/docs/src/docs/deploy.md index ec58a1c1c..98ed5e76c 100644 --- a/docs/src/docs/deploy.md +++ b/docs/src/docs/deploy.md @@ -1,13 +1,11 @@ --- -title: Deploying AI with KitOps - Kubernetes, Containers, and Local LLMs -description: Learn how to securely deploy AI/ML models to Kubernetes, container runtimes, or run LLMs. Includes init containers, custom Dockerfiles, and dev workflows. -keywords: deploy modelkit, kitops deployment, run ml model in kubernetes, init container ml model, containerized ai model, kitops docker, run llm locally, gguf llm deploy, kit dev start, oci model deployment, ml model runtime, mlops deployment cli, modelpack +title: Deploying AI with KitOps - Kubernetes and Containers +description: Learn how to securely deploy AI/ML models to Kubernetes or other container runtimes. Includes init containers and custom Dockerfiles. +keywords: deploy modelkit, kitops deployment, run ml model in kubernetes, init container ml model, containerized ai model, kitops docker, oci model deployment, ml model runtime, mlops deployment cli, modelpack --- # Deploying KitOps ModelKits -This page outlines how to deploy models stored in KitOps ModelKits either: -1. To [Kubernetes or other shared container runtimes](#deploying-to-kubernetes-or-containers) (compatible with all model types) -1. To [run an LLM locally](#running-llms-locally) (using `kit dev`) +This page outlines how to deploy models stored in KitOps ModelKits to [Kubernetes or other shared container runtimes](#deploying-to-kubernetes-or-containers) (compatible with all model types). ## Deploying to Kubernetes or Containers @@ -122,49 +120,7 @@ Example `dockerfile` for a custom container that has `my-modelkit` built into it **Questions or suggestions?** Drop an [issue in our GitHub repository](https://github.com/kitops-ml/kitops/issues) or join [our Discord server](https://discord.gg/Tapeh8agYy) to get support or share your feedback. -## Running LLMs Locally - -If you're using Kit with LLMs you can quickly run the model locally to speed integration, testing, or experimentation. - -::: tip -Kit dev currently only works with `GGUF` serialized models, if you'd like to expand its support for other types please create a [feature issue](https://github.com/kitops-ml/kitops/issues) and describe your planned approach. -::: - -To run the ModelKit locally, first create a new directory for your LLM: - -```sh -mkdir kitdev -cd kitdev -``` - -Now unpack an LLM ModelKit - there are several on [Jozu Hub](https://jozu.ml/discover), but here we're using Phi3 Mini because of its size: - - -```sh -kit unpack jozu.ml/jozu/phi3:3.8b-mini-instruct-4k-q4_K_M -``` - -Now start your LLM dev server locally using the [kit dev start command](../cli/cli-reference/#kit-dev-start): - -```sh -kit dev start . -``` - -In the command output you'll see a URL you can use to interact with the LLM (there's a command flag to always use the same port). You can control parameters of the model, change the prompt, or chat with the LLM. - -If you need to get logs use the [dev logs command](../cli/cli-reference/#kit-dev-logs): - -```sh -kit dev logs -``` - -When you're done don't forget to stop the Kit dev server: - -```sh -kit dev stop -``` - --- **Have feedback or questions?** -Open an [issue on GitHub](https://github.com/kitops-ml/kitops/issues) or [join us on Discord](https://discord.gg/Tapeh8agYy). \ No newline at end of file +Open an [issue on GitHub](https://github.com/kitops-ml/kitops/issues) or [join us on Discord](https://discord.gg/Tapeh8agYy). diff --git a/docs/src/docs/kitfile/kf-overview.md b/docs/src/docs/kitfile/kf-overview.md index 69055dd37..8ba014f2e 100644 --- a/docs/src/docs/kitfile/kf-overview.md +++ b/docs/src/docs/kitfile/kf-overview.md @@ -169,5 +169,3 @@ docs: --- **Questions or suggestions?** Drop an [issue in our GitHub repository](https://github.com/kitops-ml/kitops/issues) or join [our Discord server](https://discord.gg/Tapeh8agYy) to get support or share your feedback. - - diff --git a/docs/src/docs/next-steps.md b/docs/src/docs/next-steps.md index 50602cc70..6cb79b7e5 100644 --- a/docs/src/docs/next-steps.md +++ b/docs/src/docs/next-steps.md @@ -395,6 +395,4 @@ mymodel champion Rajat Finetuning_SLM 13.1 MiB sha256:f268a74f You can learn more about all the Kit CLI commands from our [command reference doc](../cli/cli-reference/). -To learn about how to run an LLM locally using Kit, see our [Kit Dev](../deploy/#running-llms-locally) documentation. - Thanks for taking some time to play with Kit. We'd love to hear what you think. Feel free to drop us an [issue in our GitHub repository](https://github.com/kitops-ml/kitops/issues) or join [our Discord server](https://discord.gg/Tapeh8agYy). diff --git a/frontend/dev-mode/.editorconfig b/frontend/dev-mode/.editorconfig deleted file mode 100644 index 7053c49a0..000000000 --- a/frontend/dev-mode/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -[*.{js,jsx,ts,tsx,vue}] -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true diff --git a/frontend/dev-mode/.eslintrc.cjs b/frontend/dev-mode/.eslintrc.cjs deleted file mode 100644 index d789352bc..000000000 --- a/frontend/dev-mode/.eslintrc.cjs +++ /dev/null @@ -1,63 +0,0 @@ -/* eslint-env node */ -require('@rushstack/eslint-patch/modern-module-resolution') - -module.exports = { - root: true, - 'extends': [ - 'plugin:vue/vue3-essential', - 'eslint:recommended', - '@vue/eslint-config-typescript' - ], - parserOptions: { - ecmaVersion: 'latest' - }, - plugins: [ - 'import', - ], - rules: { - quotes: ['error', 'single', { 'avoidEscape': true }], - 'no-unused-vars': 'off', - '@typescript-eslint/no-unused-vars': ['error', { 'argsIgnorePattern': '^_' }], - semi: ['error', 'never'], - 'prefer-promise-reject-errors': 'off', - 'vue/max-len': ['warn', { - code: 120, - template: 300 - }], - 'vue/component-tags-order': ['error', { - order: ['script', 'template', 'style'] - }], - 'vue/multi-word-component-names': 'off', - 'vue/html-indent': ['error', 2, { - attribute: 1, - baseIndent: 0, - closeBracket: 1, - alignAttributesVertically: false, - ignores: [], - }], - 'vue/html-closing-bracket-spacing': 'error', - 'vue/html-closing-bracket-newline': ['error', { - singleline: 'never', - multiline: 'never' - }], - 'vue/no-reserved-component-names': 'off', - 'import/order': ['error', { - 'newlines-between': 'always', - alphabetize: { - order: 'asc', - caseInsensitive: true, - }, - }], - }, - globals: { - // env globals - process: true, - // Vue Macros - defineProps: 'readonly', - defineEmits: 'readonly', - defineExpose: 'readonly', - withDefaults: 'readonly', - // env vars - config: 'readable', - } -} diff --git a/frontend/dev-mode/.gitignore b/frontend/dev-mode/.gitignore deleted file mode 100644 index 8ee54e8d3..000000000 --- a/frontend/dev-mode/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -.DS_Store -dist -dist-ssr -coverage -*.local - -/cypress/videos/ -/cypress/screenshots/ - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? - -*.tsbuildinfo diff --git a/frontend/dev-mode/.nvmrc b/frontend/dev-mode/.nvmrc deleted file mode 100644 index 42e31a00c..000000000 --- a/frontend/dev-mode/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v20.14.0 diff --git a/frontend/dev-mode/README.md b/frontend/dev-mode/README.md deleted file mode 100644 index 69cdc84b2..000000000 --- a/frontend/dev-mode/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Kit Dev Mode - -This is the UI for the dev mode for Kit cli. - -## To run this locally - -Run - -```sh -pnpm i -pnpm dev -``` - -go to http://localhost:5173 in your browser - -Enjoy! - -To build this: - -Run - -```sh -pnpm build -``` - -The final built content is inside the `dist` folder. \ No newline at end of file diff --git a/frontend/dev-mode/env.d.ts b/frontend/dev-mode/env.d.ts deleted file mode 100644 index 0dc156816..000000000 --- a/frontend/dev-mode/env.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/// -/// - -declare module '*.vue' { - import { DefineComponent } from 'vue' - const component: DefineComponent<{}, {}, any> - export default component -} diff --git a/frontend/dev-mode/global.d.ts b/frontend/dev-mode/global.d.ts deleted file mode 100644 index a3721cec7..000000000 --- a/frontend/dev-mode/global.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare global { - // custom class props for vue components - type ClassProp = string | Record - type ClassProps = ClassProp | ClassProp[] -} - -export {} diff --git a/frontend/dev-mode/index.html b/frontend/dev-mode/index.html deleted file mode 100644 index 196c990d1..000000000 --- a/frontend/dev-mode/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - KitOps dev mode - - -
- - -
- - diff --git a/frontend/dev-mode/package.json b/frontend/dev-mode/package.json deleted file mode 100644 index c60c5e7f7..000000000 --- a/frontend/dev-mode/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "kitops-dev-mode", - "version": "0.0.0", - "private": true, - "packageManager": "pnpm@10.33.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "run-p type-check \"build-only {@}\" --", - "preview": "vite preview", - "build-only": "vite build", - "type-check": "vue-tsc --build --force", - "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore" - }, - "dependencies": { - "@speed-highlight/core": "^1.2.15", - "@vueuse/components": "^10.11.1", - "just-use-native-fetch": "^1.0.0", - "markdown-it": "^14.1.1", - "vue": "^3.5.34", - "vue-router": "^4.6.4" - }, - "devDependencies": { - "@iconify-json/ri": "^1.2.10", - "@rushstack/eslint-patch": "^1.16.1", - "@tsconfig/node20": "^20.1.9", - "@types/node": "^20.19.41", - "@vitejs/plugin-vue": "^5.2.4", - "@vue/eslint-config-typescript": "^12.0.0", - "@vue/tsconfig": "^0.5.1", - "@vueuse/core": "^10.11.1", - "autoprefixer": "^10.5.0", - "eslint": "^8.57.1", - "eslint-plugin-import": "^2.32.0", - "eslint-plugin-vue": "^9.33.0", - "npm-run-all2": "^6.2.6", - "postcss": "^8.5.15", - "tailwindcss": "^3.4.19", - "typescript": "~5.4.5", - "unplugin-icons": "^0.16.6", - "vite": "^5.4.21", - "vite-plugin-dynamic-import": "^1.6.0", - "vue-tsc": "^2.2.12" - } -} \ No newline at end of file diff --git a/frontend/dev-mode/pnpm-lock.yaml b/frontend/dev-mode/pnpm-lock.yaml deleted file mode 100644 index a085d0870..000000000 --- a/frontend/dev-mode/pnpm-lock.yaml +++ /dev/null @@ -1,4223 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@speed-highlight/core': - specifier: ^1.2.15 - version: 1.2.15 - '@vueuse/components': - specifier: ^10.11.1 - version: 10.11.1(vue@3.5.34(typescript@5.4.5)) - just-use-native-fetch: - specifier: ^1.0.0 - version: 1.0.0 - markdown-it: - specifier: ^14.1.1 - version: 14.1.1 - vue: - specifier: ^3.5.34 - version: 3.5.34(typescript@5.4.5) - vue-router: - specifier: ^4.6.4 - version: 4.6.4(vue@3.5.34(typescript@5.4.5)) - devDependencies: - '@iconify-json/ri': - specifier: ^1.2.10 - version: 1.2.10 - '@rushstack/eslint-patch': - specifier: ^1.16.1 - version: 1.16.1 - '@tsconfig/node20': - specifier: ^20.1.9 - version: 20.1.9 - '@types/node': - specifier: ^20.19.41 - version: 20.19.41 - '@vitejs/plugin-vue': - specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@20.19.41))(vue@3.5.34(typescript@5.4.5)) - '@vue/eslint-config-typescript': - specifier: ^12.0.0 - version: 12.0.0(eslint-plugin-vue@9.33.0(eslint@8.57.1))(eslint@8.57.1)(typescript@5.4.5) - '@vue/tsconfig': - specifier: ^0.5.1 - version: 0.5.1 - '@vueuse/core': - specifier: ^10.11.1 - version: 10.11.1(vue@3.5.34(typescript@5.4.5)) - autoprefixer: - specifier: ^10.5.0 - version: 10.5.0(postcss@8.5.15) - eslint: - specifier: ^8.57.1 - version: 8.57.1 - eslint-plugin-import: - specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.4.5))(eslint@8.57.1) - eslint-plugin-vue: - specifier: ^9.33.0 - version: 9.33.0(eslint@8.57.1) - npm-run-all2: - specifier: ^6.2.6 - version: 6.2.6 - postcss: - specifier: ^8.5.15 - version: 8.5.15 - tailwindcss: - specifier: ^3.4.19 - version: 3.4.19(yaml@2.7.1) - typescript: - specifier: ~5.4.5 - version: 5.4.5 - unplugin-icons: - specifier: ^0.16.6 - version: 0.16.6(@vue/compiler-sfc@3.5.34) - vite: - specifier: ^5.4.21 - version: 5.4.21(@types/node@20.19.41) - vite-plugin-dynamic-import: - specifier: ^1.6.0 - version: 1.6.0 - vue-tsc: - specifier: ^2.2.12 - version: 2.2.12(typescript@5.4.5) - -packages: - - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} - - '@antfu/install-pkg@0.1.1': - resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} - - '@antfu/install-pkg@1.1.0': - resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} - - '@antfu/utils@0.7.10': - resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} - - '@antfu/utils@8.1.1': - resolution: {integrity: sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.3': - resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} - - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@eslint/js@8.57.1': - resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@humanwhocodes/config-array@0.13.0': - resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/object-schema@2.0.3': - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - deprecated: Use @eslint/object-schema instead - - '@iconify-json/ri@1.2.10': - resolution: {integrity: sha512-WWMhoncVVM+Xmu9T5fgu2lhYRrKTEWhKk3Com0KiM111EeEsRLiASjpsFKnC/SrB6covhUp95r2mH8tGxhgd5Q==} - - '@iconify/types@2.0.0': - resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - - '@iconify/utils@2.3.0': - resolution: {integrity: sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@rollup/rollup-android-arm-eabi@4.60.4': - resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.60.4': - resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.60.4': - resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.60.4': - resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.60.4': - resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.60.4': - resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} - cpu: [arm] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-arm64-gnu@4.60.4': - resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm64-musl@4.60.4': - resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-loong64-gnu@4.60.4': - resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} - cpu: [loong64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-loong64-musl@4.60.4': - resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-ppc64-musl@4.60.4': - resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} - cpu: [ppc64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-riscv64-musl@4.60.4': - resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-s390x-gnu@4.60.4': - resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-gnu@4.60.4': - resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-musl@4.60.4': - resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rollup/rollup-openbsd-x64@4.60.4': - resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.60.4': - resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.60.4': - resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.60.4': - resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.60.4': - resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.60.4': - resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} - cpu: [x64] - os: [win32] - - '@rtsao/scc@1.1.0': - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - - '@rushstack/eslint-patch@1.16.1': - resolution: {integrity: sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==} - - '@speed-highlight/core@1.2.15': - resolution: {integrity: sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==} - - '@tsconfig/node20@20.1.9': - resolution: {integrity: sha512-IjlTv1RsvnPtUcjTqtVsZExKVq+KQx4g5pCP5tI7rAs6Xesl2qFwSz/tPDBC4JajkL/MlezBu3gPUwqRHl+RIg==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/json5@0.0.29': - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - - '@types/node@20.19.41': - resolution: {integrity: sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==} - - '@types/semver@7.7.1': - resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} - - '@types/web-bluetooth@0.0.20': - resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} - - '@typescript-eslint/eslint-plugin@6.21.0': - resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/parser@6.21.0': - resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/scope-manager@6.21.0': - resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@typescript-eslint/type-utils@6.21.0': - resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/types@6.21.0': - resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@typescript-eslint/typescript-estree@6.21.0': - resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/utils@6.21.0': - resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - - '@typescript-eslint/visitor-keys@6.21.0': - resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@ungap/structured-clone@1.3.1': - resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} - - '@vitejs/plugin-vue@5.2.4': - resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} - engines: {node: ^18.0.0 || >=20.0.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 - vue: ^3.2.25 - - '@volar/language-core@2.4.15': - resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==} - - '@volar/source-map@2.4.15': - resolution: {integrity: sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==} - - '@volar/typescript@2.4.15': - resolution: {integrity: sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==} - - '@vue/compiler-core@3.5.34': - resolution: {integrity: sha512-s9cLyK5mLcvZ4Agva5QgRsQyLKvts9WbU9DB6NqiZkkGEdwmcEiylj5Jbwkp680drF/NNCV8OlAJSe+yMLxaJw==} - - '@vue/compiler-dom@3.5.34': - resolution: {integrity: sha512-EbF/T++k0e2MMZlJsBhzK8Sgwt0HcIPOhzn1CTB/lv6sQcyk+OWf8YeiLxZp3ro7MbbLcAfAJ6sEvjFWuNgUCw==} - - '@vue/compiler-sfc@3.5.34': - resolution: {integrity: sha512-D/ihr6uZeIt6r+pVZf46RWT1fAsLFMbUP7k8G1VkiiWexriED9GrX3echHd4Abbt17zjlfiFJ8z7a3BxZOPNjg==} - - '@vue/compiler-ssr@3.5.34': - resolution: {integrity: sha512-cDtTHKibkThKGHH1SP+WdccquNRYQDFH6rRjQCqT9G2ltFAfoR5pUftpab/z+aM5mW9HLLVQW7hfKKQe/1GBeQ==} - - '@vue/compiler-vue2@2.7.16': - resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} - - '@vue/devtools-api@6.6.4': - resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - - '@vue/eslint-config-typescript@12.0.0': - resolution: {integrity: sha512-StxLFet2Qe97T8+7L8pGlhYBBr8Eg05LPuTDVopQV6il+SK6qqom59BA/rcFipUef2jD8P2X44Vd8tMFytfvlg==} - engines: {node: ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 - eslint-plugin-vue: ^9.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@vue/language-core@2.2.12': - resolution: {integrity: sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@vue/reactivity@3.5.34': - resolution: {integrity: sha512-y9XDjCEuBp+98k+UL5dbYkh57AHU4o6cxZedOPXw3bmrZZYLQsVHguGurq7hVrPCSrQtrnz1f9dssyFr+dMXfQ==} - - '@vue/runtime-core@3.5.34': - resolution: {integrity: sha512-mKeBYvu8tcMSLhypAHBmriUFfWXKTCF/23Z4jiCoYK3UtWepkliViNLuR90V9XOyD62mUxs9p1jsrpK3CCGIzw==} - - '@vue/runtime-dom@3.5.34': - resolution: {integrity: sha512-e8kZzERmCwUnBRVsgSQlAfrfU2rGoy0FFKPBXSlfEjc/O3KfA7QP0t1/2ZylrbchjmIKB4dPTd07A6WPr0eOrg==} - - '@vue/server-renderer@3.5.34': - resolution: {integrity: sha512-nHxmJoTrKsmrkbILRhkC9gY1G3moZbJTqCzDd7DOOzG5KH9oeJ0Unqrff5f9v0pW//jES05ZkJcNtfE8JjOIew==} - peerDependencies: - vue: 3.5.34 - - '@vue/shared@3.5.34': - resolution: {integrity: sha512-24uqU4OIiX29ryC3MeWid/Xf2fa2EFRUVLb77nRhk+UrTVrh/XiGtFAFmJBAtBRbjwNdsPRP+jj/OL27Eg1NDA==} - - '@vue/tsconfig@0.5.1': - resolution: {integrity: sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==} - - '@vueuse/components@10.11.1': - resolution: {integrity: sha512-ThcreQCX/eq61sLkLKjigD4PQvs3Wy4zglICvQH9tP6xl87y5KsQEoizn6OI+R3hrOgwQHLJe7Y0wLLh3fBKcg==} - - '@vueuse/core@10.11.1': - resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} - - '@vueuse/metadata@10.11.1': - resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==} - - '@vueuse/shared@10.11.1': - resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv@6.15.0: - resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} - - alien-signals@1.0.13: - resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} - engines: {node: '>=12'} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} - - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} - - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} - - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} - - autoprefixer@10.5.0: - resolution: {integrity: sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - baseline-browser-mapping@2.10.31: - resolution: {integrity: sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==} - engines: {node: '>=6.0.0'} - hasBin: true - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - - brace-expansion@1.1.14: - resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} - - brace-expansion@2.1.0: - resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - browserslist@4.28.2: - resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.9: - resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} - - caniuse-lite@1.0.30001793: - resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - - confbox@0.2.4: - resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} - - data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} - - data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} - - de-indent@1.0.2: - resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - - didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - electron-to-chromium@1.5.360: - resolution: {integrity: sha512-GkcBt6YYAw9SxFWn+xVar4cLVGlXVuswwtRLBozi2zp0GjXs4ZnOrqV4zbXzg35n7w81hCkyJNYicgXlVHAmBA==} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - entities@7.0.1: - resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} - engines: {node: '>=0.12'} - - es-abstract@1.24.2: - resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} - - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-import-resolver-node@0.3.10: - resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} - - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - - eslint-plugin-import@2.32.0: - resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - - eslint-plugin-vue@9.33.0: - resolution: {integrity: sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==} - engines: {node: ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint@8.57.1: - resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. - hasBin: true - - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - - exsolve@1.0.8: - resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} - - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} - - fraction.js@5.3.4: - resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} - - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - - generator-function@2.0.1: - resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} - engines: {node: '>= 0.4'} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - - globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} - - globals@15.15.0: - resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} - engines: {node: '>=18'} - - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} - engines: {node: '>= 0.4'} - - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - inflight@1.0.6: - resolution: {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. - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} - - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} - - is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} - - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} - engines: {node: '>= 0.4'} - - is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} - - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} - - is-generator-function@1.1.2: - resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} - engines: {node: '>= 0.4'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - - is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} - - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} - - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} - - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - - is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} - - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jiti@1.21.7: - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} - hasBin: true - - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-parse-even-better-errors@3.0.2: - resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - - just-use-native-fetch@1.0.0: - resolution: {integrity: sha512-jhj8AcVjFHgRmHBT7ysuXyKYytlTw6e9/FCCHPaxa8ymqN4SOiOFihxRAIj/DrdX1iFUc6mPvNJYK/WW46+p5w==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - linkify-it@5.0.0: - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - - local-pkg@0.4.3: - resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} - engines: {node: '>=14'} - - local-pkg@1.2.1: - resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} - engines: {node: '>=14'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash@4.18.1: - resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - markdown-it@14.1.1: - resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} - hasBin: true - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - mdurl@2.0.0: - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - - memorystream@0.3.1: - resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} - engines: {node: '>= 0.10.0'} - - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - minimatch@3.1.5: - resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - - minimatch@9.0.9: - resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - mlly@1.8.2: - resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - muggle-string@0.4.1: - resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - nanoid@3.3.12: - resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - node-exports-info@1.6.0: - resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} - engines: {node: '>= 0.4'} - - node-releases@2.0.45: - resolution: {integrity: sha512-iIbHXV9eBB2nB0wa7oTsrrXq+qQt+9SIlx9AX3T96YgobtEQfis5n6TJ6vV+3QP8DwdriEAcGhARaFCu37peBg==} - engines: {node: '>=18'} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - npm-normalize-package-bin@3.0.1: - resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - npm-run-all2@6.2.6: - resolution: {integrity: sha512-tkyb4pc0Zb0oOswCb5tORPk9MvVL6gcDq1cMItQHmsbVk1skk7YF6cH+UU2GxeNLHMuk6wFEOSmEmJ2cnAK1jg==} - engines: {node: ^14.18.0 || ^16.13.0 || >=18.0.0, npm: '>= 8'} - hasBin: true - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - package-manager-detector@1.6.0: - resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} - engines: {node: '>=8.6'} - - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} - - pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - - pkg-types@2.3.1: - resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==} - - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - - postcss-import@15.1.0: - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 - - postcss-js@4.1.0: - resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 - - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} - peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - yaml: - optional: true - - postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 - - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} - - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - - postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} - engines: {node: ^10 || ^12 || >=14} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - quansync@0.2.11: - resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} - - read-package-json-fast@3.0.2: - resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} - - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} - engines: {node: '>= 0.4'} - hasBin: true - - resolve@2.0.0-next.7: - resolution: {integrity: sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==} - engines: {node: '>= 0.4'} - hasBin: true - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - - rollup@4.60.4: - resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-array-concat@1.1.4: - resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} - engines: {node: '>=0.4'} - - safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} - - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - semver@7.8.0: - resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} - engines: {node: '>=10'} - hasBin: true - - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - shell-quote@1.8.3: - resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} - engines: {node: '>= 0.4'} - - side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} - - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} - - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} - - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - tailwindcss@3.4.19: - resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} - engines: {node: '>=14.0.0'} - hasBin: true - - text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - tinyexec@1.1.2: - resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} - engines: {node: '>=18'} - - tinyglobby@0.2.16: - resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} - engines: {node: '>=12.0.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - ts-api-utils@1.4.3: - resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' - - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - - typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} - - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} - - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} - - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} - engines: {node: '>=14.17'} - hasBin: true - - uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - - ufo@1.6.4: - resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} - - unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - unplugin-icons@0.16.6: - resolution: {integrity: sha512-jL70sAC7twp4hI/MTfm+vyvTRtHqiEIzf3XOjJz7yzhMEEQnk5Ey5YIXRAU03Mc4BF99ITvvnBzfyRZee86OeA==} - peerDependencies: - '@svgr/core': '>=7.0.0' - '@svgx/core': ^1.0.1 - '@vue/compiler-sfc': ^3.0.2 || ^2.7.0 - vue-template-compiler: ^2.6.12 - vue-template-es2015-compiler: ^1.9.0 - peerDependenciesMeta: - '@svgr/core': - optional: true - '@svgx/core': - optional: true - '@vue/compiler-sfc': - optional: true - vue-template-compiler: - optional: true - vue-template-es2015-compiler: - optional: true - - unplugin@1.16.1: - resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} - engines: {node: '>=14.0.0'} - - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - vite-plugin-dynamic-import@1.6.0: - resolution: {integrity: sha512-TM0sz70wfzTIo9YCxVFwS8OA9lNREsh+0vMHGSkWDTZ7bgd1Yjs5RV8EgB634l/91IsXJReg0xtmuQqP0mf+rg==} - - vite@5.4.21: - resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - - vscode-uri@3.1.0: - resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - - vue-demi@0.14.10: - resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} - engines: {node: '>=12'} - hasBin: true - peerDependencies: - '@vue/composition-api': ^1.0.0-rc.1 - vue: ^3.0.0-0 || ^2.6.0 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - - vue-eslint-parser@9.4.3: - resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} - engines: {node: ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '>=6.0.0' - - vue-router@4.6.4: - resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==} - peerDependencies: - vue: ^3.5.0 - - vue-tsc@2.2.12: - resolution: {integrity: sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==} - hasBin: true - peerDependencies: - typescript: '>=5.0.0' - - vue@3.5.34: - resolution: {integrity: sha512-WdLBG9gm02OgJIG9axd5Hpx0TFLdzVgfG2evFFu8Rur5O/IoGc5cMjnjh3tPL6GnRGsYvUhBSKVPYVcxRKpMCA==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - webpack-virtual-modules@0.6.2: - resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} - - which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} - - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.20: - resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} - engines: {node: '>= 0.4'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - which@3.0.1: - resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} - - yaml@2.7.1: - resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==} - engines: {node: '>= 14'} - hasBin: true - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - -snapshots: - - '@alloc/quick-lru@5.2.0': {} - - '@antfu/install-pkg@0.1.1': - dependencies: - execa: 5.1.1 - find-up: 5.0.0 - - '@antfu/install-pkg@1.1.0': - dependencies: - package-manager-detector: 1.6.0 - tinyexec: 1.1.2 - - '@antfu/utils@0.7.10': {} - - '@antfu/utils@8.1.1': {} - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.28.5': {} - - '@babel/parser@7.29.3': - dependencies: - '@babel/types': 7.29.0 - - '@babel/types@7.29.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm@0.21.5': - optional: true - - '@esbuild/android-x64@0.21.5': - optional: true - - '@esbuild/darwin-arm64@0.21.5': - optional: true - - '@esbuild/darwin-x64@0.21.5': - optional: true - - '@esbuild/freebsd-arm64@0.21.5': - optional: true - - '@esbuild/freebsd-x64@0.21.5': - optional: true - - '@esbuild/linux-arm64@0.21.5': - optional: true - - '@esbuild/linux-arm@0.21.5': - optional: true - - '@esbuild/linux-ia32@0.21.5': - optional: true - - '@esbuild/linux-loong64@0.21.5': - optional: true - - '@esbuild/linux-mips64el@0.21.5': - optional: true - - '@esbuild/linux-ppc64@0.21.5': - optional: true - - '@esbuild/linux-riscv64@0.21.5': - optional: true - - '@esbuild/linux-s390x@0.21.5': - optional: true - - '@esbuild/linux-x64@0.21.5': - optional: true - - '@esbuild/netbsd-x64@0.21.5': - optional: true - - '@esbuild/openbsd-x64@0.21.5': - optional: true - - '@esbuild/sunos-x64@0.21.5': - optional: true - - '@esbuild/win32-arm64@0.21.5': - optional: true - - '@esbuild/win32-ia32@0.21.5': - optional: true - - '@esbuild/win32-x64@0.21.5': - optional: true - - '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': - dependencies: - eslint: 8.57.1 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.2': {} - - '@eslint/eslintrc@2.1.4': - dependencies: - ajv: 6.15.0 - debug: 4.4.3 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.1 - minimatch: 3.1.5 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@8.57.1': {} - - '@humanwhocodes/config-array@0.13.0': - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.3 - minimatch: 3.1.5 - transitivePeerDependencies: - - supports-color - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/object-schema@2.0.3': {} - - '@iconify-json/ri@1.2.10': - dependencies: - '@iconify/types': 2.0.0 - - '@iconify/types@2.0.0': {} - - '@iconify/utils@2.3.0': - dependencies: - '@antfu/install-pkg': 1.1.0 - '@antfu/utils': 8.1.1 - '@iconify/types': 2.0.0 - debug: 4.4.3 - globals: 15.15.0 - kolorist: 1.8.0 - local-pkg: 1.2.1 - mlly: 1.8.2 - transitivePeerDependencies: - - supports-color - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 - - '@rollup/rollup-android-arm-eabi@4.60.4': - optional: true - - '@rollup/rollup-android-arm64@4.60.4': - optional: true - - '@rollup/rollup-darwin-arm64@4.60.4': - optional: true - - '@rollup/rollup-darwin-x64@4.60.4': - optional: true - - '@rollup/rollup-freebsd-arm64@4.60.4': - optional: true - - '@rollup/rollup-freebsd-x64@4.60.4': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-x64-musl@4.60.4': - optional: true - - '@rollup/rollup-openbsd-x64@4.60.4': - optional: true - - '@rollup/rollup-openharmony-arm64@4.60.4': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.60.4': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.60.4': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.60.4': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.60.4': - optional: true - - '@rtsao/scc@1.1.0': {} - - '@rushstack/eslint-patch@1.16.1': {} - - '@speed-highlight/core@1.2.15': {} - - '@tsconfig/node20@20.1.9': {} - - '@types/estree@1.0.8': {} - - '@types/json-schema@7.0.15': {} - - '@types/json5@0.0.29': {} - - '@types/node@20.19.41': - dependencies: - undici-types: 6.21.0 - - '@types/semver@7.7.1': {} - - '@types/web-bluetooth@0.0.20': {} - - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.4.5))(eslint@8.57.1)(typescript@5.4.5)': - dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.4.5) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare: 1.4.0 - semver: 7.8.0 - ts-api-utils: 1.4.3(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.4.5)': - dependencies: - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 - eslint: 8.57.1 - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@6.21.0': - dependencies: - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/visitor-keys': 6.21.0 - - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.4.5)': - dependencies: - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.5) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.4.5) - debug: 4.4.3 - eslint: 8.57.1 - ts-api-utils: 1.4.3(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@6.21.0': {} - - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.4.5)': - dependencies: - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.3 - semver: 7.8.0 - ts-api-utils: 1.4.3(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.4.5)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - '@types/json-schema': 7.0.15 - '@types/semver': 7.7.1 - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.5) - eslint: 8.57.1 - semver: 7.8.0 - transitivePeerDependencies: - - supports-color - - typescript - - '@typescript-eslint/visitor-keys@6.21.0': - dependencies: - '@typescript-eslint/types': 6.21.0 - eslint-visitor-keys: 3.4.3 - - '@ungap/structured-clone@1.3.1': {} - - '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@20.19.41))(vue@3.5.34(typescript@5.4.5))': - dependencies: - vite: 5.4.21(@types/node@20.19.41) - vue: 3.5.34(typescript@5.4.5) - - '@volar/language-core@2.4.15': - dependencies: - '@volar/source-map': 2.4.15 - - '@volar/source-map@2.4.15': {} - - '@volar/typescript@2.4.15': - dependencies: - '@volar/language-core': 2.4.15 - path-browserify: 1.0.1 - vscode-uri: 3.1.0 - - '@vue/compiler-core@3.5.34': - dependencies: - '@babel/parser': 7.29.3 - '@vue/shared': 3.5.34 - entities: 7.0.1 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - - '@vue/compiler-dom@3.5.34': - dependencies: - '@vue/compiler-core': 3.5.34 - '@vue/shared': 3.5.34 - - '@vue/compiler-sfc@3.5.34': - dependencies: - '@babel/parser': 7.29.3 - '@vue/compiler-core': 3.5.34 - '@vue/compiler-dom': 3.5.34 - '@vue/compiler-ssr': 3.5.34 - '@vue/shared': 3.5.34 - estree-walker: 2.0.2 - magic-string: 0.30.21 - postcss: 8.5.15 - source-map-js: 1.2.1 - - '@vue/compiler-ssr@3.5.34': - dependencies: - '@vue/compiler-dom': 3.5.34 - '@vue/shared': 3.5.34 - - '@vue/compiler-vue2@2.7.16': - dependencies: - de-indent: 1.0.2 - he: 1.2.0 - - '@vue/devtools-api@6.6.4': {} - - '@vue/eslint-config-typescript@12.0.0(eslint-plugin-vue@9.33.0(eslint@8.57.1))(eslint@8.57.1)(typescript@5.4.5)': - dependencies: - '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.4.5))(eslint@8.57.1)(typescript@5.4.5) - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.4.5) - eslint: 8.57.1 - eslint-plugin-vue: 9.33.0(eslint@8.57.1) - vue-eslint-parser: 9.4.3(eslint@8.57.1) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@vue/language-core@2.2.12(typescript@5.4.5)': - dependencies: - '@volar/language-core': 2.4.15 - '@vue/compiler-dom': 3.5.34 - '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.34 - alien-signals: 1.0.13 - minimatch: 9.0.9 - muggle-string: 0.4.1 - path-browserify: 1.0.1 - optionalDependencies: - typescript: 5.4.5 - - '@vue/reactivity@3.5.34': - dependencies: - '@vue/shared': 3.5.34 - - '@vue/runtime-core@3.5.34': - dependencies: - '@vue/reactivity': 3.5.34 - '@vue/shared': 3.5.34 - - '@vue/runtime-dom@3.5.34': - dependencies: - '@vue/reactivity': 3.5.34 - '@vue/runtime-core': 3.5.34 - '@vue/shared': 3.5.34 - csstype: 3.2.3 - - '@vue/server-renderer@3.5.34(vue@3.5.34(typescript@5.4.5))': - dependencies: - '@vue/compiler-ssr': 3.5.34 - '@vue/shared': 3.5.34 - vue: 3.5.34(typescript@5.4.5) - - '@vue/shared@3.5.34': {} - - '@vue/tsconfig@0.5.1': {} - - '@vueuse/components@10.11.1(vue@3.5.34(typescript@5.4.5))': - dependencies: - '@vueuse/core': 10.11.1(vue@3.5.34(typescript@5.4.5)) - '@vueuse/shared': 10.11.1(vue@3.5.34(typescript@5.4.5)) - vue-demi: 0.14.10(vue@3.5.34(typescript@5.4.5)) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - - '@vueuse/core@10.11.1(vue@3.5.34(typescript@5.4.5))': - dependencies: - '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 10.11.1 - '@vueuse/shared': 10.11.1(vue@3.5.34(typescript@5.4.5)) - vue-demi: 0.14.10(vue@3.5.34(typescript@5.4.5)) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - - '@vueuse/metadata@10.11.1': {} - - '@vueuse/shared@10.11.1(vue@3.5.34(typescript@5.4.5))': - dependencies: - vue-demi: 0.14.10(vue@3.5.34(typescript@5.4.5)) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - - acorn-jsx@5.3.2(acorn@8.16.0): - dependencies: - acorn: 8.16.0 - - acorn@8.16.0: {} - - ajv@6.15.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - alien-signals@1.0.13: {} - - ansi-regex@5.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.3: {} - - any-promise@1.3.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.2 - - arg@5.0.2: {} - - argparse@2.0.1: {} - - array-buffer-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - is-array-buffer: 3.0.5 - - array-includes@3.1.9: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - is-string: 1.1.1 - math-intrinsics: 1.1.0 - - array-union@2.1.0: {} - - array.prototype.findlastindex@1.2.6: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.flat@1.3.3: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-shim-unscopables: 1.1.0 - - array.prototype.flatmap@1.3.3: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-shim-unscopables: 1.1.0 - - arraybuffer.prototype.slice@1.0.4: - dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - is-array-buffer: 3.0.5 - - async-function@1.0.0: {} - - autoprefixer@10.5.0(postcss@8.5.15): - dependencies: - browserslist: 4.28.2 - caniuse-lite: 1.0.30001793 - fraction.js: 5.3.4 - picocolors: 1.1.1 - postcss: 8.5.15 - postcss-value-parser: 4.2.0 - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.1.0 - - balanced-match@1.0.2: {} - - baseline-browser-mapping@2.10.31: {} - - binary-extensions@2.3.0: {} - - boolbase@1.0.0: {} - - brace-expansion@1.1.14: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.1.0: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browserslist@4.28.2: - dependencies: - baseline-browser-mapping: 2.10.31 - caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.360 - node-releases: 2.0.45 - update-browserslist-db: 1.2.3(browserslist@4.28.2) - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.9: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - callsites@3.1.0: {} - - camelcase-css@2.0.1: {} - - caniuse-lite@1.0.30001793: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - commander@4.1.1: {} - - concat-map@0.0.1: {} - - confbox@0.1.8: {} - - confbox@0.2.4: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - cssesc@3.0.0: {} - - csstype@3.2.3: {} - - data-view-buffer@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-offset@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - de-indent@1.0.2: {} - - debug@3.2.7: - dependencies: - ms: 2.1.3 - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - deep-is@0.1.4: {} - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - - didyoumean@1.2.2: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - dlv@1.1.3: {} - - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - electron-to-chromium@1.5.360: {} - - entities@4.5.0: {} - - entities@7.0.1: {} - - es-abstract@1.24.2: - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - call-bound: 1.0.4 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.3 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-negative-zero: 2.0.3 - is-regex: 1.2.1 - is-set: 2.0.3 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 - math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.4 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.20 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-module-lexer@1.7.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.3 - - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.3 - - es-to-primitive@1.3.0: - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - - esbuild@0.21.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - - escalade@3.2.0: {} - - escape-string-regexp@4.0.0: {} - - eslint-import-resolver-node@0.3.10: - dependencies: - debug: 3.2.7 - is-core-module: 2.16.2 - resolve: 2.0.0-next.7 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.4.5))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.4.5) - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.10 - transitivePeerDependencies: - - supports-color - - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.4.5))(eslint@8.57.1): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.4.5))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1) - hasown: 2.0.3 - is-core-module: 2.16.2 - is-glob: 4.0.3 - minimatch: 3.1.5 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.4.5) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-vue@9.33.0(eslint@8.57.1): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - eslint: 8.57.1 - globals: 13.24.0 - natural-compare: 1.4.0 - nth-check: 2.1.1 - postcss-selector-parser: 6.1.2 - semver: 7.8.0 - vue-eslint-parser: 9.4.3(eslint@8.57.1) - xml-name-validator: 4.0.0 - transitivePeerDependencies: - - supports-color - - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint@8.57.1: - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - '@eslint-community/regexpp': 4.12.2 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.1 - '@humanwhocodes/config-array': 0.13.0 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.3.1 - ajv: 6.15.0 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.7.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.1 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.5 - natural-compare: 1.4.0 - optionator: 0.9.4 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - espree@9.6.1: - dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) - eslint-visitor-keys: 3.4.3 - - esquery@1.7.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-walker@2.0.2: {} - - esutils@2.0.3: {} - - execa@5.1.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - exsolve@1.0.8: {} - - fast-deep-equal@3.1.3: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.20.1: - dependencies: - reusify: 1.1.0 - - fdir@6.5.0(picomatch@4.0.4): - optionalDependencies: - picomatch: 4.0.4 - - file-entry-cache@6.0.1: - dependencies: - flat-cache: 3.2.0 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@3.2.0: - dependencies: - flatted: 3.4.2 - keyv: 4.5.4 - rimraf: 3.0.2 - - flatted@3.4.2: {} - - for-each@0.3.5: - dependencies: - is-callable: 1.2.7 - - fraction.js@5.3.4: {} - - fs.realpath@1.0.0: {} - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.3 - is-callable: 1.2.7 - - functions-have-names@1.2.3: {} - - generator-function@2.0.1: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.3 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-stream@6.0.1: {} - - get-symbol-description@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.5 - once: 1.4.0 - path-is-absolute: 1.0.1 - - globals@13.24.0: - dependencies: - type-fest: 0.20.2 - - globals@15.15.0: {} - - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - - gopd@1.2.0: {} - - graphemer@1.4.0: {} - - has-bigints@1.1.0: {} - - has-flag@4.0.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-proto@1.2.0: - dependencies: - dunder-proto: 1.0.1 - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.3: - dependencies: - function-bind: 1.1.2 - - he@1.2.0: {} - - human-signals@2.1.0: {} - - ignore@5.3.2: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - internal-slot@1.1.0: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.3 - side-channel: 1.1.0 - - is-array-buffer@3.0.5: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - is-async-function@2.1.1: - dependencies: - async-function: 1.0.0 - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-bigint@1.1.0: - dependencies: - has-bigints: 1.1.0 - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-boolean-object@1.2.2: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-callable@1.2.7: {} - - is-core-module@2.16.2: - dependencies: - hasown: 2.0.3 - - is-data-view@1.0.2: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-typed-array: 1.1.15 - - is-date-object@1.1.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-extglob@2.1.1: {} - - is-finalizationregistry@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-generator-function@1.1.2: - dependencies: - call-bound: 1.0.4 - generator-function: 2.0.1 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-map@2.0.3: {} - - is-negative-zero@2.0.3: {} - - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-number@7.0.0: {} - - is-path-inside@3.0.3: {} - - is-regex@1.2.1: - dependencies: - call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.3 - - is-set@2.0.3: {} - - is-shared-array-buffer@1.0.4: - dependencies: - call-bound: 1.0.4 - - is-stream@2.0.1: {} - - is-string@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-symbol@1.1.1: - dependencies: - call-bound: 1.0.4 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.20 - - is-weakmap@2.0.2: {} - - is-weakref@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-weakset@2.0.4: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - isarray@2.0.5: {} - - isexe@2.0.0: {} - - jiti@1.21.7: {} - - js-yaml@4.1.1: - dependencies: - argparse: 2.0.1 - - json-buffer@3.0.1: {} - - json-parse-even-better-errors@3.0.2: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - json5@1.0.2: - dependencies: - minimist: 1.2.8 - - just-use-native-fetch@1.0.0: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kolorist@1.8.0: {} - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - lilconfig@3.1.3: {} - - lines-and-columns@1.2.4: {} - - linkify-it@5.0.0: - dependencies: - uc.micro: 2.1.0 - - local-pkg@0.4.3: {} - - local-pkg@1.2.1: - dependencies: - mlly: 1.8.2 - pkg-types: 2.3.1 - quansync: 0.2.11 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - - lodash@4.18.1: {} - - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - markdown-it@14.1.1: - dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.0 - mdurl: 2.0.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 - - math-intrinsics@1.1.0: {} - - mdurl@2.0.0: {} - - memorystream@0.3.1: {} - - merge-stream@2.0.0: {} - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.2 - - mimic-fn@2.1.0: {} - - minimatch@3.1.5: - dependencies: - brace-expansion: 1.1.14 - - minimatch@9.0.3: - dependencies: - brace-expansion: 2.1.0 - - minimatch@9.0.9: - dependencies: - brace-expansion: 2.1.0 - - minimist@1.2.8: {} - - mlly@1.8.2: - dependencies: - acorn: 8.16.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.4 - - ms@2.1.3: {} - - muggle-string@0.4.1: {} - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - nanoid@3.3.12: {} - - natural-compare@1.4.0: {} - - node-exports-info@1.6.0: - dependencies: - array.prototype.flatmap: 1.3.3 - es-errors: 1.3.0 - object.entries: 1.1.9 - semver: 6.3.1 - - node-releases@2.0.45: {} - - normalize-path@3.0.0: {} - - npm-normalize-package-bin@3.0.1: {} - - npm-run-all2@6.2.6: - dependencies: - ansi-styles: 6.2.3 - cross-spawn: 7.0.6 - memorystream: 0.3.1 - minimatch: 9.0.9 - pidtree: 0.6.0 - read-package-json-fast: 3.0.2 - shell-quote: 1.8.3 - which: 3.0.1 - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - nth-check@2.1.1: - dependencies: - boolbase: 1.0.0 - - object-assign@4.1.1: {} - - object-hash@3.0.0: {} - - object-inspect@1.13.4: {} - - object-keys@1.1.1: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - object.entries@1.1.9: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - object.fromentries@2.0.8: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-object-atoms: 1.1.1 - - object.groupby@1.0.3: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - - object.values@1.2.1: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - own-keys@1.0.1: - dependencies: - get-intrinsic: 1.3.0 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - package-manager-detector@1.6.0: {} - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - path-browserify@1.0.1: {} - - path-exists@4.0.0: {} - - path-is-absolute@1.0.1: {} - - path-key@3.1.1: {} - - path-parse@1.0.7: {} - - path-type@4.0.0: {} - - pathe@2.0.3: {} - - picocolors@1.1.1: {} - - picomatch@2.3.2: {} - - picomatch@4.0.4: {} - - pidtree@0.6.0: {} - - pify@2.3.0: {} - - pirates@4.0.7: {} - - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.8.2 - pathe: 2.0.3 - - pkg-types@2.3.1: - dependencies: - confbox: 0.2.4 - exsolve: 1.0.8 - pathe: 2.0.3 - - possible-typed-array-names@1.1.0: {} - - postcss-import@15.1.0(postcss@8.5.15): - dependencies: - postcss: 8.5.15 - postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.12 - - postcss-js@4.1.0(postcss@8.5.15): - dependencies: - camelcase-css: 2.0.1 - postcss: 8.5.15 - - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.15)(yaml@2.7.1): - dependencies: - lilconfig: 3.1.3 - optionalDependencies: - jiti: 1.21.7 - postcss: 8.5.15 - yaml: 2.7.1 - - postcss-nested@6.2.0(postcss@8.5.15): - dependencies: - postcss: 8.5.15 - postcss-selector-parser: 6.1.2 - - postcss-selector-parser@6.1.2: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss-value-parser@4.2.0: {} - - postcss@8.5.15: - dependencies: - nanoid: 3.3.12 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - prelude-ls@1.2.1: {} - - punycode.js@2.3.1: {} - - punycode@2.3.1: {} - - quansync@0.2.11: {} - - queue-microtask@1.2.3: {} - - read-cache@1.0.0: - dependencies: - pify: 2.3.0 - - read-package-json-fast@3.0.2: - dependencies: - json-parse-even-better-errors: 3.0.2 - npm-normalize-package-bin: 3.0.1 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.2 - - reflect.getprototypeof@1.0.10: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - which-builtin-type: 1.2.1 - - regexp.prototype.flags@1.5.4: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-errors: 1.3.0 - get-proto: 1.0.1 - gopd: 1.2.0 - set-function-name: 2.0.2 - - resolve-from@4.0.0: {} - - resolve@1.22.12: - dependencies: - es-errors: 1.3.0 - is-core-module: 2.16.2 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - resolve@2.0.0-next.7: - dependencies: - es-errors: 1.3.0 - is-core-module: 2.16.2 - node-exports-info: 1.6.0 - object-keys: 1.1.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - reusify@1.1.0: {} - - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - - rollup@4.60.4: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.4 - '@rollup/rollup-android-arm64': 4.60.4 - '@rollup/rollup-darwin-arm64': 4.60.4 - '@rollup/rollup-darwin-x64': 4.60.4 - '@rollup/rollup-freebsd-arm64': 4.60.4 - '@rollup/rollup-freebsd-x64': 4.60.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 - '@rollup/rollup-linux-arm-musleabihf': 4.60.4 - '@rollup/rollup-linux-arm64-gnu': 4.60.4 - '@rollup/rollup-linux-arm64-musl': 4.60.4 - '@rollup/rollup-linux-loong64-gnu': 4.60.4 - '@rollup/rollup-linux-loong64-musl': 4.60.4 - '@rollup/rollup-linux-ppc64-gnu': 4.60.4 - '@rollup/rollup-linux-ppc64-musl': 4.60.4 - '@rollup/rollup-linux-riscv64-gnu': 4.60.4 - '@rollup/rollup-linux-riscv64-musl': 4.60.4 - '@rollup/rollup-linux-s390x-gnu': 4.60.4 - '@rollup/rollup-linux-x64-gnu': 4.60.4 - '@rollup/rollup-linux-x64-musl': 4.60.4 - '@rollup/rollup-openbsd-x64': 4.60.4 - '@rollup/rollup-openharmony-arm64': 4.60.4 - '@rollup/rollup-win32-arm64-msvc': 4.60.4 - '@rollup/rollup-win32-ia32-msvc': 4.60.4 - '@rollup/rollup-win32-x64-gnu': 4.60.4 - '@rollup/rollup-win32-x64-msvc': 4.60.4 - fsevents: 2.3.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-array-concat@1.1.4: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - isarray: 2.0.5 - - safe-push-apply@1.0.0: - dependencies: - es-errors: 1.3.0 - isarray: 2.0.5 - - safe-regex-test@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-regex: 1.2.1 - - semver@6.3.1: {} - - semver@7.8.0: {} - - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-proto@1.0.0: - dependencies: - dunder-proto: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - shell-quote@1.8.3: {} - - side-channel-list@1.0.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.1 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - signal-exit@3.0.7: {} - - slash@3.0.0: {} - - source-map-js@1.2.1: {} - - stop-iteration-iterator@1.1.0: - dependencies: - es-errors: 1.3.0 - internal-slot: 1.1.0 - - string.prototype.trim@1.2.10: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-object-atoms: 1.1.1 - has-property-descriptors: 1.0.2 - - string.prototype.trimend@1.0.9: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string.prototype.trimstart@1.0.8: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-bom@3.0.0: {} - - strip-final-newline@2.0.0: {} - - strip-json-comments@3.1.1: {} - - sucrase@3.35.1: - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - commander: 4.1.1 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.7 - tinyglobby: 0.2.16 - ts-interface-checker: 0.1.13 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - tailwindcss@3.4.19(yaml@2.7.1): - 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.3 - glob-parent: 6.0.2 - is-glob: 4.0.3 - jiti: 1.21.7 - lilconfig: 3.1.3 - micromatch: 4.0.8 - normalize-path: 3.0.0 - object-hash: 3.0.0 - picocolors: 1.1.1 - postcss: 8.5.15 - postcss-import: 15.1.0(postcss@8.5.15) - postcss-js: 4.1.0(postcss@8.5.15) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.15)(yaml@2.7.1) - postcss-nested: 6.2.0(postcss@8.5.15) - postcss-selector-parser: 6.1.2 - resolve: 1.22.12 - sucrase: 3.35.1 - transitivePeerDependencies: - - tsx - - yaml - - text-table@0.2.0: {} - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - tinyexec@1.1.2: {} - - tinyglobby@0.2.16: - dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - ts-api-utils@1.4.3(typescript@5.4.5): - dependencies: - typescript: 5.4.5 - - ts-interface-checker@0.1.13: {} - - tsconfig-paths@3.15.0: - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-fest@0.20.2: {} - - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - - typed-array-byte-length@1.0.3: - dependencies: - call-bind: 1.0.9 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - - typed-array-byte-offset@1.0.4: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.10 - - typed-array-length@1.0.7: - dependencies: - call-bind: 1.0.9 - for-each: 0.3.5 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.1.0 - reflect.getprototypeof: 1.0.10 - - typescript@5.4.5: {} - - uc.micro@2.1.0: {} - - ufo@1.6.4: {} - - unbox-primitive@1.1.0: - dependencies: - call-bound: 1.0.4 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 - - undici-types@6.21.0: {} - - unplugin-icons@0.16.6(@vue/compiler-sfc@3.5.34): - dependencies: - '@antfu/install-pkg': 0.1.1 - '@antfu/utils': 0.7.10 - '@iconify/utils': 2.3.0 - debug: 4.4.3 - kolorist: 1.8.0 - local-pkg: 0.4.3 - unplugin: 1.16.1 - optionalDependencies: - '@vue/compiler-sfc': 3.5.34 - transitivePeerDependencies: - - supports-color - - unplugin@1.16.1: - dependencies: - acorn: 8.16.0 - webpack-virtual-modules: 0.6.2 - - update-browserslist-db@1.2.3(browserslist@4.28.2): - dependencies: - browserslist: 4.28.2 - escalade: 3.2.0 - picocolors: 1.1.1 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - util-deprecate@1.0.2: {} - - vite-plugin-dynamic-import@1.6.0: - dependencies: - acorn: 8.16.0 - es-module-lexer: 1.7.0 - fast-glob: 3.3.3 - magic-string: 0.30.21 - - vite@5.4.21(@types/node@20.19.41): - dependencies: - esbuild: 0.21.5 - postcss: 8.5.15 - rollup: 4.60.4 - optionalDependencies: - '@types/node': 20.19.41 - fsevents: 2.3.3 - - vscode-uri@3.1.0: {} - - vue-demi@0.14.10(vue@3.5.34(typescript@5.4.5)): - dependencies: - vue: 3.5.34(typescript@5.4.5) - - vue-eslint-parser@9.4.3(eslint@8.57.1): - dependencies: - debug: 4.4.3 - eslint: 8.57.1 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.7.0 - lodash: 4.18.1 - semver: 7.8.0 - transitivePeerDependencies: - - supports-color - - vue-router@4.6.4(vue@3.5.34(typescript@5.4.5)): - dependencies: - '@vue/devtools-api': 6.6.4 - vue: 3.5.34(typescript@5.4.5) - - vue-tsc@2.2.12(typescript@5.4.5): - dependencies: - '@volar/typescript': 2.4.15 - '@vue/language-core': 2.2.12(typescript@5.4.5) - typescript: 5.4.5 - - vue@3.5.34(typescript@5.4.5): - dependencies: - '@vue/compiler-dom': 3.5.34 - '@vue/compiler-sfc': 3.5.34 - '@vue/runtime-dom': 3.5.34 - '@vue/server-renderer': 3.5.34(vue@3.5.34(typescript@5.4.5)) - '@vue/shared': 3.5.34 - optionalDependencies: - typescript: 5.4.5 - - webpack-virtual-modules@0.6.2: {} - - which-boxed-primitive@1.1.1: - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.2 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 - - which-builtin-type@1.2.1: - dependencies: - call-bound: 1.0.4 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.1.1 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.2 - is-regex: 1.2.1 - is-weakref: 1.1.1 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.20 - - which-collection@1.0.2: - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 - - which-typed-array@1.1.20: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - which@3.0.1: - dependencies: - isexe: 2.0.0 - - word-wrap@1.2.5: {} - - wrappy@1.0.2: {} - - xml-name-validator@4.0.0: {} - - yaml@2.7.1: - optional: true - - yocto-queue@0.1.0: {} diff --git a/frontend/dev-mode/postcss.config.js b/frontend/dev-mode/postcss.config.js deleted file mode 100644 index 1d7d3e447..000000000 --- a/frontend/dev-mode/postcss.config.js +++ /dev/null @@ -1,7 +0,0 @@ -export default { - plugins: { - 'tailwindcss/nesting': {}, - tailwindcss: {}, - autoprefixer: {}, - }, -} diff --git a/frontend/dev-mode/public/css/fonts.css b/frontend/dev-mode/public/css/fonts.css deleted file mode 100644 index dc35d91b7..000000000 --- a/frontend/dev-mode/public/css/fonts.css +++ /dev/null @@ -1,31 +0,0 @@ -@font-face { - font-family: 'Atkinson Hyperlegible'; - font-weight: 400; - font-style: normal; - font-display: swap; - src: local('Rubik'), url(/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Regular.ttf) format('truetype'); -} - -@font-face { - font-family: 'Atkinson Hyperlegible'; - font-weight: 400; - font-style: italic; - font-display: swap; - src: local('Rubik'), url(/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Italic.ttf) format('truetype'); -} - -@font-face { - font-family: 'Atkinson Hyperlegible'; - font-weight: 700; - font-style: normal; - font-display: swap; - src: local('Rubik'), url(/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Bold.ttf) format('truetype'); -} - -@font-face { - font-family: 'Atkinson Hyperlegible'; - font-weight: 700; - font-style: italic; - font-display: swap; - src: local('Rubik'), url(/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-BoldItalic.ttf) format('truetype'); -} \ No newline at end of file diff --git a/frontend/dev-mode/public/favicon.ico b/frontend/dev-mode/public/favicon.ico deleted file mode 100644 index 3e7ef0403..000000000 Binary files a/frontend/dev-mode/public/favicon.ico and /dev/null differ diff --git a/frontend/dev-mode/public/favicons/android-chrome-192x192.png b/frontend/dev-mode/public/favicons/android-chrome-192x192.png deleted file mode 100644 index 523f27640..000000000 Binary files a/frontend/dev-mode/public/favicons/android-chrome-192x192.png and /dev/null differ diff --git a/frontend/dev-mode/public/favicons/android-chrome-512x512.png b/frontend/dev-mode/public/favicons/android-chrome-512x512.png deleted file mode 100644 index 29df150f2..000000000 Binary files a/frontend/dev-mode/public/favicons/android-chrome-512x512.png and /dev/null differ diff --git a/frontend/dev-mode/public/favicons/apple-touch-icon.png b/frontend/dev-mode/public/favicons/apple-touch-icon.png deleted file mode 100644 index 95d88a2ff..000000000 Binary files a/frontend/dev-mode/public/favicons/apple-touch-icon.png and /dev/null differ diff --git a/frontend/dev-mode/public/favicons/browserconfig.xml b/frontend/dev-mode/public/favicons/browserconfig.xml deleted file mode 100644 index b9639caf4..000000000 --- a/frontend/dev-mode/public/favicons/browserconfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - #000000 - - - diff --git a/frontend/dev-mode/public/favicons/favicon-16x16.png b/frontend/dev-mode/public/favicons/favicon-16x16.png deleted file mode 100644 index 51820c025..000000000 Binary files a/frontend/dev-mode/public/favicons/favicon-16x16.png and /dev/null differ diff --git a/frontend/dev-mode/public/favicons/favicon-32x32.png b/frontend/dev-mode/public/favicons/favicon-32x32.png deleted file mode 100644 index a23543e2e..000000000 Binary files a/frontend/dev-mode/public/favicons/favicon-32x32.png and /dev/null differ diff --git a/frontend/dev-mode/public/favicons/favicon.ico b/frontend/dev-mode/public/favicons/favicon.ico deleted file mode 100644 index 3e7ef0403..000000000 Binary files a/frontend/dev-mode/public/favicons/favicon.ico and /dev/null differ diff --git a/frontend/dev-mode/public/favicons/mstile-150x150.png b/frontend/dev-mode/public/favicons/mstile-150x150.png deleted file mode 100644 index 0c5961303..000000000 Binary files a/frontend/dev-mode/public/favicons/mstile-150x150.png and /dev/null differ diff --git a/frontend/dev-mode/public/favicons/safari-pinned-tab.svg b/frontend/dev-mode/public/favicons/safari-pinned-tab.svg deleted file mode 100644 index d53c2ff51..000000000 --- a/frontend/dev-mode/public/favicons/safari-pinned-tab.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - -Created by potrace 1.14, written by Peter Selinger 2001-2017 - - - - - - diff --git a/frontend/dev-mode/public/favicons/site.webmanifest b/frontend/dev-mode/public/favicons/site.webmanifest deleted file mode 100644 index 9eab6b7fa..000000000 --- a/frontend/dev-mode/public/favicons/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "", - "short_name": "", - "icons": [ - { - "src": "/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#000000", - "background_color": "#000000", - "display": "standalone" -} diff --git a/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Bold.ttf b/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Bold.ttf deleted file mode 100644 index c72b4889f..000000000 Binary files a/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Bold.ttf and /dev/null differ diff --git a/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-BoldItalic.ttf b/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-BoldItalic.ttf deleted file mode 100644 index ff966b11c..000000000 Binary files a/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-BoldItalic.ttf and /dev/null differ diff --git a/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Italic.ttf b/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Italic.ttf deleted file mode 100644 index 1cf113a08..000000000 Binary files a/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Italic.ttf and /dev/null differ diff --git a/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Regular.ttf b/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Regular.ttf deleted file mode 100644 index 23614a4d3..000000000 Binary files a/frontend/dev-mode/public/fonts/atkinson-hyperlegible/AtkinsonHyperlegible-Regular.ttf and /dev/null differ diff --git a/frontend/dev-mode/public/fonts/atkinson-hyperlegible/OFL.txt b/frontend/dev-mode/public/fonts/atkinson-hyperlegible/OFL.txt deleted file mode 100644 index 8a983cae3..000000000 --- a/frontend/dev-mode/public/fonts/atkinson-hyperlegible/OFL.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2020 Braille Institute of America, Inc. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/frontend/dev-mode/src/App.vue b/frontend/dev-mode/src/App.vue deleted file mode 100644 index 467792b2c..000000000 --- a/frontend/dev-mode/src/App.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - diff --git a/frontend/dev-mode/src/assets/main.css b/frontend/dev-mode/src/assets/main.css deleted file mode 100644 index 74b1800d6..000000000 --- a/frontend/dev-mode/src/assets/main.css +++ /dev/null @@ -1,58 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base { - html { - @apply font-sans; - } - - a:hover { - @apply underline; - } -} - -@layer components { - /* For Firefox */ - @-moz-document url-prefix() { - * { - scrollbar-width: auto; - scrollbar-color: #000000 transparent; - } - } - - /* Chrome, Edge and Safari */ - *::-webkit-scrollbar { - height: 10px; - width: 10px; - } - *::-webkit-scrollbar-track { - border-radius: 5px; - background-color: transparent; - } - - *::-webkit-scrollbar-track:hover { - background-color: rgba(0, 0, 0, 0.2); - } - - *::-webkit-scrollbar-track:active { - background-color: rgba(0, 0, 0, 0.2); - } - - *::-webkit-scrollbar-thumb { - border-radius: 5px; - background-color: rgba(0,0,0,0.8); - } - - *::-webkit-scrollbar-thumb:hover { - background-color: #000000; - } - - *::-webkit-scrollbar-thumb:active { - background-color: #000000; - } - - *::-webkit-scrollbar-corner { - background-color: transparent; - } -} \ No newline at end of file diff --git a/frontend/dev-mode/src/components/ChatPrompt.vue b/frontend/dev-mode/src/components/ChatPrompt.vue deleted file mode 100644 index 092e35c75..000000000 --- a/frontend/dev-mode/src/components/ChatPrompt.vue +++ /dev/null @@ -1,242 +0,0 @@ - - - diff --git a/frontend/dev-mode/src/components/InputCodeSnippets.vue b/frontend/dev-mode/src/components/InputCodeSnippets.vue deleted file mode 100644 index 5165d523c..000000000 --- a/frontend/dev-mode/src/components/InputCodeSnippets.vue +++ /dev/null @@ -1,173 +0,0 @@ - - - diff --git a/frontend/dev-mode/src/components/LoadingState.vue b/frontend/dev-mode/src/components/LoadingState.vue deleted file mode 100644 index dcdcd5250..000000000 --- a/frontend/dev-mode/src/components/LoadingState.vue +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/frontend/dev-mode/src/components/ParameterTooltip.vue b/frontend/dev-mode/src/components/ParameterTooltip.vue deleted file mode 100644 index 5668678d0..000000000 --- a/frontend/dev-mode/src/components/ParameterTooltip.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/frontend/dev-mode/src/components/PromptView.vue b/frontend/dev-mode/src/components/PromptView.vue deleted file mode 100644 index c831fcc24..000000000 --- a/frontend/dev-mode/src/components/PromptView.vue +++ /dev/null @@ -1,59 +0,0 @@ - - - diff --git a/frontend/dev-mode/src/components/ResponseCode.vue b/frontend/dev-mode/src/components/ResponseCode.vue deleted file mode 100644 index df29f87ad..000000000 --- a/frontend/dev-mode/src/components/ResponseCode.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/frontend/dev-mode/src/components/SettingsModal.vue b/frontend/dev-mode/src/components/SettingsModal.vue deleted file mode 100644 index 3e70a1518..000000000 --- a/frontend/dev-mode/src/components/SettingsModal.vue +++ /dev/null @@ -1,477 +0,0 @@ - - - - - diff --git a/frontend/dev-mode/src/components/StatsValues.vue b/frontend/dev-mode/src/components/StatsValues.vue deleted file mode 100644 index f0dc87044..000000000 --- a/frontend/dev-mode/src/components/StatsValues.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/frontend/dev-mode/src/components/ui/Accordion.vue b/frontend/dev-mode/src/components/ui/Accordion.vue deleted file mode 100644 index 61a4e0717..000000000 --- a/frontend/dev-mode/src/components/ui/Accordion.vue +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - diff --git a/frontend/dev-mode/src/components/ui/Button.vue b/frontend/dev-mode/src/components/ui/Button.vue deleted file mode 100644 index 4923adafd..000000000 --- a/frontend/dev-mode/src/components/ui/Button.vue +++ /dev/null @@ -1,60 +0,0 @@ - - - - - diff --git a/frontend/dev-mode/src/components/ui/Checkbox.vue b/frontend/dev-mode/src/components/ui/Checkbox.vue deleted file mode 100644 index 49b4222e9..000000000 --- a/frontend/dev-mode/src/components/ui/Checkbox.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - - - diff --git a/frontend/dev-mode/src/components/ui/CodeHighlighter.vue b/frontend/dev-mode/src/components/ui/CodeHighlighter.vue deleted file mode 100644 index f1d970b06..000000000 --- a/frontend/dev-mode/src/components/ui/CodeHighlighter.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - diff --git a/frontend/dev-mode/src/components/ui/CopyTextButton.vue b/frontend/dev-mode/src/components/ui/CopyTextButton.vue deleted file mode 100644 index e84f0e963..000000000 --- a/frontend/dev-mode/src/components/ui/CopyTextButton.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/frontend/dev-mode/src/components/ui/Input.vue b/frontend/dev-mode/src/components/ui/Input.vue deleted file mode 100644 index 26c854b26..000000000 --- a/frontend/dev-mode/src/components/ui/Input.vue +++ /dev/null @@ -1,79 +0,0 @@ - - - - - diff --git a/frontend/dev-mode/src/components/ui/MarkdownContent.vue b/frontend/dev-mode/src/components/ui/MarkdownContent.vue deleted file mode 100644 index 9d1457cf9..000000000 --- a/frontend/dev-mode/src/components/ui/MarkdownContent.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - - - diff --git a/frontend/dev-mode/src/components/ui/Radio.vue b/frontend/dev-mode/src/components/ui/Radio.vue deleted file mode 100644 index 1933d823f..000000000 --- a/frontend/dev-mode/src/components/ui/Radio.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - - - diff --git a/frontend/dev-mode/src/components/ui/Slider.vue b/frontend/dev-mode/src/components/ui/Slider.vue deleted file mode 100644 index 776263df4..000000000 --- a/frontend/dev-mode/src/components/ui/Slider.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - - - diff --git a/frontend/dev-mode/src/components/ui/Textarea.vue b/frontend/dev-mode/src/components/ui/Textarea.vue deleted file mode 100644 index 6a3eeed76..000000000 --- a/frontend/dev-mode/src/components/ui/Textarea.vue +++ /dev/null @@ -1,135 +0,0 @@ - - - - - diff --git a/frontend/dev-mode/src/components/ui/Toggle.vue b/frontend/dev-mode/src/components/ui/Toggle.vue deleted file mode 100644 index 6d561e9bc..000000000 --- a/frontend/dev-mode/src/components/ui/Toggle.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - - - diff --git a/frontend/dev-mode/src/components/ui/Tooltip.vue b/frontend/dev-mode/src/components/ui/Tooltip.vue deleted file mode 100644 index cb1a160ff..000000000 --- a/frontend/dev-mode/src/components/ui/Tooltip.vue +++ /dev/null @@ -1,151 +0,0 @@ - - - diff --git a/frontend/dev-mode/src/composables/useLlama.ts b/frontend/dev-mode/src/composables/useLlama.ts deleted file mode 100644 index fe4c6158c..000000000 --- a/frontend/dev-mode/src/composables/useLlama.ts +++ /dev/null @@ -1,294 +0,0 @@ -import { type Ref, computed, ref, type MaybeRef, unref } from 'vue' - -import { llama } from '@/services/completion' - -type Chunk = { - data: any -} - -type LlamaResponseParams = { - id_slot?: string, - slot_id?: number, - stop: string[] -} - -export type TranscriptMessage = { - content: string; -} & LlamaResponseParams - -export type ChatTranscript = [string, TranscriptMessage[]] - -export type CompletionTranscript = [string, string | TranscriptMessage] - -export type Transcript = ChatTranscript[] | CompletionTranscript[] - -export type Session = { - prompt: string, - template: string, - historyTemplate: string, - transcript: Transcript, - type: 'chat' | 'completion', - char: string, - user: string, - image_selected: string, - response: TranscriptMessage[] -} - -export type Parameters = { - n_predict: number, - temperature: number, - repeat_last_n: number, - repeat_penalty: number, - top_k: number, - top_p: number, - min_p: number, - tfs_z: number, - typical_p: number, - presence_penalty: number, - frequency_penalty: number, - mirostat: number, - mirostat_tau: number, - mirostat_eta: number, - grammar: string, - n_probs: number, - min_keep: number, - image_data: Array, - cache_prompt: boolean, - api_key: string, - slot_id?: number, - prop_order?: string, -} - -export type LlamaComposableResponse = { - stats: Ref | null>, - session: Ref, - template: (str: string, extraSettings?: Record) => string, - isGenerating: Ref, - isChatStarted: Ref, - isPending: Ref, - chat: (msg: string) => Promise, - runCompletion: () => void, - stop: (e: Event) => void, - reset: (e: Event) => void, - uploadImage: (e: Event) => void -} - -export const DEFAULT_SESSION: Session = { - // eslint-disable-next-line - prompt: 'This is a conversation between User and Llama, a friendly chatbot. Llama is helpful, kind, honest, good at writing, and never fails to answer any requests immediately and with precision.', - template: '{{prompt}}\n\n{{history}}\n{{char}}:', - historyTemplate: '{{name}}: {{message}}', - transcript: [], - type: 'chat', - char: 'Llama', - user: 'User', - image_selected: '', - response: [] as TranscriptMessage[] -} - -export const DEFAULT_PARAMS_VALUES = { - n_predict: 400, - temperature: 0.7, - repeat_last_n: 256, // 0 = disable penalty, -1 = context size - repeat_penalty: 1.18, // 1.0 = disabled - top_k: 40, // <= 0 to use vocab size - top_p: 0.95, // 1.0 = disabled - min_p: 0.05, // 0 = disabled - tfs_z: 1.0, // 1.0 = disabled - typical_p: 1.0, // 1.0 = disabled - presence_penalty: 0.0, // 0.0 = disabled - frequency_penalty: 0.0, // 0.0 = disabled - mirostat: 0, // 0/1/2 - mirostat_tau: 5, // target entropy - mirostat_eta: 0.1, // learning rate - grammar: '', - n_probs: 0, // no completion_probabilities, - min_keep: 0, // min probs from each sampler, - image_data: [], - cache_prompt: true, - api_key: '', - prop_order: undefined, - slot_id: -1 -} as Parameters - -// eslint-disable-next-line vue/max-len -export default function useLlama(parameters?: MaybeRef, localSession?: Session):LlamaComposableResponse { - const stats = ref(null) - const controller = ref(null) - const params = unref(parameters) - - const session = ref({ - ...DEFAULT_SESSION, - ...localSession - }) - - // currently generating a completion? - const isGenerating = computed(() => Boolean(controller.value)) - - // has the user started a chat? - const isChatStarted = computed(() => session.value.transcript.length > 0) - - // was the request sent and pending for response? - const isPending = ref(false) - - const runLlama = async (prompt: string, llamaResponseParams: LlamaResponseParams, char: string): Promise => { - const currentMessages: TranscriptMessage[] = [] - const history = session.value.transcript - if (controller.value) { - throw new Error('already running') - } - controller.value = new AbortController() - isPending.value = true - - try { - for await (const chunk of llama(prompt, llamaResponseParams, { controller: controller.value })) { - isPending.value = false - const data: any = (chunk as Chunk).data - if (data.stop) { - while ( - currentMessages.length > 0 && - currentMessages[currentMessages.length - 1].content.match(/\n$/) !== null - ) { - currentMessages.pop() - } - session.value.transcript = [...history, [char, currentMessages]] as Transcript - } else { - currentMessages.push(data) - if (params) { - params.slot_id = data.slot_id - } - if (session.value.image_selected && !data.multimodal) { - alert("The server was not compiled for multimodal or the model projector can't be loaded.") - return - } - session.value.transcript = [...history, [char, currentMessages]] as Transcript - } - - if (data.timings) { - stats.value = data - } - } - - session.value.response.push(currentMessages as any) - } catch (e) { - if (!(e instanceof DOMException) || e.name !== 'AbortError') { - console.error(e) - } - } - - controller.value = null - } - - // simple template replace - const template = (str: string, extraSettings?: Record): string => { - let settings = session.value - if (extraSettings) { - settings = { ...settings, ...extraSettings } - } - return String(str) - .replaceAll( - /\{\{(.*?)\}\}/g, (_, key: Exclude) => template(settings[key]) - ) - } - - const chat = async (message: string): Promise => { - if (controller.value) { - console.log('already running...') - return - } - - session.value.transcript = [...session.value.transcript, ['{{user}}', [{ content: message }]]] as Transcript - - let prompt = template(session.value.template, { - message, - history: session.value.transcript.flatMap( - ([name, data]) => - template( - session.value.historyTemplate, - { - name, - message: Array.isArray(data) ? - (data as TranscriptMessage[]).map((msg) => msg.content).join('').replace(/^\s/, '') : - data, - } - ) - ).join('\n'), - }) - - if (session.value.image_selected) { - // eslint-disable-next-line - prompt = `A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions.\nUSER:[img-10]${message}\nASSISTANT:` - } - - await runLlama(prompt, { - ...params, - stop: ['', template('{{char}}:'), template('{{user}}:'), '<|im_end|>'], - }, '{{char}}') - } - - const runCompletion = (): void => { - if (controller.value) { - return - } - - isPending.value = true - const prompt = session.value.prompt - session.value.transcript = [...session.value.transcript, ['', prompt]] as Transcript - - runLlama(prompt, { - ...params, - stop: ['<|im_end|>'], - }, '') - .finally(() => { - session.value.prompt = session.value.transcript.map(([_, data]) => - Array.isArray(data) - ? data.map(msg => msg.content).join('') - : data - ).join('') - session.value.transcript = [['', session.value.prompt]] as Transcript - isPending.value = false - }) - } - - const stop = (e: Event): void => { - e.preventDefault() - isPending.value = false - - if (controller.value) { - controller.value.abort() - controller.value = null - } - } - - const reset = (e: Event): void => { - stop(e) - session.value.transcript = [] - } - - const uploadImage = (): void => { - const selectedFile = (event?.target as HTMLInputElement)?.files?.[0] - - if (selectedFile) { - const reader = new FileReader() - reader.onload = function () { - const image_data = reader.result as string - session.value.image_selected = image_data - } - reader.readAsDataURL(selectedFile) - } - } - - return { - stats, - session, - isGenerating, - isChatStarted, - isPending, - template, - chat, - runCompletion, - stop, - reset, - uploadImage - } -} diff --git a/frontend/dev-mode/src/main.ts b/frontend/dev-mode/src/main.ts deleted file mode 100644 index 0b19501a9..000000000 --- a/frontend/dev-mode/src/main.ts +++ /dev/null @@ -1,12 +0,0 @@ -import './assets/main.css' - -import { createApp } from 'vue' - -import App from './App.vue' -import router from './router' - -const app = createApp(App) - -app.use(router) - -app.mount('#app') diff --git a/frontend/dev-mode/src/router/index.ts b/frontend/dev-mode/src/router/index.ts deleted file mode 100644 index 41f1aa874..000000000 --- a/frontend/dev-mode/src/router/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { createRouter, createWebHistory } from 'vue-router' - -import NotFound from '../views/NotFound.vue' - -const router = createRouter({ - history: createWebHistory(import.meta.env.BASE_URL), - routes: [ - { - path: '/:pathMatch(.*)*', - name: 'NotFound', - component: NotFound - }, - ] -}) - -export default router diff --git a/frontend/dev-mode/src/services/completion.ts b/frontend/dev-mode/src/services/completion.ts deleted file mode 100644 index caae8a274..000000000 --- a/frontend/dev-mode/src/services/completion.ts +++ /dev/null @@ -1,200 +0,0 @@ -// Taken from https://github.com/ggerganov/llama.cpp/blob/master/examples/server/public/completion.js -type ParamDefaults = { - stream: boolean, - n_predict: number, - temperature: number, - stop: string[] -} - -type Params = { - stream?: boolean, - n_predict?: number, - temperature?: number, - stop?: string[], - api_key?: string -} - -type Config = { - controller?: AbortController, - api_url?: string, -} - -type SSEEvent = { - data?: { - content: string, - stop?: boolean, - generation_settings?: any, - }, - error?: string, - timings?: any -} - -type ErrorResponse = { - type: string, - message: string, - code: number -} - -const paramDefaults: ParamDefaults = { - stream: true, - n_predict: 500, - temperature: 0.2, - stop: [''] -} - -export const apiUrl = location.pathname.replace(/\/+$/, '') - -let generation_settings: any = null - -// Get the name of the available models -export async function getModels() { - const promise = await fetch(`${apiUrl}/v1/models`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - } - }) - .then((response) => response.json()) - .then((response) => response.data) - - return promise -} - -// Completes the prompt as a generator. Recommended for most use cases. -// -// Example: -// -// import { llama } from '/completion.js' -// -// const request = llama("Tell me a joke", {n_predict: 800}) -// for await (const chunk of request) { -// document.write(chunk.data.content) -// } -// -export async function* llama(prompt: string, params: Params = {}, config: Config = {}): - AsyncGenerator { - let controller = config.controller - - if (!controller) { - controller = new AbortController() - } - - const completionParams = { ...paramDefaults, ...params, prompt } - const response = await fetch(`${apiUrl}/completion`, { - method: 'POST', - body: JSON.stringify(completionParams), - headers: { - 'Connection': 'keep-alive', - 'Content-Type': 'application/json', - 'Accept': 'text/event-stream', - ...(params.api_key ? { 'Authorization': `Bearer ${params.api_key}` } : {}) - }, - signal: controller.signal, - }) - - const reader = response.body?.getReader() - const decoder = new TextDecoder() - - let content = '' - let leftover = '' // Buffer for partially read lines - - try { - let cont = true - - while (cont) { - if (!reader) { - break - } - - const result = await reader.read() as { - done: boolean, - data: any, - error: string, - value: any - } - - if (result.done) { - break - } - - // Add any leftover data to the current chunk of data - const text = leftover + decoder.decode(result.value) - - // Check if the last character is a line break - const endsWithLineBreak = text.endsWith('\n') - - // Split the text into lines - const lines = text.split('\n') - - // If the text doesn't end with a line break, then the last line is incomplete - // Store it in leftover to be added to the next chunk of data - if (!endsWithLineBreak) { - leftover = lines.pop()! - } else { - leftover = '' // Reset leftover if we have a line break at the end - } - - // Parse all sse events and add them to result - const regex = /^(\S+):\s(.*)$/gm - for (const line of lines) { - const match = regex.exec(line) - if (match) { - result[match[1]] = match[2] - - // since we know this is llama.cpp, let's just decode the json in data - if (result.data) { - result.data = JSON.parse(result.data) - content += result.data.content - - // yield - yield result - - // if we got a stop token from server, we will break here - if (result.data.stop) { - if (result.data.generation_settings) { - generation_settings = result.data.generation_settings - } - cont = false - break - } - } - - if (result.error) { - try { - const error = JSON.parse(result.error) as ErrorResponse - if (error.message.includes('slot unavailable')) { - // Throw an error to be caught by upstream callers - throw new Error('slot unavailable') - } else { - console.error(`llama.cpp error [${error.code} - ${error.type}]: ${error.message}`) - } - } catch (e) { - console.error(`llama.cpp error ${result.error}`) - } - } - } - } - } - } catch (e) { - // @ts-expect-error - if (e.name !== 'AbortError') { - console.error('llama error: ', e) - } - throw e - } - finally { - controller.abort() - } - - return content -} - -// Get the model info from the server. This is useful for getting the context window and so on. -export const llamaModelInfo = async (config: Config = {}): Promise => { - if (!generation_settings) { - const api_url = config.api_url || '' - const props = await fetch(`${api_url}/props`).then(r => r.json()) - generation_settings = props.default_generation_settings - } - return generation_settings -} diff --git a/frontend/dev-mode/src/services/json-schema-to-grammar.js b/frontend/dev-mode/src/services/json-schema-to-grammar.js deleted file mode 100644 index 5285deea8..000000000 --- a/frontend/dev-mode/src/services/json-schema-to-grammar.js +++ /dev/null @@ -1,595 +0,0 @@ -// taken directly from https://github.com/ggerganov/llama.cpp/blob/master/examples/server/public/json-schema-to-grammar.mjs -// WARNING: This file was ported from json_schema_to_grammar.py, please fix bugs / add features there first. -const SPACE_RULE = '" "?' - -function _buildRepetition(itemRule, minItems, maxItems, opts={}) { - const separatorRule = opts.separatorRule ?? '' - const itemRuleIsLiteral = opts.itemRuleIsLiteral ?? false - - if (separatorRule === '') { - if (minItems === 0 && maxItems === 1) { - return `${itemRule}?` - } else if (minItems === 1 && maxItems === undefined) { - return `${itemRule}+` - } - } - - let result = '' - if (minItems > 0) { - if (itemRuleIsLiteral && separatorRule === '') { - result = `"${itemRule.slice(1, -1).repeat(minItems)}"` - } else { - result = Array.from({ length: minItems }, () => itemRule) - .join(separatorRule !== '' ? ` ${separatorRule} ` : ' ') - } - } - - const optRepetitions = (upToN, prefixWithSep=false) => { - const content = separatorRule !== '' && prefixWithSep ? `${separatorRule} ${itemRule}` : itemRule - if (upToN === 0) { - return '' - } else if (upToN === 1) { - return `(${content})?` - } else if (separatorRule !== '' && !prefixWithSep) { - return `(${content} ${optRepetitions(upToN - 1, true)})?` - } else { - return Array.from({ length: upToN }, () => `(${content}`).join(' ').trim() + Array.from({ length: upToN }, () => ')?').join('') - } - } - - if (minItems > 0 && maxItems !== minItems) { - result += ' ' - } - - if (maxItems !== undefined) { - result += optRepetitions(maxItems - minItems, minItems > 0) - } else { - const itemOperator = `(${separatorRule !== '' ? separatorRule + ' ' : ''}${itemRule})` - - if (minItems === 0 && separatorRule !== '') { - result = `(${itemRule} ${itemOperator}*)?` - } else { - result += `${itemOperator}*` - } - } - - return result -} - -class BuiltinRule { - constructor(content, deps) { - this.content = content - this.deps = deps || [] - } -} - -const UP_TO_15_DIGITS = _buildRepetition('[0-9]', 0, 15) - -const PRIMITIVE_RULES = { - boolean : new BuiltinRule('("true" | "false") space', []), - 'decimal-part' : new BuiltinRule('[0-9] ' + UP_TO_15_DIGITS, []), - 'integral-part': new BuiltinRule('[0-9] | [1-9] ' + UP_TO_15_DIGITS, []), - number : new BuiltinRule('("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space', ['integral-part', 'decimal-part']), - integer : new BuiltinRule('("-"? integral-part) space', ['integral-part']), - value : new BuiltinRule('object | array | string | number | boolean | null', ['object', 'array', 'string', 'number', 'boolean', 'null']), - object : new BuiltinRule('"{" space ( string ":" space value ("," space string ":" space value)* )? "}" space', ['string', 'value']), - array : new BuiltinRule('"[" space ( value ("," space value)* )? "]" space', ['value']), - uuid : new BuiltinRule('"\\"" ' + [8, 4, 4, 4, 12].map(n => [...new Array(n)].map(_ => '[0-9a-fA-F]').join('')).join(' "-" ') + ' "\\"" space', []), - char : new BuiltinRule('[^"\\\\] | "\\\\" (["\\\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])', []), - string : new BuiltinRule('"\\"" char* "\\"" space', ['char']), - null : new BuiltinRule('"null" space', []), -} - -// TODO: support "uri", "email" string formats -const STRING_FORMAT_RULES = { - 'date' : new BuiltinRule('[0-9] [0-9] [0-9] [0-9] "-" ( "0" [1-9] | "1" [0-2] ) "-" ( \"0\" [1-9] | [1-2] [0-9] | "3" [0-1] )', []), - 'time' : new BuiltinRule('([01] [0-9] | "2" [0-3]) ":" [0-5] [0-9] ":" [0-5] [0-9] ( "." [0-9] [0-9] [0-9] )? ( "Z" | ( "+" | "-" ) ( [01] [0-9] | "2" [0-3] ) ":" [0-5] [0-9] )', []), - 'date-time' : new BuiltinRule('date "T" time', ['date', 'time']), - 'date-string' : new BuiltinRule('"\\"" date "\\"" space', ['date']), - 'time-string' : new BuiltinRule('"\\"" time "\\"" space', ['time']), - 'date-time-string': new BuiltinRule('"\\"" date-time "\\"" space', ['date-time']), -} - -const RESERVED_NAMES = {'root': true, ...PRIMITIVE_RULES, ...STRING_FORMAT_RULES} - -const INVALID_RULE_CHARS_RE = /[^\dA-Za-z-]+/g -const GRAMMAR_LITERAL_ESCAPE_RE = /[\n\r"]/g -const GRAMMAR_RANGE_LITERAL_ESCAPE_RE = /[\n\r"\]\-\\]/g -const GRAMMAR_LITERAL_ESCAPES = { '\r': '\\r', '\n': '\\n', '"': '\\"', '-': '\\-', ']': '\\]' } - -const NON_LITERAL_SET = new Set('|.()[]{}*+?') -const ESCAPED_IN_REGEXPS_BUT_NOT_IN_LITERALS = new Set('[]()|{}*+?') - -export class SchemaConverter { - constructor(options) { - this._propOrder = options.prop_order || {} - this._allowFetch = options.allow_fetch || false - this._dotall = options.dotall || false - this._rules = {'space': SPACE_RULE} - this._refs = {} - this._refsBeingResolved = new Set() - } - - _formatLiteral(literal) { - const escaped = literal.replace( - GRAMMAR_LITERAL_ESCAPE_RE, - m => GRAMMAR_LITERAL_ESCAPES[m] - ) - return `"${escaped}"` - } - - _formatRangeChar(literal) { - return JSON.stringify(literal).slice(1, -1).replace( - GRAMMAR_RANGE_LITERAL_ESCAPE_RE, - m => GRAMMAR_LITERAL_ESCAPES[m] - ) - } - - _addRule(name, rule) { - let escName = name.replace(INVALID_RULE_CHARS_RE, '-') - let key = escName - - if (escName in this._rules) { - if (this._rules[escName] === rule) { - return key - } - - let i = 0 - while ((`${escName}${i}` in this._rules) && (this._rules[`${escName}${i}`] !== rule)) { - i += 1 - } - key = `${escName}${i}` - } - - this._rules[key] = rule - return key - } - - async resolveRefs(schema, url) { - const visit = async (n) => { - if (Array.isArray(n)) { - return Promise.all(n.map(visit)) - } else if (typeof n === 'object' && n !== null) { - let ref = n.$ref - let target - if (ref !== undefined && !this._refs[ref]) { - if (ref.startsWith('https://')) { - if (!this._allowFetch) { - throw new Error('Fetching remote schemas is not allowed (use --allow-fetch for force)') - } - const fetch = (await import('node-fetch')).default - - const fragSplit = ref.split('#') - const baseUrl = fragSplit[0] - - target = this._refs[baseUrl] - if (!target) { - target = await this.resolveRefs(await fetch(ref).then(res => res.json()), baseUrl) - this._refs[baseUrl] = target - } - - if (fragSplit.length === 1 || fragSplit[fragSplit.length - 1] === '') { - return target - } - } else if (ref.startsWith('#/')) { - target = schema - ref = `${url}${ref}` - n.$ref = ref - } else { - throw new Error(`Unsupported ref ${ref}`) - } - - const selectors = ref.split('#')[1].split('/').slice(1) - for (const sel of selectors) { - if (!target || !(sel in target)) { - throw new Error(`Error resolving ref ${ref}: ${sel} not in ${JSON.stringify(target)}`) - } - target = target[sel] - } - - this._refs[ref] = target - } else { - await Promise.all(Object.values(n).map(visit)) - } - } - - return n - } - - return visit(schema) - } - - _generateUnionRule(name, altSchemas) { - return altSchemas - .map((altSchema, i) => this.visit(altSchema, `${name ?? ''}${name ? '-' : 'alternative-'}${i}`)) - .join(' | ') - } - - _visitPattern(pattern, name) { - if (!pattern.startsWith('^') || !pattern.endsWith('$')) { - throw new Error('Pattern must start with "^" and end with "$"') - } - pattern = pattern.slice(1, -1) - const subRuleIds = {} - - let i = 0 - const length = pattern.length - - const getDot = () => { - let rule - if (this._dotall) { - rule = '[\\U00000000-\\U0010FFFF]' - } else { - // Accept any character... except \n and \r line break chars (\x0A and \xOD) - rule = '[^\\x0A\\x0D]' - } - return this._addRule('dot', rule) - } - - - const toRule = ([s, isLiteral]) => isLiteral ? '"' + s + '"' : s - - const transform = () => { - const start = i - // For each component of this sequence, store its string representation and whether it's a literal. - // We only need a flat structure here to apply repetition operators to the last item, and - // to merge literals at the and (we're parsing grouped ( sequences ) recursively and don't treat '|' specially - // (GBNF's syntax is luckily very close to regular expressions!) - const seq = [] - - const joinSeq = () => { - const ret = [] - for (const [isLiteral, g] of groupBy(seq, x => x[1])) { - if (isLiteral) { - ret.push([[...g].map(x => x[0]).join(''), true]) - } else { - ret.push(...g) - } - } - if (ret.length === 1) { - return ret[0] - } - return [ret.map(x => toRule(x)).join(' '), false] - } - - while (i < length) { - const c = pattern[i] - if (c === '.') { - seq.push([getDot(), false]) - i += 1 - } else if (c === '(') { - i += 1 - if (i < length) { - if (pattern[i] === '?') { - throw new Error(`Unsupported pattern syntax "${pattern[i]}" at index ${i} of /${pattern}/`) - } - } - seq.push([`(${toRule(transform())})`, false]) - } else if (c === ')') { - i += 1 - if (start <= 0 || pattern[start - 1] !== '(') { - throw new Error(`Unbalanced parentheses; start = ${start}, i = ${i}, pattern = ${pattern}`) - } - return joinSeq() - } else if (c === '[') { - let squareBrackets = c - i += 1 - while (i < length && pattern[i] !== ']') { - if (pattern[i] === '\\') { - squareBrackets += pattern.slice(i, i + 2) - i += 2 - } else { - squareBrackets += pattern[i] - i += 1 - } - } - if (i >= length) { - throw new Error(`Unbalanced square brackets; start = ${start}, i = ${i}, pattern = ${pattern}`) - } - squareBrackets += ']' - i += 1 - seq.push([squareBrackets, false]) - } else if (c === '|') { - seq.push(['|', false]) - i += 1 - } else if (c === '*' || c === '+' || c === '?') { - seq[seq.length - 1] = [toRule(seq[seq.length - 1]) + c, false] - i += 1 - } else if (c === '{') { - let curlyBrackets = c - i += 1 - while (i < length && pattern[i] !== '}') { - curlyBrackets += pattern[i] - i += 1 - } - if (i >= length) { - throw new Error(`Unbalanced curly brackets; start = ${start}, i = ${i}, pattern = ${pattern}`) - } - curlyBrackets += '}' - i += 1 - const nums = curlyBrackets.slice(1, -1).split(',').map(s => s.trim()) - let minTimes, maxTimes - if (nums.length === 1) { - minTimes = parseInt(nums[0], 10) - maxTimes = minTimes - } else { - if (nums.length !== 2) { - throw new Error(`Invalid quantifier ${curlyBrackets}`) - } - minTimes = nums[0] ? parseInt(nums[0], 10) : 0 - maxTimes = nums[1] ? parseInt(nums[1], 10) : Infinity - } - - let [sub, subIsLiteral] = seq[seq.length - 1] - - if (!subIsLiteral) { - let id = subRuleIds[sub] - if (id === undefined) { - id = this._addRule(`${name}-${Object.keys(subRuleIds).length + 1}`, sub) - subRuleIds[sub] = id - } - sub = id - } - - seq[seq.length - 1] = [ - _buildRepetition(subIsLiteral ? `"${sub}"` : sub, minTimes, maxTimes, {itemRuleIsLiteral: subIsLiteral}), - false - ] - } else { - let literal = '' - while (i < length) { - if (pattern[i] === '\\' && i < length - 1) { - const next = pattern[i + 1] - if (ESCAPED_IN_REGEXPS_BUT_NOT_IN_LITERALS.has(next)) { - i += 1 - literal += pattern[i] - i += 1 - } else { - literal += pattern.slice(i, i + 2) - i += 2 - } - } else if (pattern[i] === '"') { - literal += '\\"' - i += 1 - } else if (!NON_LITERAL_SET.has(pattern[i]) && - (i === length - 1 || literal === '' || pattern[i + 1] === '.' || !NON_LITERAL_SET.has(pattern[i+1]))) { - literal += pattern[i] - i += 1 - } else { - break - } - } - if (literal !== '') { - seq.push([literal, true]) - } - } - } - - return joinSeq() - } - - return this._addRule(name, '"\\"" ' + toRule(transform()) + ' "\\"" space') - } - - _resolveRef(ref) { - let refName = ref.split('/').pop() - if (!(refName in this._rules) && !this._refsBeingResolved.has(ref)) { - this._refsBeingResolved.add(ref) - const resolved = this._refs[ref] - refName = this.visit(resolved, refName) - this._refsBeingResolved.delete(ref) - } - return refName - } - - _generateConstantRule(value) { - return this._formatLiteral(JSON.stringify(value)) - } - - visit(schema, name) { - const schemaType = schema.type - const schemaFormat = schema.format - const ruleName = name in RESERVED_NAMES ? name + '-' : name == '' ? 'root' : name - - const ref = schema.$ref - if (ref !== undefined) { - return this._addRule(ruleName, this._resolveRef(ref)) - } else if (schema.oneOf || schema.anyOf) { - return this._addRule(ruleName, this._generateUnionRule(name, schema.oneOf || schema.anyOf)) - } else if (Array.isArray(schemaType)) { - return this._addRule(ruleName, this._generateUnionRule(name, schemaType.map(t => ({ type: t })))) - } else if ('const' in schema) { - return this._addRule(ruleName, this._generateConstantRule(schema.const)) - } else if ('enum' in schema) { - const rule = schema.enum.map(v => this._generateConstantRule(v)).join(' | ') - return this._addRule(ruleName, rule) - } else if ((schemaType === undefined || schemaType === 'object') && - ('properties' in schema || - ('additionalProperties' in schema && schema.additionalProperties !== true))) { - const required = new Set(schema.required || []) - const properties = Object.entries(schema.properties ?? {}) - return this._addRule(ruleName, this._buildObjectRule(properties, required, name, schema.additionalProperties)) - } else if ((schemaType === undefined || schemaType === 'object') && 'allOf' in schema) { - const required = new Set() - const properties = [] - const addComponent = (compSchema, isRequired) => { - const ref = compSchema.$ref - if (ref !== undefined) { - compSchema = this._refs[ref] - } - - if ('properties' in compSchema) { - for (const [propName, propSchema] of Object.entries(compSchema.properties)) { - properties.push([propName, propSchema]) - if (isRequired) { - required.add(propName) - } - } - } - } - - for (const t of schema.allOf) { - if ('anyOf' in t) { - for (const tt of t.anyOf) { - addComponent(tt, false) - } - } else { - addComponent(t, true) - } - } - - return this._addRule(ruleName, this._buildObjectRule(properties, required, name, /* additionalProperties= */ false)) - } else if ((schemaType === undefined || schemaType === 'array') && ('items' in schema || 'prefixItems' in schema)) { - const items = schema.items ?? schema.prefixItems - if (Array.isArray(items)) { - return this._addRule( - ruleName, - '"[" space ' + - items.map((item, i) => this.visit(item, `${name ?? ''}${name ? '-' : ''}tuple-${i}`)).join(' "," space ') + - ' "]" space' - ) - } else { - const itemRuleName = this.visit(items, `${name ?? ''}${name ? '-' : ''}item`) - const minItems = schema.minItems || 0 - const maxItems = schema.maxItems - return this._addRule(ruleName, '"[" space ' + _buildRepetition(itemRuleName, minItems, maxItems, {separatorRule: '"," space'}) + ' "]" space') - } - } else if ((schemaType === undefined || schemaType === 'string') && 'pattern' in schema) { - return this._visitPattern(schema.pattern, ruleName) - } else if ((schemaType === undefined || schemaType === 'string') && /^uuid[1-5]?$/.test(schema.format || '')) { - return this._addPrimitive( - ruleName === 'root' ? 'root' : schemaFormat, - PRIMITIVE_RULES['uuid'] - ) - } else if ((schemaType === undefined || schemaType === 'string') && `${schema.format}-string` in STRING_FORMAT_RULES) { - const primName = `${schema.format}-string` - return this._addRule(ruleName, this._addPrimitive(primName, STRING_FORMAT_RULES[primName])) - } else if (schemaType === 'string' && ('minLength' in schema || 'maxLength' in schema)) { - const charRuleName = this._addPrimitive('char', PRIMITIVE_RULES['char']) - const minLen = schema.minLength || 0 - const maxLen = schema.maxLength - return this._addRule(ruleName, '"\\\"" ' + _buildRepetition(charRuleName, minLen, maxLen) + ' "\\\"" space') - } else if ((schemaType === 'object') || (Object.keys(schema).length === 0)) { - return this._addRule(ruleName, this._addPrimitive('object', PRIMITIVE_RULES['object'])) - } else { - if (!(schemaType in PRIMITIVE_RULES)) { - throw new Error(`Unrecognized schema: ${JSON.stringify(schema)}`) - } - // TODO: support minimum, maximum, exclusiveMinimum, exclusiveMaximum at least for zero - return this._addPrimitive(ruleName === 'root' ? 'root' : schemaType, PRIMITIVE_RULES[schemaType]) - } - } - - _addPrimitive(name, rule) { - let n = this._addRule(name, rule.content) - for (const dep of rule.deps) { - const depRule = PRIMITIVE_RULES[dep] || STRING_FORMAT_RULES[dep] - if (!depRule) { - throw new Error(`Rule ${dep} not known`) - } - if (!(dep in this._rules)) { - this._addPrimitive(dep, depRule) - } - } - return n - } - - _buildObjectRule(properties, required, name, additionalProperties) { - const propOrder = this._propOrder - // sort by position in prop_order (if specified) then by original order - const sortedProps = properties.map(([k]) => k).sort((a, b) => { - const orderA = propOrder[a] || Infinity - const orderB = propOrder[b] || Infinity - return orderA - orderB || properties.findIndex(([k]) => k === a) - properties.findIndex(([k]) => k === b) - }) - - const propKvRuleNames = {} - for (const [propName, propSchema] of properties) { - const propRuleName = this.visit(propSchema, `${name ?? ''}${name ? '-' : ''}${propName}`) - propKvRuleNames[propName] = this._addRule( - `${name ?? ''}${name ? '-' : ''}${propName}-kv`, - `${this._formatLiteral(JSON.stringify(propName))} space ":" space ${propRuleName}` - ) - } - const requiredProps = sortedProps.filter(k => required.has(k)) - const optionalProps = sortedProps.filter(k => !required.has(k)) - - if (typeof additionalProperties === 'object' || additionalProperties === true) { - const subName = `${name ?? ''}${name ? '-' : ''}additional` - const valueRule = this.visit(additionalProperties === true ? {} : additionalProperties, `${subName}-value`) - propKvRuleNames['*'] = this._addRule( - `${subName}-kv`, - `${this._addPrimitive('string', PRIMITIVE_RULES['string'])} ":" space ${valueRule}`) - optionalProps.push('*') - } - - let rule = '"{" space ' - rule += requiredProps.map(k => propKvRuleNames[k]).join(' "," space ') - - if (optionalProps.length > 0) { - rule += ' (' - if (requiredProps.length > 0) { - rule += ' "," space ( ' - } - - const getRecursiveRefs = (ks, firstIsOptional) => { - const [k, ...rest] = ks - const kvRuleName = propKvRuleNames[k] - let res - if (k === '*') { - res = this._addRule( - `${name ?? ''}${name ? '-' : ''}additional-kvs`, - `${kvRuleName} ( "," space ` + kvRuleName + ' )*' - ) - } else if (firstIsOptional) { - res = `( "," space ${kvRuleName} )?` - } else { - res = kvRuleName - } - if (rest.length > 0) { - res += ' ' + this._addRule( - `${name ?? ''}${name ? '-' : ''}${k}-rest`, - getRecursiveRefs(rest, true) - ) - } - return res - } - - rule += optionalProps.map((_, i) => getRecursiveRefs(optionalProps.slice(i), false)).join(' | ') - if (requiredProps.length > 0) { - rule += ' )' - } - rule += ' )?' - } - - rule += ' "}" space' - - return rule - } - - formatGrammar() { - let grammar = '' - for (const [name, rule] of Object.entries(this._rules).sort(([a], [b]) => a.localeCompare(b))) { - grammar += `${name} ::= ${rule}\n` - } - return grammar - } -} - -// Helper function to group elements by a key function -function* groupBy(iterable, keyFn) { - let lastKey = null - let group = [] - for (const element of iterable) { - const key = keyFn(element) - if (lastKey !== null && key !== lastKey) { - yield [lastKey, group] - group = [] - } - group.push(element) - lastKey = key - } - if (group.length > 0) { - yield [lastKey, group] - } -} diff --git a/frontend/dev-mode/src/views/NotFound.vue b/frontend/dev-mode/src/views/NotFound.vue deleted file mode 100644 index f61a41406..000000000 --- a/frontend/dev-mode/src/views/NotFound.vue +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/frontend/dev-mode/tailwind.config.ts b/frontend/dev-mode/tailwind.config.ts deleted file mode 100644 index 2eabd9257..000000000 --- a/frontend/dev-mode/tailwind.config.ts +++ /dev/null @@ -1,73 +0,0 @@ -import type { Config } from 'tailwindcss' -import baseColors from 'tailwindcss/colors' -import plugin from 'tailwindcss/plugin' - -// From https://github.com/tailwindlabs/tailwindcss/issues/4690#issuecomment-1046087220 -delete (baseColors as Record).lightBlue -delete (baseColors as Record).warmGray -delete (baseColors as Record).trueGray -delete (baseColors as Record).coolGray -delete (baseColors as Record).blueGray - -/** @type {Config} */ -export default { - content: [ - './index.html', - './src/**/*.{vue,js,ts}' - ], - - theme: { - extend: { - fontFamily: { - sans: ['Atkinson Hyperlegible'] - }, - colors: { - 'off-white': '#ECECEC', - night: '#121212', - gold: '#FFAF52', - cornflower: '#7A8CFF', - gray: { - '01': '#2D2D2D', - '02': '#4D4D4D', - '03': '#585858', - '04': '#606060', - '05': '#6A6A6A', - '06': '#AAAAAA', - '07': '#E0E0E0', - '08': '#E8E8E8', - '09': '#F0F0F0', - '10': '#F5F5F5' - }, - elevation: { - '0': 'rgb(18, 18, 18)', - '01': '#1F1F1F', - '02': '#292929', - '03': '#333333', - '04': '#3D3D3D', - '05': '#464646' - }, - }, - zIndex: { - // @ts-ignore - '1': 1 - }, - spacing: { - '22': '5.5rem' - } - }, - }, - - plugins: [ - // hocus variant = hover OR focus - plugin(function({ addVariant }) { - addVariant('hocus', ['&:hover', '&:focus']) - }), - - // xs: media breakpoint for mobiles from 0 to `screens.sm` - plugin(function ({ addVariant }) { - addVariant('xs', "@media screen and (max-width: theme('screens.sm'))") - }), - ], - -} satisfies Config - diff --git a/frontend/dev-mode/tsconfig.app.json b/frontend/dev-mode/tsconfig.app.json deleted file mode 100644 index 17e0689ff..000000000 --- a/frontend/dev-mode/tsconfig.app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "extends": "@vue/tsconfig/tsconfig.dom.json", - "include": [ - "env.d.ts", - "global.d.ts", - "tailwind.config.ts", - "src/**/*", - "src/**/*.vue" - ], - "exclude": ["src/**/__tests__/*"], - "compilerOptions": { - "skipLibCheck": true, - "noImplicitAny": false, - "lib": [ - "ES2023.Array", - "ES2022", - "dom" - ], - "composite": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] - } - } -} diff --git a/frontend/dev-mode/tsconfig.json b/frontend/dev-mode/tsconfig.json deleted file mode 100644 index 66b5e5703..000000000 --- a/frontend/dev-mode/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.app.json" - } - ] -} diff --git a/frontend/dev-mode/tsconfig.node.json b/frontend/dev-mode/tsconfig.node.json deleted file mode 100644 index f09406303..000000000 --- a/frontend/dev-mode/tsconfig.node.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "@tsconfig/node20/tsconfig.json", - "include": [ - "vite.config.*", - "vitest.config.*", - "cypress.config.*", - "nightwatch.conf.*", - "playwright.config.*" - ], - "compilerOptions": { - "composite": true, - "noEmit": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - - "module": "ESNext", - "moduleResolution": "Bundler", - "types": ["node"] - } -} diff --git a/frontend/dev-mode/vite.config.ts b/frontend/dev-mode/vite.config.ts deleted file mode 100644 index 80a251383..000000000 --- a/frontend/dev-mode/vite.config.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { URL, fileURLToPath } from 'node:url' - -import vue from '@vitejs/plugin-vue' -import icons from 'unplugin-icons/vite' -import { defineConfig } from 'vite' -import dynamicImport from 'vite-plugin-dynamic-import' - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [ - vue(), - icons({ autoInstall: true }), - dynamicImport({ - filter(id: string) { - if (id.includes('@speed-highlight/core')) - return true - } - }) - ], - resolve: { - alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)), - 'node-fetch': 'just-use-native-fetch', - } - } -}) diff --git a/pkg/cmd/dev/cmd.go b/pkg/cmd/dev/cmd.go deleted file mode 100644 index 1c611373f..000000000 --- a/pkg/cmd/dev/cmd.go +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -package dev - -import ( - "net" - "strconv" - - "github.com/kitops-ml/kitops/pkg/lib/harness" - "github.com/kitops-ml/kitops/pkg/output" - - "github.com/spf13/cobra" -) - -func DevCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "dev [flags]", - Short: devShortDesc, - Long: devLongDesc, - Example: devExample, - } - cmd.AddCommand(DevStartCommand()) - cmd.AddCommand(DevStopCommand()) - cmd.AddCommand(DevLogsCommand()) - return cmd -} - -func DevStartCommand() *cobra.Command { - opts := &DevStartOptions{} - cmd := &cobra.Command{ - Use: "start [directory|registry/repository[:tag|@digest]] [flags]", - Short: devStartShortDesc, - Long: devStartLongDesc, - Example: devStartExample, - RunE: runStartCommand(opts), - } - cmd.Args = cobra.MaximumNArgs(1) - cmd.Flags().StringVarP(&opts.modelFile, "file", "f", "", "Path to the kitfile") - cmd.Flags().StringVar(&opts.host, "host", "127.0.0.1", "Host for the development server") - cmd.Flags().IntVar(&opts.port, "port", 0, "Port for development server to listen on") - opts.AddNetworkFlags(cmd) - cmd.Flags().SortFlags = false - - return cmd -} - -func DevStopCommand() *cobra.Command { - opts := &DevBaseOptions{} - cmd := &cobra.Command{ - Use: "stop", - Short: devStopShortDesc, - Long: devStopLongDesc, - RunE: runStopCommand(opts), - } - return cmd -} - -func DevLogsCommand() *cobra.Command { - opts := &DevLogsOptions{} - cmd := &cobra.Command{ - Use: "logs", - Short: devLogsShortDesc, - Long: devLogsLongDesc, - RunE: runLogsCommand(opts), - } - cmd.Flags().BoolVarP(&opts.follow, "follow", "f", false, "Stream the log file") - return cmd -} - -func runStartCommand(opts *DevStartOptions) func(cmd *cobra.Command, args []string) error { - return func(cmd *cobra.Command, args []string) error { - if err := opts.complete(cmd.Context(), args); err != nil { - return output.Fatalf("failed to complete options: %s", err) - } - - err := runDev(cmd.Context(), opts) - if err != nil { - return output.Fatalf("Failed to start dev server: %s", err) - } - output.Infof("Development server started at http://%s:%d", opts.host, opts.port) - output.Infof("Use \"kit dev stop\" to stop the development server") - return nil - } -} - -func runStopCommand(opts *DevBaseOptions) func(cmd *cobra.Command, args []string) error { - return func(cmd *cobra.Command, args []string) error { - if err := opts.complete(cmd.Context(), args); err != nil { - return output.Fatalf("failed to complete options: %s", err) - } - - output.Infoln("Stopping development server...") - err := stopDev(cmd.Context(), opts) - if err != nil { - return output.Fatalf("Failed to stop dev server: %s", err) - } - output.Infoln("Development server stopped") - return nil - } -} - -func runLogsCommand(opts *DevLogsOptions) func(cmd *cobra.Command, args []string) error { - return func(cmd *cobra.Command, args []string) error { - if err := opts.complete(cmd.Context(), args); err != nil { - return output.Fatalf("failed to complete options: %s", err) - } - - err := harness.PrintLogs(opts.configHome, cmd.OutOrStdout(), opts.follow) - if err != nil { - return output.Fatalln(err) - } - return nil - } -} - -func findAvailablePort() (int, error) { - l, err := net.Listen("tcp", ":0") - if err != nil { - return 0, err - } - defer l.Close() - _, portStr, err := net.SplitHostPort(l.Addr().String()) - if err != nil { - return 0, err - } - port, err := strconv.Atoi(portStr) - if err != nil { - return 0, err - } - return port, nil -} diff --git a/pkg/cmd/dev/dev.go b/pkg/cmd/dev/dev.go deleted file mode 100644 index d857e1132..000000000 --- a/pkg/cmd/dev/dev.go +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -package dev - -import ( - "context" - "errors" - "fmt" - "io/fs" - "os" - "os/signal" - "path/filepath" - "strings" - "syscall" - - "github.com/kitops-ml/kitops/pkg/artifact" - "github.com/kitops-ml/kitops/pkg/lib/constants" - "github.com/kitops-ml/kitops/pkg/lib/filesystem" - "github.com/kitops-ml/kitops/pkg/lib/filesystem/unpack" - "github.com/kitops-ml/kitops/pkg/lib/harness" - kfutils "github.com/kitops-ml/kitops/pkg/lib/kitfile" - "github.com/kitops-ml/kitops/pkg/output" -) - -func runDev(ctx context.Context, options *DevStartOptions) error { - // Create a context for long-running operations like unpack - signalCtx, stopSignal := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM) - defer stopSignal() - - if options.modelRef != nil { - if err := extractModelKitToCache(signalCtx, options); err != nil { - return fmt.Errorf("failed to extract ModelKit: %w", err) - } - // If a signal was received right after extraction, clean up and stop here - if err := signalCtx.Err(); err != nil { - output.Infof("Interrupted, cleaning up cache...") - if cleanupErr := options.cleanup(); cleanupErr != nil { - output.Debugf("Failed to cleanup cache directory: %v", cleanupErr) - } - return signalCtx.Err() - } - } - - kitfile := &artifact.KitFile{} - - modelfile, err := os.Open(options.modelFile) - if err != nil { - return err - } - defer modelfile.Close() - if err := kitfile.LoadModel(modelfile); err != nil { - return err - } - output.Infof("Loaded Kitfile: %s", options.modelFile) - if artifact.IsModelKitReference(kitfile.Model.Path) { - resolvedKitfile, err := kfutils.ResolveKitfile(ctx, options.configHome, kitfile.Model.Path, kitfile.Model.Path) - if err != nil { - return fmt.Errorf("failed to resolve referenced modelkit %s: %w", kitfile.Model.Path, err) - } - kitfile.Model.Path = resolvedKitfile.Model.Path - kitfile.Model.Parts = append(kitfile.Model.Parts, resolvedKitfile.Model.Parts...) - } - - modelAbsPath, _, err := filesystem.VerifySubpath(options.contextDir, kitfile.Model.Path) - if err != nil { - return err - } - - modelPath, err := findModelFile(modelAbsPath) - if err != nil { - return err - } - - llmHarness := &harness.LLMHarness{} - llmHarness.Host = options.host - llmHarness.Port = options.port - llmHarness.ConfigHome = options.configHome - if err := llmHarness.Init(); err != nil { - return err - } - - if err := llmHarness.Start(modelPath); err != nil { - return err - } - - return nil -} - -func stopDev(_ context.Context, options *DevBaseOptions) error { - - // Don't fail stopDev if harness is not running. - // We still want to clean up any cached contents. - var stopErr error - llmHarness := &harness.LLMHarness{ConfigHome: options.configHome} - if err := llmHarness.Init(); err != nil { - output.Debugf("Harness init failed during stop: %v", err) - stopErr = err - } else if err := llmHarness.Stop(); err != nil { - output.Debugf("Failed to stop dev server: %v", err) - stopErr = err - } - - // Always attempt to clean up cache directory - cacheDir := constants.ExtractedDevModelPath(options.configHome) - cleanupErr := os.RemoveAll(cacheDir) - if cleanupErr == nil { - output.Infof("Cleaned up cache directory") - } else { - output.Debugf("Failed to clean up cache directory: %v", cleanupErr) - } - - // Return errors according to precedence: both -> join; cleanup -> cleanup; stop -> stop; else nil - if cleanupErr != nil && stopErr != nil { - return errors.Join(stopErr, fmt.Errorf("failed to clean up cache directory: %w", cleanupErr)) - } - if cleanupErr != nil { - return fmt.Errorf("failed to clean up cache directory: %w", cleanupErr) - } - if stopErr != nil { - return stopErr - } - return nil -} - -func findModelFile(absPath string) (string, error) { - stat, err := os.Lstat(absPath) - if err != nil { - return "", err - } - if stat.Mode().IsRegular() { - // model path refers to a regular file; assume it's fine to use - return absPath, nil - } else if !stat.IsDir() { - return "", fmt.Errorf("could not find model file in %s: path is not regular file or directory", absPath) - } - - modelPath := "" - if err := filepath.WalkDir(absPath, func(path string, d fs.DirEntry, err error) error { - if err != nil { - return err - } - if strings.HasSuffix(path, ".gguf") && d.Type().IsRegular() { - if modelPath == "" { - modelPath = path - } else { - return fmt.Errorf("multiple model files found: %s and %s", modelPath, path) - } - } - return nil - }); err != nil { - return "", fmt.Errorf("error searching for model file in %s: %w", absPath, err) - } else if modelPath == "" { - return "", fmt.Errorf("could not find model file in %s", absPath) - } - output.Debugf("Found model path in directory %s at %s", absPath, modelPath) - return modelPath, nil -} - -// extractModelKitToCache extracts a ModelKit reference to a cache directory -// using the unpack library with model filter -func extractModelKitToCache(ctx context.Context, options *DevStartOptions) error { - output.Infof("Extracting ModelKit %s to cache directory...", options.modelRef.String()) - - // Use consistent cache directory for extraction - extractDir := constants.ExtractedDevModelPath(options.configHome) - if err := os.MkdirAll(extractDir, 0755); err != nil { - return fmt.Errorf("failed to create cache directory: %w", err) - } - options.contextDir = extractDir - - // Extract the ModelKit using the library directly - libOpts := &unpack.UnpackOptions{ - ModelRef: options.modelRef, - UnpackDir: extractDir, - ConfigHome: options.configHome, - Overwrite: true, // Safe for extraction directory - NetworkOptions: options.NetworkOptions, - } - - // Add model filter - modelFilter, err := kfutils.ParseFilter("model,kitfile") - if err != nil { - return fmt.Errorf("failed to create model filter: %w", err) - } - libOpts.FilterConfs = []kfutils.FilterConf{*modelFilter} - - err = unpack.UnpackModelKit(ctx, libOpts) - if err != nil { - cleanUpErr := os.RemoveAll(extractDir) - if cleanUpErr != nil { - return errors.Join( - fmt.Errorf("failed to extract ModelKit: %w", err), - fmt.Errorf("failed to cleanup cache directory: %w", cleanUpErr), - ) - } - return fmt.Errorf("failed to extract ModelKit: %w", err) - } - - kitfilePath, err := filesystem.FindKitfileInPath(extractDir) - if err != nil { - return fmt.Errorf("kitfile not found in extracted ModelKit: %w", err) - } - options.modelFile = kitfilePath - - output.Infof("ModelKit extracted to %s", extractDir) - return nil -} diff --git a/pkg/cmd/dev/dev_test.go b/pkg/cmd/dev/dev_test.go deleted file mode 100644 index b3923e70b..000000000 --- a/pkg/cmd/dev/dev_test.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -package dev - -import ( - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestFindModelFile(t *testing.T) { - tests := []struct { - name string - setupFiles []string - testPath string // If set, test direct file path instead of directory - expectError bool - errorContains string - }{ - { - name: "single gguf file in directory", - setupFiles: []string{"model.gguf"}, - }, - { - name: "gguf file in subdirectory", - setupFiles: []string{"models/llama-7b.gguf", "other-file.txt"}, - }, - { - name: "direct file path", - setupFiles: []string{"direct-model.gguf"}, - testPath: "direct-model.gguf", - }, - { - name: "multiple gguf files", - setupFiles: []string{"model1.gguf", "model2.gguf"}, - expectError: true, - errorContains: "multiple model files found", - }, - { - name: "no gguf files", - setupFiles: []string{"readme.txt", "config.json"}, - expectError: true, - errorContains: "could not find model file", - }, - { - name: "nonexistent path", - setupFiles: []string{}, - testPath: "nonexistent.gguf", - expectError: true, - errorContains: "", // Don't check specific error message (platform dependent) - }, - { - name: "directory without gguf files", - setupFiles: []string{"subdir/readme.txt"}, - testPath: "subdir", - expectError: true, - errorContains: "could not find model file", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "find-model-test-*") - require.NoError(t, err) - defer os.RemoveAll(tmpDir) - - // Setup files - for _, file := range tt.setupFiles { - filePath := filepath.Join(tmpDir, file) - require.NoError(t, os.MkdirAll(filepath.Dir(filePath), 0755)) - require.NoError(t, os.WriteFile(filePath, []byte("test model data"), 0644)) - } - - // Determine test path - var testPath string - if tt.testPath != "" { - if filepath.IsAbs(tt.testPath) { - testPath = tt.testPath - } else { - testPath = filepath.Join(tmpDir, tt.testPath) - } - } else { - testPath = tmpDir - } - - result, err := findModelFile(testPath) - - if tt.expectError { - require.Error(t, err) - if tt.errorContains != "" { - assert.Contains(t, err.Error(), tt.errorContains) - } - return - } - - require.NoError(t, err) - assert.Contains(t, result, ".gguf", "Result should be a .gguf file") - - stat, err := os.Stat(result) - require.NoError(t, err) - assert.True(t, stat.Mode().IsRegular(), "Result should be a regular file") - }) - } -} diff --git a/pkg/cmd/dev/opts.go b/pkg/cmd/dev/opts.go deleted file mode 100644 index 264502e0c..000000000 --- a/pkg/cmd/dev/opts.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -package dev - -import ( - "context" - "fmt" - "os" - - "oras.land/oras-go/v2/registry" - - "github.com/kitops-ml/kitops/pkg/artifact" - "github.com/kitops-ml/kitops/pkg/cmd/options" - "github.com/kitops-ml/kitops/pkg/lib/constants" - "github.com/kitops-ml/kitops/pkg/lib/filesystem" - "github.com/kitops-ml/kitops/pkg/output" -) - -type DevBaseOptions struct { - configHome string -} - -type DevLogsOptions struct { - DevBaseOptions - follow bool -} - -func (opts *DevBaseOptions) complete(ctx context.Context, _ []string) error { - configHome, ok := ctx.Value(constants.ConfigKey{}).(string) - if !ok { - return fmt.Errorf("default config path not set on command context") - } - opts.configHome = configHome - return nil -} - -type DevStartOptions struct { - DevBaseOptions - options.NetworkOptions - host string - port int - modelFile string - contextDir string - modelRef *registry.Reference // For ModelKit references -} - -func (opts *DevStartOptions) complete(ctx context.Context, args []string) error { - if err := opts.DevBaseOptions.complete(ctx, args); err != nil { - return err - } - - // Default: use current directory - opts.contextDir = "" - - if len(args) == 1 { - // Check if the argument is a ModelKit reference - if ref, _, err := artifact.ParseReference(args[0]); err == nil && ref.Reference != "" { - // This looks like a ModelKit reference - opts.modelRef = ref - output.Debugf("Detected ModelKit reference: %s", ref.String()) - } else { - // This is a directory path - opts.contextDir = args[0] - output.Debugf("Using directory path: %s", args[0]) - } - } - - // If we have a ModelKit reference we'll extract to cache and then use that as contextDir - // but check for conflicts here - if opts.modelRef != nil && opts.modelFile != "" { - return fmt.Errorf("cannot specify both a ModelKit reference and a --file flag") - } - - // Using a directory, find Kitfile unless --file is provided - if opts.modelRef == nil && opts.modelFile == "" { - foundKitfile, err := filesystem.FindKitfileInPath(opts.contextDir) - if err != nil { - return fmt.Errorf( - "no Kitfile found in directory '%s'.\n"+ - "Please ensure the directory contains a Kitfile, or specify a ModelKit reference or --file flag.\n"+ - "Error: %w", - opts.contextDir, err, - ) - } - opts.modelFile = foundKitfile - } - - if opts.host == "" { - opts.host = "127.0.0.1" - } - - if opts.port == 0 { - availPort, err := findAvailablePort() - if err != nil { - return fmt.Errorf("failed to find an available port: %w", err) - } - opts.port = availPort - } - - // Complete network options for remote access - if err := opts.NetworkOptions.Complete(ctx, args); err != nil { - return err - } - - return nil -} - -func (opts *DevStartOptions) cleanup() error { - // Only clean up if we extracted a ModelKit reference to contextDir - if opts.modelRef != nil && opts.contextDir != "" { - return os.RemoveAll(opts.contextDir) - } - return nil -} diff --git a/pkg/cmd/dev/opts_test.go b/pkg/cmd/dev/opts_test.go deleted file mode 100644 index a0f627851..000000000 --- a/pkg/cmd/dev/opts_test.go +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -package dev - -import ( - "context" - "os" - "path/filepath" - "testing" - - "github.com/kitops-ml/kitops/pkg/lib/constants" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "oras.land/oras-go/v2/registry" -) - -func TestDevStartOptions_Complete_ReferenceDetection(t *testing.T) { - tests := []struct { - name string - args []string - setupKitfile bool - expectModelRef bool - expectContextDir bool - }{ - { - name: "directory path treated as reference", - args: []string{"./test-dir"}, - setupKitfile: true, - expectModelRef: false, - }, - { - name: "simple modelkit reference", - args: []string{"myrepo/my-model:latest"}, - expectModelRef: true, - }, - { - name: "registry url reference", - args: []string{"registry.example.com/models/llama:7b"}, - expectModelRef: true, - }, - { - name: "localhost reference", - args: []string{"localhost:5000/model:tag"}, - expectModelRef: true, - }, - { - name: "reference with port and path", - args: []string{"my-registry.com:8080/org/model:v1.0"}, - expectModelRef: true, - }, - { - name: "no arguments defaults to current directory", - args: []string{}, - setupKitfile: true, - expectContextDir: false, // Empty contextDir for current directory - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - // Setup temp directory - tmpDir, err := os.MkdirTemp("", "dev-opts-test-*") - require.NoError(t, err) - defer os.RemoveAll(tmpDir) - - // Change to temp directory for tests - origWd, err := os.Getwd() - require.NoError(t, err) - defer os.Chdir(origWd) - require.NoError(t, os.Chdir(tmpDir)) - - // Setup test directory with kitfile if needed - if tt.setupKitfile { - var testDir string - if len(tt.args) > 0 && tt.args[0] != "" { - testDir = filepath.Join(tmpDir, "test-dir") - require.NoError(t, os.MkdirAll(testDir, 0755)) - } else { - testDir = tmpDir // Current directory test - } - - kitfilePath := filepath.Join(testDir, constants.DefaultKitfileName) - kitfileContent := `manifestVersion: 1.0.0 -package: - name: test-model -model: - path: model.gguf` - require.NoError(t, os.WriteFile(kitfilePath, []byte(kitfileContent), 0644)) - } - - opts := &DevStartOptions{} - configHome := filepath.Join(tmpDir, ".kitops") - - // Create context with config key as expected by the complete method - ctx := context.WithValue(context.Background(), constants.ConfigKey{}, configHome) - - // Initialize NetworkOptions with defaults (as would happen in command setup) - opts.Concurrency = 5 - opts.TLSVerify = true - - // Execute - err = opts.complete(ctx, tt.args) - require.NoError(t, err) - - // Verify detection logic - if tt.expectModelRef { - assert.NotNil(t, opts.modelRef, "Expected modelRef to be set for: %v", tt.args) - assert.Equal(t, "", opts.contextDir, "Expected contextDir to be empty for ModelKit reference") - } - - if tt.expectContextDir { - assert.NotEmpty(t, opts.contextDir, "Expected contextDir to be set for directory path") - assert.Nil(t, opts.modelRef, "Expected modelRef to be nil for directory path") - } - }) - } -} - -func TestDevStartOptions_Complete_ErrorCases(t *testing.T) { - tests := []struct { - name string - args []string - setupKitfile bool - expectErrorContains string - }{ - { - name: "no arguments with no kitfile in current dir", - args: []string{}, - expectErrorContains: "no Kitfile found in directory", - }, - { - name: "empty string argument", - args: []string{""}, - expectErrorContains: "no Kitfile found in directory", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "dev-opts-error-test-*") - require.NoError(t, err) - defer os.RemoveAll(tmpDir) - - // Change to temp directory - origWd, err := os.Getwd() - require.NoError(t, err) - defer os.Chdir(origWd) - require.NoError(t, os.Chdir(tmpDir)) - - opts := &DevStartOptions{} - configHome := filepath.Join(tmpDir, ".kitops") - - // Create context with config key as expected by the complete method - ctx := context.WithValue(context.Background(), constants.ConfigKey{}, configHome) - - // Initialize NetworkOptions with defaults (as would happen in command setup) - opts.Concurrency = 5 - opts.TLSVerify = true - - err = opts.complete(ctx, tt.args) - - if tt.expectErrorContains != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.expectErrorContains) - } else { - // These cases don't error in complete(), they would fail later - require.NoError(t, err) - } - }) - } -} - -func TestDevStartOptions_Cleanup(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "dev-cleanup-test-*") - require.NoError(t, err) - - // Create a test file in the temp directory - testFile := filepath.Join(tmpDir, "test-model.gguf") - require.NoError(t, os.WriteFile(testFile, []byte("test content"), 0644)) - - opts := &DevStartOptions{ - contextDir: tmpDir, - modelRef: ®istry.Reference{}, // Simulate ModelKit reference for cleanup - } - - // Verify directory and file exist - _, err = os.Stat(tmpDir) - require.NoError(t, err) - _, err = os.Stat(testFile) - require.NoError(t, err) - - // Test cleanup - err = opts.cleanup() - assert.NoError(t, err) - - // Verify directory was removed - _, err = os.Stat(tmpDir) - assert.True(t, os.IsNotExist(err)) -} diff --git a/pkg/cmd/dev/usage.go b/pkg/cmd/dev/usage.go deleted file mode 100644 index c7bd8046a..000000000 --- a/pkg/cmd/dev/usage.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -package dev - -const ( - devShortDesc = "Run models locally (experimental)" - devLongDesc = "Start a local server and interact with a model in the browser" - devExample = "kit dev start" - - devStartShortDesc = "Start development server (experimental)" - devStartLongDesc = `Start development server (experimental) from a modelkit - -Start a development server for a modelkit. You can provide either: -- A directory path containing an unpacked modelkit with a Kitfile -- A ModelKit reference in the format registry/repository[:tag|@digest] - (e.g., myrepo/my-model:latest) which will be automatically extracted - to a temporary directory - -When using a ModelKit reference, only the model components are extracted -to optimize startup time.` - - devStartExample = `# Serve the model located in the current directory -kit dev start - -# Serve the modelkit in ./my-model on port 8080 -kit dev start ./my-model --port 8080 - -# Serve a ModelKit reference from local storage or registry -kit dev start myrepo/my-model:latest - -# Serve a specific model with custom host and port -kit dev start registry.example.com/models/llama2:7b --host 0.0.0.0 --port 8080` - - devStopShortDesc = "Stop development server" - devStopLongDesc = "Stop the development server if it is running" - - devLogsShortDesc = "View logs for development server" - devLogsLongDesc = `Print any logs output by the development server. - -If the development server is currently running, the logs for this server will -be printed. If it is stopped, the logs for the previous run of the server, if -available, will be printed instead.` -) diff --git a/pkg/lib/constants/consts.go b/pkg/lib/constants/consts.go index 14763817a..1154862be 100644 --- a/pkg/lib/constants/consts.go +++ b/pkg/lib/constants/consts.go @@ -40,16 +40,9 @@ const ( StorageSubpath = "storage" CacheSubpath = "cache" CredentialsSubpath = "credentials.json" - HarnessSubpath = "harness" - HarnessProcessFile = "process.pid" - HarnessLogFile = "harness.log" UpdateNotificationsConfigFilename = "disable-update-notifications" UpdateCheckCacheFilename = "update-check.json" - // Dev command model extraction/cache paths - DevModelsSubpath = "dev-models" - CurrentDevModelSubpath = "current" - // Kitops-specific annotations for modelkit artifacts // TODO: update these to use the newer kitops.org domain CliVersionAnnotation = "ml.kitops.modelkit.cli-version" @@ -145,10 +138,6 @@ func IngestPath(storageBase string) string { return filepath.Join(storageBase, "ingest") } -func HarnessPath(configBase string) string { - return filepath.Join(configBase, HarnessSubpath) -} - func CredentialsPath(configBase string) string { return filepath.Join(configBase, CredentialsSubpath) } @@ -157,16 +146,6 @@ func CachePath(configBase string) string { return filepath.Join(configBase, CacheSubpath) } -// DevModelsPath returns the base directory used for dev-mode model extractions -func DevModelsPath(configBase string) string { - return filepath.Join(configBase, DevModelsSubpath) -} - -// ExtractedDevModelPath returns the path to the "extracted" dev-mode model directory -func ExtractedDevModelPath(configBase string) string { - return filepath.Join(DevModelsPath(configBase), CurrentDevModelSubpath) -} - // IndexJsonPath is a wrapper for getting the index.json path for a local OCI index, // based off the base path of the index. func IndexJsonPath(storageBase string) string { diff --git a/pkg/lib/harness/generated/gen_common.sh b/pkg/lib/harness/generated/gen_common.sh deleted file mode 100755 index bc2102aaa..000000000 --- a/pkg/lib/harness/generated/gen_common.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh - -UI_DIR=../../../../frontend/dev-mode -LLAMAFILE_VER=$(go run ./llamafile_ver_helper.go) - -build_ui() { - UI_HOME=$1 - - echo "Building harness UI from ${UI_HOME}" - - pushd ${UI_HOME} - pnpm install - pnpm run build - popd -} - -compress() { - echo "Compressing $1 to $2" - tar -czf $2 -C $1 . -} - -generate_sha() { - FILE=$1 - CHECKSUM_FILE=$2 - - echo "Generating SHA256 checksum for ${FILE}" - sha256sum ${FILE} | awk '{print $1 " " FILENAME}' FILENAME="${FILE}" >> ${CHECKSUM_FILE} - echo "Checksum for ${FILE} saved to ${CHECKSUM_FILE}" -} - - -# Function to download a binary asset from a GitHub release -download_github_release_binary() { - OWNER=$1 - REPO=$2 - RELEASE_TAG=$3 - ASSET_NAME=$4 - OUTPUT_DIR=$5 - - echo "Downloading asset '${ASSET_NAME}' from release '${RELEASE_TAG}' of repository '${OWNER}/${REPO}'" - - DOWNLOAD_URL="https://github.com/${OWNER}/${REPO}/releases/download/${RELEASE_TAG}/llamafile-${RELEASE_TAG}" - - mkdir -p ${OUTPUT_DIR} - - curl -L -o ${OUTPUT_DIR}/llamafile ${DOWNLOAD_URL} - - echo "Asset '${ASSET_NAME}' downloaded successfully to: ${OUTPUT_DIR}/${ASSET_NAME}" - - echo "${RELEASE_TAG}" > ${OUTPUT_DIR}/llamafile.version - - COMPRESSED_FILE="llamafile.tar.gz" - compress ${OUTPUT_DIR} ../${COMPRESSED_FILE} - - echo "Compressed asset saved to: ${COMPRESSED_FILE}" -} - -build_ui ${UI_DIR} -compress ${UI_DIR}/dist ../ui.tar.gz -download_github_release_binary "Mozilla-Ocho" "llamafile" "${LLAMAFILE_VER}" "llamafile-${LLAMAFILE_VER}" "./downloads" - -CHECKSUM_FILE="../checksums.txt" -> ${CHECKSUM_FILE} # Clear the checksum file if it exists -generate_sha "../ui.tar.gz" ${CHECKSUM_FILE} -generate_sha "../llamafile.tar.gz" ${CHECKSUM_FILE} - -echo "All checksums have been saved to ${CHECKSUM_FILE}" \ No newline at end of file diff --git a/pkg/lib/harness/generated/llamafile.go b/pkg/lib/harness/generated/llamafile.go deleted file mode 100644 index dc497930d..000000000 --- a/pkg/lib/harness/generated/llamafile.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -package generated - -//go:generate sh ./gen_common.sh diff --git a/pkg/lib/harness/generated/llamafile_ver_helper.go b/pkg/lib/harness/generated/llamafile_ver_helper.go deleted file mode 100644 index eb63aa0db..000000000 --- a/pkg/lib/harness/generated/llamafile_ver_helper.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -//go:build ignore -// +build ignore - -package main - -import ( - "fmt" - - "github.com/kitops-ml/kitops/pkg/lib/harness" -) - -func main() { - fmt.Println(harness.LlamaFileVersion) -} diff --git a/pkg/lib/harness/generated/refresh_downloads.sh b/pkg/lib/harness/generated/refresh_downloads.sh deleted file mode 100755 index 78b30c9d9..000000000 --- a/pkg/lib/harness/generated/refresh_downloads.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash - -set -e - -# R2 Configuration from environment variables -R2_ACCESS_KEY_ID="${R2_ACCESS_KEY_ID}" -R2_SECRET_ACCESS_KEY="${R2_SECRET_ACCESS_KEY}" -R2_ENDPOINT="${R2_ENDPOINT}" - -R2_BUCKET_NAME="kitops-binaries" -REMOTE_NAME="r2" - -# Files to Upload -FILES_TO_UPLOAD=( - "llamafile.tar.gz" - "ui.tar.gz" - "checksums.txt" -) - - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" -LLAMAFILE_VER=$(go run $SCRIPT_DIR/llamafile_ver_helper.go) - - - -# --------------------------- -# Functions -# --------------------------- - -configure_rclone() { - echo "Configuring rclone for Cloudflare R2..." - - # Create rclone configuration using environment variables - rclone config create "$REMOTE_NAME" s3 \ - provider Cloudflare \ - access_key_id "$R2_ACCESS_KEY_ID" \ - secret_access_key "$R2_SECRET_ACCESS_KEY" \ - endpoint "$R2_ENDPOINT" \ - region auto \ - acl private - - echo "rclone configured successfully." -} - -upload() { - SOURCE="$1" - DESTINATION="$2" - - FULL_DESTINATION="${REMOTE_NAME}:${R2_BUCKET_NAME}/${DESTINATION}" - - # Perform the upload using rclone copy - echo "Uploading '${SOURCE}' to '${FULL_DESTINATION}' ..." - rclone copy "$SOURCE" "$FULL_DESTINATION" --verbose - echo "Upload of '${SOURCE}' completed successfully." -} - -# --------------------------- -# Script Execution -# --------------------------- - -# Check if rclone is installed -if ! command -v rclone &> /dev/null -then - echo "Error: rclone could not be found. Please install rclone before running this script." - exit 1 -fi - -# Check if all required environment variables are set -if [[ -z "$R2_ACCESS_KEY_ID" || -z "$R2_SECRET_ACCESS_KEY" || -z "$R2_ENDPOINT" ]]; then - echo "Error: One or more required environment variables (R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_ENDPOINT) are not set." - exit 1 -fi - -configure_rclone - -for DEST_PATH in "${FILES_TO_UPLOAD[@]}"; do - FILE_PATH="${SCRIPT_DIR}/../${DEST_PATH}" - - if [ -f "$FILE_PATH" ]; then - echo "File found: '$FILE_PATH'. Preparing to upload..." - upload "$FILE_PATH" "$LLAMAFILE_VER/$DEST_PATH" - else - echo "Warning: File '$FILE_PATH' does not exist. Skipping upload." - fi -done - -echo "All files uploaded" diff --git a/pkg/lib/harness/llm-harness.go b/pkg/lib/harness/llm-harness.go deleted file mode 100644 index e49d01d42..000000000 --- a/pkg/lib/harness/llm-harness.go +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -package harness - -import ( - "bufio" - "errors" - "fmt" - "io" - "io/fs" - "os" - "os/exec" - "path/filepath" - "runtime" - "strconv" - "strings" - "syscall" - "time" - - "github.com/kitops-ml/kitops/pkg/lib/constants" - "github.com/kitops-ml/kitops/pkg/output" -) - -const LlamaFileVersion = "0.8.16" - -type LLMHarness struct { - Host string - Port int - ConfigHome string -} - -func (harness *LLMHarness) Init() error { - harnessPath := constants.HarnessPath(harness.ConfigHome) - ok, err := checkHarness(harnessPath) - if err != nil { - return fmt.Errorf("failed to verify dev server: %w", err) - } - if ok { - return nil - } - err = extractServer(harnessPath) - if err != nil { - return fmt.Errorf("failed to extract dev server files: %w", err) - } - err = extractUI(harnessPath) - if err != nil { - return fmt.Errorf("failed to extract dev UI files: %w", err) - } - return nil -} - -func (harness *LLMHarness) Start(modelPath string) (err error) { - - harnessPath := constants.HarnessPath(harness.ConfigHome) - pidFile := filepath.Join(harnessPath, constants.HarnessProcessFile) - logFile := filepath.Join(harnessPath, constants.HarnessLogFile) - - if _, err := os.Stat(pidFile); !os.IsNotExist(err) { - // Attempt to read the PID from the file. - pid, err := readPIDFromFile(pidFile) - if err != nil { - return fmt.Errorf("failed to read PID file: %w", err) - } - // Check if the process is still running. - if isProcessRunning(pid) { - return fmt.Errorf("a server process with PID %d is already running", pid) - } else { - output.Infoln("The process previously recorded is not running. Proceeding to start a new process.") - } - } - - uiHome := filepath.Join(harnessPath, "ui") - output.Debugf("model path is %s", modelPath) - var cmd *exec.Cmd - if runtime.GOOS == "windows" { - cmd = exec.Command( - "./llamafile.exe", - "--server", - "--model", modelPath, - "--host", harness.Host, - "--port", fmt.Sprintf("%d", harness.Port), - "--path", uiHome, - "--gpu", "AUTO", - "--nobrowser", - "--unsecure", - ) - } else { - cmd = exec.Command("sh", "-c", - fmt.Sprintf("./llamafile --server --model %s --host %s --port %d --path %s --gpu AUTO --nobrowser --unsecure", - modelPath, harness.Host, harness.Port, uiHome), - ) - } - - cmd.Dir = harnessPath - logs, err := os.OpenFile(logFile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) - if err != nil { - return fmt.Errorf("failed to open log file for harness: %w", err) - } - - defer func() { - if errClose := logs.Close(); errClose != nil { - if err == nil { - err = fmt.Errorf("failed to close log file: %w", errClose) - } else { - err = fmt.Errorf("%v; failed to close log file: %w", err, errClose) - } - } - }() - - output.Debugf("Saving server logs to %s", logFile) - cmd.Stdout = logs - cmd.Stderr = logs - - if err := cmd.Start(); err != nil { - return fmt.Errorf("error starting llm harness: %w", err) - } - - pid := cmd.Process.Pid - if err := writePIDFile(pidFile, pid); err != nil { - return fmt.Errorf("failed to write PID file: %w", err) - } - - output.Debugf("Started harness with PID %d and saved to file.\n", pid) - - return nil -} - -func (harness *LLMHarness) Stop() error { - pidFile := filepath.Join(constants.HarnessPath(harness.ConfigHome), constants.HarnessProcessFile) - - pid, err := readPIDFromFile(pidFile) - if os.IsNotExist(err) { - return fmt.Errorf("no Running server found") - } - if err != nil { - return err - } - - // Check if the process is still running. - if !isProcessRunning(pid) { - return fmt.Errorf("no running process found with PID %d", pid) - } - - // Kill the process using the PID. - process, err := os.FindProcess(pid) - if err != nil { - return fmt.Errorf("error finding process: %w", err) - } - - err = process.Signal(os.Interrupt) // Try to kill it gently - if err != nil { - output.Debugf("Error killing process %v", err) - // If SIGTERM failed, kill it with SIGKILL - err = process.Kill() - if err != nil { - return fmt.Errorf("error killing process: %w", err) - } - } - - output.Debugf("Process with PID %d has been killed.", pid) - // Delete the PID file to clean up. - err = os.Remove(pidFile) - if err != nil { - return fmt.Errorf("error removing PID file: %w", err) - } - - return nil -} - -func PrintLogs(configHome string, w io.Writer, follow bool) error { - harnessPath := constants.HarnessPath(configHome) - logPath := filepath.Join(harnessPath, constants.HarnessLogFile) - logFile, err := os.Open(logPath) - if err != nil { - if os.IsNotExist(err) { - output.Errorf("No log file found") - return nil - } - return fmt.Errorf("error reading log file: %w", err) - } - defer logFile.Close() - reader := bufio.NewReader(logFile) - for { - line, err := reader.ReadString('\n') - if err != nil { - if err == io.EOF { - if !follow { - return nil - } - time.Sleep(1 * time.Second) - err := checkExistence(configHome) - if err != nil { - return fmt.Errorf("server stopped") - } - continue - } else { - return fmt.Errorf("failed to print log file: %w", err) - } - } - if _, err := w.Write([]byte(line)); err != nil { - return fmt.Errorf("failed to write to output: %w", err) - } - } -} - -func checkExistence(configHome string) error { - pidFile := filepath.Join(constants.HarnessPath(configHome), constants.HarnessProcessFile) - - pid, err := readPIDFromFile(pidFile) - if os.IsNotExist(err) { - return fmt.Errorf("no Running server found") - } - if err != nil { - return err - } - - // Check if the process is still running. - if !isProcessRunning(pid) { - return fmt.Errorf("no running process found with PID %d", pid) - } - return nil -} - -func isProcessRunning(pid int) bool { - process, err := os.FindProcess(pid) - if err != nil { - return false - } - if runtime.GOOS == "windows" { - // On Windows, just finding the process implies it exists - return true - } - // Sending signal 0 to a process does not affect it but can be used for error checking. - // If an error is returned, the process does not exist. - err = process.Signal(syscall.Signal(0)) - return err == nil -} - -// ensures the directory for pidFilePath exists and writes the PID to the file. -func writePIDFile(pidFilePath string, pid int) error { - // Ensure the directory for the pidFilePath exists. - dir := filepath.Dir(pidFilePath) - if err := os.MkdirAll(dir, 0o755); err != nil { - return fmt.Errorf("error creating directory %s: %w", dir, err) - } - - // Write the PID to the file. - pidData := []byte(fmt.Sprintf("%d", pid)) - if err := os.WriteFile(pidFilePath, pidData, 0644); err != nil { - return fmt.Errorf("error writing PID to file %s: %w", pidFilePath, err) - } - - return nil -} - -func readPIDFromFile(filePath string) (int, error) { - data, err := os.ReadFile(filePath) - if err != nil { - return 0, err - } - pid, err := strconv.Atoi(string(data)) - if err != nil { - return 0, err - } - return pid, nil -} - -func checkHarness(harnessHome string) (bool, error) { - executableName := "llamafile" - if runtime.GOOS == "windows" { - executableName = "llamafile.exe" - } - llamaFilePath := filepath.Join(harnessHome, executableName) - llamaVersionPath := filepath.Join(harnessHome, "llamafile.version") - uiPath := filepath.Join(harnessHome, "ui") - - // 'llamafile' - if _, err := os.Stat(llamaFilePath); errors.Is(err, fs.ErrNotExist) { - return false, nil - } else if err != nil { - return false, fmt.Errorf("error checking 'llamafile': %w", err) - } - - // llamafile.version - if _, err := os.Stat(llamaVersionPath); errors.Is(err, fs.ErrNotExist) { - return false, nil - } else if err != nil { - return false, fmt.Errorf("error checking 'llamafile.version': %w", err) - } - - versionData, err := os.ReadFile(llamaVersionPath) - if err != nil { - return false, fmt.Errorf("error reading 'llamafile.version': %w", err) - } - version := strings.TrimSpace(string(versionData)) - if version != LlamaFileVersion { - return false, nil - } - - // 'ui/' - uiInfo, err := os.Stat(uiPath) - if errors.Is(err, fs.ErrNotExist) { - return false, nil - } else if err != nil { - return false, fmt.Errorf("error checking 'ui' directory: %w", err) - } - if !uiInfo.IsDir() { - return false, fmt.Errorf("'ui' exists but is not a directory") - } - - // harness is ready - return true, nil -} diff --git a/pkg/lib/harness/llm_download.go b/pkg/lib/harness/llm_download.go deleted file mode 100644 index c5116c254..000000000 --- a/pkg/lib/harness/llm_download.go +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -//go:build !embed_harness -// +build !embed_harness - -package harness - -import ( - "bufio" - "crypto/sha256" - "encoding/hex" - "fmt" - "io" - "net/http" - "os" - "path/filepath" - "runtime" - "strings" - - "github.com/kitops-ml/kitops/pkg/output" -) - -const ( - llamafileDownloadURL = "https://jozu.ml/downloads/?file=llamafile.tar.gz&version=" + LlamaFileVersion - uiDownloadURL = "https://jozu.ml/downloads/?file=ui.tar.gz&version=" + LlamaFileVersion - checksumURL = "https://jozu.ml/downloads/?file=checksums.txt&version=" + LlamaFileVersion -) - -func extractServer(harnessHome string) error { - if err := os.MkdirAll(harnessHome, os.FileMode(0755)); err != nil { - return fmt.Errorf("error creating directory %s: %w", harnessHome, err) - } - tmpFolder, err := os.MkdirTemp("", "kitops_tmp") - if err != nil { - return fmt.Errorf("failed to create temporary directory: %w", err) - } - defer os.RemoveAll(tmpFolder) - - output.Infoln("downloading harness binaries") - err = downloadFile(llamafileDownloadURL, tmpFolder, "llamafile.tar.gz") - if err != nil { - return fmt.Errorf("failed to extract llamafile: %w", err) - } - // Download and verify checksum - checksums, err := downloadAndParseChecksums(tmpFolder) - if err != nil { - return fmt.Errorf("failed to download and parse checksums: %w", err) - } - err = verifyChecksum(tmpFolder, "llamafile.tar.gz", checksums) - if err != nil { - return fmt.Errorf("checksum verification failed for llamafile.tar.gz: %w", err) - } - - localFS := os.DirFS(tmpFolder) - - err = extractFile(localFS, "llamafile.tar.gz", harnessHome) - if err != nil { - return fmt.Errorf("failed to unpack llamafile: %w", err) - } - - llamaFilePath := filepath.Join(harnessHome, "llamafile") - if runtime.GOOS == "windows" { - llamaExePath := filepath.Join(harnessHome, "llamafile.exe") - if err := os.Rename(llamaFilePath, llamaExePath); err != nil { - return fmt.Errorf("error renaming file to executable: %w", err) - } - } else { - if err := os.Chmod(llamaFilePath, os.FileMode(0755)); err != nil { - return fmt.Errorf("error setting executable permission: %w", err) - } - } - - return nil -} - -func extractUI(harnessHome string) error { - tmpFolder, err := os.MkdirTemp("", "kitops_tmp") - if err != nil { - return fmt.Errorf("failed to create temporary directory: %w", err) - } - defer os.RemoveAll(tmpFolder) - - output.Infoln("Updating harness UI components") - err = downloadFile(uiDownloadURL, tmpFolder, "ui.tar.gz") - if err != nil { - return fmt.Errorf("failed to extract UI: %w", err) - } - - // Download checksum.txt - checksums, err := downloadAndParseChecksums(tmpFolder) - if err != nil { - return fmt.Errorf("failed to download and parse checksums: %w", err) - } - // Verify checksum - err = verifyChecksum(tmpFolder, "ui.tar.gz", checksums) - if err != nil { - return fmt.Errorf("checksum verification failed for ui.tar.gz: %w", err) - } - - uiHome := filepath.Join(harnessHome, "ui") - if err := os.MkdirAll(uiHome, os.FileMode(0755)); err != nil { - return fmt.Errorf("failed to create directory %s: %w", uiHome, err) - } - localFS := os.DirFS(tmpFolder) - - return extractFile(localFS, "ui.tar.gz", uiHome) -} - -func downloadFile(url string, folder string, filename string) error { - - err := os.MkdirAll(folder, os.FileMode(0755)) - if err != nil { - return fmt.Errorf("failed to create folder %s: %w", folder, err) - } - - filePath := filepath.Join(folder, filename) - - out, err := os.Create(filePath) - if err != nil { - return fmt.Errorf("failed to create file %s: %w", folder, err) - } - defer out.Close() - - resp, err := http.Get(url) - if err != nil { - return fmt.Errorf("download from url %s failed: %w", url, err) - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("bad status downloading file from %s: %s", url, resp.Status) - - } - - _, err = io.Copy(out, resp.Body) - if err != nil { - return fmt.Errorf("failed to write to file %s: %w", filePath, err) - } - - return nil - -} -func downloadAndParseChecksums(tmpFolder string) (map[string]string, error) { - err := downloadFile(checksumURL, tmpFolder, "checksums.txt") - if err != nil { - return nil, fmt.Errorf("failed to download checksums.txt: %w", err) - } - - checksumFilePath := filepath.Join(tmpFolder, "checksums.txt") - checksums, err := parseChecksumFile(checksumFilePath) - if err != nil { - return nil, fmt.Errorf("failed to parse checksums.txt: %w", err) - } - - return checksums, nil -} - -func verifyChecksum(folder, filename string, checksums map[string]string) error { - expectedChecksum, ok := checksums[filename] - if !ok { - return fmt.Errorf("checksum not found for file: %s", filename) - } - - filePath := filepath.Join(folder, filename) - file, err := os.Open(filePath) - if err != nil { - return fmt.Errorf("failed to open file %s: %w", filePath, err) - } - defer file.Close() - - hash := sha256.New() - if _, err := io.Copy(hash, file); err != nil { - return fmt.Errorf("failed to compute checksum for %s: %w", filePath, err) - } - - computedChecksum := hex.EncodeToString(hash.Sum(nil)) - - if computedChecksum != expectedChecksum { - return fmt.Errorf("checksum mismatch for %s: expected %s, got %s", filename, expectedChecksum, computedChecksum) - } - - output.Infoln(fmt.Sprintf("Checksum verified for %s", filename)) - return nil -} - -func parseChecksumFile(filePath string) (map[string]string, error) { - checksums := make(map[string]string) - - file, err := os.Open(filePath) - if err != nil { - return nil, fmt.Errorf("failed to open checksum file: %w", err) - } - defer file.Close() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - line := scanner.Text() - // Skip empty lines - if strings.TrimSpace(line) == "" { - continue - } - parts := strings.Fields(line) - if len(parts) != 2 { - return nil, fmt.Errorf("invalid checksum line: %s", line) - } - checksum := parts[0] - filename := filepath.Base(parts[1]) // Get the base name of the file (e.g., 'ui.tar.gz') - checksums[filename] = checksum - } - - if err := scanner.Err(); err != nil { - return nil, fmt.Errorf("error reading checksum file: %w", err) - } - - return checksums, nil -} diff --git a/pkg/lib/harness/llm_payload.go b/pkg/lib/harness/llm_payload.go deleted file mode 100644 index 05dea0f6d..000000000 --- a/pkg/lib/harness/llm_payload.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -//go:build embed_harness -// +build embed_harness - -package harness - -import ( - "embed" - "fmt" - "os" - "path/filepath" - "runtime" -) - -//go:embed llamafile*.tar.gz -var serverEmbed embed.FS - -//go:embed ui.tar.gz -var uiEmbed embed.FS - -func extractServer(harnessHome string) error { - // Create the harnessHome directory once before extracting files - if err := os.MkdirAll(harnessHome, os.FileMode(0755)); err != nil { - return fmt.Errorf("error creating directory %s: %w", harnessHome, err) - } - if err := extractFile(serverEmbed, "llamafile.tar.gz", harnessHome); err != nil { - return fmt.Errorf("error extracting file %s to %s: %w", "llamafile.tar.gz", harnessHome, err) - } - - // Set executable permissions and rename on Windows - llamaFilePath := filepath.Join(harnessHome, "llamafile") - if runtime.GOOS == "windows" { - llamaExePath := filepath.Join(harnessHome, "llamafile.exe") - if err := os.Rename(llamaFilePath, llamaExePath); err != nil { - return fmt.Errorf("error renaming file to executable: %w", err) - } - } else { - if err := os.Chmod(llamaFilePath, os.FileMode(0755)); err != nil { - return fmt.Errorf("error setting executable permission: %w", err) - } - } - - return nil -} - -func extractUI(harnessHome string) error { - uiHome := filepath.Join(harnessHome, "ui") - if err := os.MkdirAll(uiHome, os.FileMode(0755)); err != nil { - return fmt.Errorf("failed to create directory %s: %w", uiHome, err) - } - return extractFile(uiEmbed, "ui.tar.gz", uiHome) -} diff --git a/pkg/lib/harness/llm_payload_all.go b/pkg/lib/harness/llm_payload_all.go deleted file mode 100644 index 2cdcf2ff7..000000000 --- a/pkg/lib/harness/llm_payload_all.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -package harness - -import ( - "archive/tar" - "compress/gzip" - "fmt" - "io" - "io/fs" - "os" - "path/filepath" - "strings" - - "github.com/kitops-ml/kitops/pkg/lib/filesystem" -) - -func extractFile(fs fs.FS, file, harnessHome string) (err error) { - srcFile, err := fs.Open(file) - if err != nil { - return fmt.Errorf("failed to open file %s: %w", file, err) - } - defer srcFile.Close() - - srcReader := io.Reader(srcFile) - destFileName := file - - if strings.HasSuffix(file, ".tar.gz") { - gzr, err := gzip.NewReader(srcReader) - if err != nil { - return fmt.Errorf("failed to create gzip reader for %s: %w", file, err) - } - defer gzr.Close() - tarReader := tar.NewReader(gzr) - return extractTar(tarReader, harnessHome) - } - - if strings.HasSuffix(file, ".gz") { - srcReader, err = gzip.NewReader(srcReader) - if err != nil { - return fmt.Errorf("failed to decompress payload %s: %w", file, err) - } - destFileName = strings.TrimSuffix(file, ".gz") - } - - destFile := filepath.Join(harnessHome, filepath.Base(destFileName)) - dest, err := os.OpenFile(destFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(0755)) // Keep executable permissions - if err != nil { - return fmt.Errorf("failed to create destination file %s: %w", destFile, err) - } - defer closeFileErrCheck(dest, &err, "failed to close destination file") - - if _, err := io.Copy(dest, srcReader); err != nil { - return fmt.Errorf("failed to copy payload to %s: %w", destFile, err) - } - return nil -} - -func extractTar(tr *tar.Reader, dir string) (err error) { - for { - header, err := tr.Next() - if err == io.EOF { - break - } - if err != nil { - return fmt.Errorf("failed to read tar header: %w", err) - } - // Sanitize the file name to prevent path traversal - sanitizedName := filepath.Clean(header.Name) - if strings.Contains(sanitizedName, "..") || filepath.IsAbs(sanitizedName) { - return fmt.Errorf("invalid file path in archive: %s", sanitizedName) - } - outPath := filepath.Join(dir, sanitizedName) - - switch header.Typeflag { - case tar.TypeDir: - if err := os.MkdirAll(outPath, header.FileInfo().Mode()); err != nil { - return fmt.Errorf("failed to create directory %s: %w", outPath, err) - } - - case tar.TypeReg: - if fi, exists := filesystem.PathExists(outPath); exists { - if !fi.Mode().IsRegular() { - return fmt.Errorf("path '%s' already exists and is not a regular file", outPath) - } - } - file, err := os.OpenFile(outPath, os.O_CREATE|os.O_TRUNC|os.O_RDWR, header.FileInfo().Mode()) - if err != nil { - return fmt.Errorf("failed to create file %s: %w", outPath, err) - } - defer closeFileErrCheck(file, &err, "failed to close gzip reader") - - written, err := io.Copy(file, tr) - if err != nil { - return fmt.Errorf("failed to write file %s: %w", outPath, err) - } - if written != header.Size { - return fmt.Errorf("could not unpack file %s", outPath) - } - - default: - return fmt.Errorf("unrecognized type in archive: %s", header.Name) - } - } - return nil -} - -func closeFileErrCheck(f *os.File, err *error, msg string) { - if cerr := f.Close(); cerr != nil { - if *err == nil { - *err = fmt.Errorf("%s: %w", msg, cerr) - } else { - *err = fmt.Errorf("%v; %s: %w", *err, msg, cerr) - } - } -} diff --git a/testing/dev_test.go b/testing/dev_test.go deleted file mode 100644 index 0e13999ab..000000000 --- a/testing/dev_test.go +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2024 The KitOps Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -package testing - -import ( - "fmt" - "os" - "path/filepath" - "regexp" - "strings" - "testing" - - "github.com/kitops-ml/kitops/pkg/lib/constants" - "github.com/stretchr/testify/assert" -) - -type devTestcase struct { - Name string - Description string `yaml:"description"` - Setup struct { - ModelKits []struct { - Tag string `yaml:"tag"` - Kitfile string `yaml:"kitfile"` - Files []string `yaml:"files"` - } `yaml:"modelkits"` - } `yaml:"setup"` - Tests []struct { - Name string `yaml:"name"` - Args string `yaml:"args"` - ExpectStartError bool `yaml:"expectStartError"` - ExpectedCacheDir bool `yaml:"expectedCacheDir"` - ExpectedCleanup bool `yaml:"expectedCleanup"` - StartErrorRegexp string `yaml:"startErrorRegexp"` - ExpectedFiles []string `yaml:"expectedFiles"` - } `yaml:"tests"` -} - -func (t devTestcase) withName(name string) devTestcase { - t.Name = name - return t -} - -// assertContainsRegexp checks if output matches the given regex pattern -func assertContainsRegexp(t *testing.T, output, pattern string, shouldContain bool) { - matched, err := regexp.MatchString(pattern, output) - if err != nil { - t.Fatalf("Invalid regex pattern %s: %v", pattern, err) - } - if shouldContain && !matched { - t.Fatalf("Output should match regexp %s, but got:\n%s", pattern, output) - } - if !shouldContain && matched { - t.Fatalf("Output should not match regexp %s, but got:\n%s", pattern, output) - } -} - -func TestDevCommand(t *testing.T) { - testPreflight(t) - - tests := loadAllTestCasesOrPanic[devTestcase](t, filepath.Join("testdata", "dev")) - for _, tt := range tests { - t.Run(fmt.Sprintf("%s (%s)", tt.Name, tt.Description), func(t *testing.T) { - // Set up temporary directory for work - tmpDir := setupTempDir(t) - contextPath := filepath.Join(tmpDir, ".kitops") - t.Setenv(constants.KitopsHomeEnvVar, contextPath) - - // Pack ModelKits for testing - for i, modelkit := range tt.Setup.ModelKits { - modelKitDir := filepath.Join(tmpDir, fmt.Sprintf("modelkit-%d", i)) - if err := os.MkdirAll(modelKitDir, 0755); err != nil { - t.Fatal(err) - } - - setupKitfileAndKitignore(t, modelKitDir, modelkit.Kitfile, "") - setupFiles(t, modelKitDir, modelkit.Files) - runCommand(t, expectNoError, "pack", modelKitDir, "-t", modelkit.Tag) - } - - // Run individual test cases - for _, testCase := range tt.Tests { - t.Run(testCase.Name, func(t *testing.T) { - cacheDir := filepath.Join(contextPath, "dev-models", "current") - - // Clear cache directory and stop any running dev server before each test - os.RemoveAll(cacheDir) - _ = runCommand(t, expectError, "dev", "stop") // Ignore errors - - // Parse arguments - var args []string - if testCase.Args != "" { - args = strings.Fields(testCase.Args) - } - fullArgs := append([]string{"dev", "start"}, args...) - - if testCase.ExpectStartError { - output := runCommand(t, expectError, fullArgs...) - if testCase.StartErrorRegexp != "" { - assertContainsRegexp(t, output, testCase.StartErrorRegexp, true) - } - - // For reference-based tests, check if cache directory was created - if testCase.ExpectedCacheDir { - // Cache directory should exist even if dev start failed - // (because extraction happens before harness failure) - _, err := os.Stat(cacheDir) - if !assert.NoError(t, err, "Cache directory should be created during extraction") { - return - } - - // Check if expected files were extracted - if len(testCase.ExpectedFiles) > 0 { - checkFilesExist(t, cacheDir, testCase.ExpectedFiles) - } - } - } else { - // Test successful start - run in background and then stop - output := runCommand(t, expectNoError, fullArgs...) - - // Log successful start - t.Logf("Dev server started successfully: %s", output) - - // Check cache directory if expected - if testCase.ExpectedCacheDir { - _, err := os.Stat(cacheDir) - assert.NoError(t, err, "Cache directory should be created during extraction") - - if len(testCase.ExpectedFiles) > 0 { - checkFilesExist(t, cacheDir, testCase.ExpectedFiles) - } - } - } - - // Test cleanup if expected - if testCase.ExpectedCleanup { - // For successful starts, dev stop should succeed and clean up cache - // For failed starts, dev stop will fail but we don't test cleanup in that case - if !testCase.ExpectStartError { - runCommand(t, expectNoError, "dev", "stop") // Should succeed since server is running - - // Verify cache directory was cleaned up - _, err := os.Stat(cacheDir) - assert.True(t, os.IsNotExist(err), "Cache directory should be cleaned up after successful dev stop") - } - } - }) - } - }) - } -} - -// TestDevDirectory tests the original directory-based dev functionality -func TestDevDirectory(t *testing.T) { - testPreflight(t) - - tmpDir := setupTempDir(t) - modelKitPath, _, contextPath := setupTestDirs(t, tmpDir) - t.Setenv(constants.KitopsHomeEnvVar, contextPath) - - // Create a test model file - kitfileContent := `manifestVersion: 1.0.0 -package: - name: test-dev-model -model: - path: test-model.gguf` - - setupKitfileAndKitignore(t, modelKitPath, kitfileContent, "") - setupFiles(t, modelKitPath, []string{"test-model.gguf"}) - - // Test that dev start works with directory paths (original functionality) - output := runCommand(t, expectNoError, "dev", "start", modelKitPath) - - // Should succeed completely - assert.Contains(t, output, "Development server started") - assert.NotContains(t, output, "failed to find Kitfile") - assert.NotContains(t, output, "could not find model file") - - // Clean up the running server - runCommand(t, expectNoError, "dev", "stop") -} - -// TestDevCleanup tests that dev stop properly cleans up resources -func TestDevCleanup(t *testing.T) { - testPreflight(t) - - tmpDir := setupTempDir(t) - contextPath := filepath.Join(tmpDir, ".kitops") - t.Setenv(constants.KitopsHomeEnvVar, contextPath) - - // Create a fake cache directory structure - cacheDir := filepath.Join(contextPath, "dev-models", "current") - if err := os.MkdirAll(cacheDir, 0755); err != nil { - t.Fatal(err) - } - - // Create test files in cache - testFiles := []string{"test-model.gguf", "Kitfile"} - for _, file := range testFiles { - testFile := filepath.Join(cacheDir, file) - if err := os.WriteFile(testFile, []byte("test model data"), 0644); err != nil { - t.Fatal(err) - } - } - - // Verify cache directory and files exist - _, err := os.Stat(cacheDir) - assert.NoError(t, err, "Cache directory should exist before cleanup") - - for _, file := range testFiles { - _, err := os.Stat(filepath.Join(cacheDir, file)) - assert.NoError(t, err, "Test file %s should exist before cleanup", file) - } - - // Run dev stop (will fail due to no running server), but should still clean up cache - runCommand(t, expectError, "dev", "stop") - _, err = os.Stat(cacheDir) - assert.True(t, os.IsNotExist(err), "Cache directory should be removed by dev stop") -} - -// TestDevErrorScenarios tests various error conditions -func TestDevErrorScenarios(t *testing.T) { - testPreflight(t) - - tests := []struct { - name string - args []string - expectedRegexp string - }{ - { - name: "no arguments and no kitfile", - args: []string{"dev", "start"}, - expectedRegexp: "no Kitfile found in directory", - }, - { - name: "nonexistent modelkit reference", - args: []string{"dev", "start", "nonexistent/model:tag"}, - expectedRegexp: "failed to extract ModelKit.*not found", - }, - { - name: "empty argument", - args: []string{"dev", "start", ""}, - expectedRegexp: "no Kitfile found in directory", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tmpDir := setupTempDir(t) - contextPath := filepath.Join(tmpDir, ".kitops") - t.Setenv(constants.KitopsHomeEnvVar, contextPath) - - output := runCommand(t, expectError, tt.args...) - assertContainsRegexp(t, output, tt.expectedRegexp, true) // Use our function with shouldContain=true - }) - } -} - -// TestDevReferenceExtraction tests that ModelKit references are properly extracted -func TestDevReferenceExtraction(t *testing.T) { - testPreflight(t) - - tmpDir := setupTempDir(t) - contextPath := filepath.Join(tmpDir, ".kitops") - t.Setenv(constants.KitopsHomeEnvVar, contextPath) - - // Create a test ModelKit - modelKitDir := filepath.Join(tmpDir, "test-modelkit") - if err := os.MkdirAll(modelKitDir, 0755); err != nil { - t.Fatal(err) - } - - kitfileContent := `manifestVersion: 1.0.0 -package: - name: test-extraction-model -model: - path: models/test-model.gguf` - - setupKitfileAndKitignore(t, modelKitDir, kitfileContent, "") - setupFiles(t, modelKitDir, []string{"models/test-model.gguf"}) - - // Pack the ModelKit - runCommand(t, expectNoError, "pack", modelKitDir, "-t", "test/extraction:latest") - - // Try to start dev server with ModelKit reference - // This should extract the ModelKit to cache directory and start successfully - cacheDir := filepath.Join(contextPath, "dev-models", "current") - - output := runCommand(t, expectNoError, "dev", "start", "test/extraction:latest") - - // Should succeed - server should start - assert.Contains(t, output, "Development server started") - assert.NotContains(t, output, "failed to extract ModelKit") - assert.NotContains(t, output, "not found") - - // Cache directory should be created - _, err := os.Stat(cacheDir) - assert.NoError(t, err, "Cache directory should be created during extraction") - - // Expected files should be extracted - expectedFiles := []string{"Kitfile", "models/test-model.gguf"} - for _, file := range expectedFiles { - filePath := filepath.Join(cacheDir, file) - _, err := os.Stat(filePath) - assert.NoError(t, err, "File %s should be extracted to cache", file) - } - - // Clean up - should succeed since server is running - runCommand(t, expectNoError, "dev", "stop") - - // Verify cleanup - should work since stop was successful - _, err = os.Stat(cacheDir) - assert.True(t, os.IsNotExist(err), "Cache directory should be cleaned up") -}