From 0ff9f4b74e080f71a6ef098c00bfcff29c918ce0 Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Wed, 9 Jul 2025 23:57:47 +0900 Subject: [PATCH] Add local LLM, STT --- README.md | 6 +- electron-builder.yml | 2 + package-lock.json | 2417 +---------------- package.json | 4 +- src/app/ApiKeyHeader.js | 1513 ++++++++++- src/common/ai/factory.js | 28 + src/common/ai/providers/ollama.js | 242 ++ src/common/ai/providers/whisper.js | 231 ++ src/common/config/checksums.js | 46 + src/common/config/schema.js | 17 + src/common/repositories/ollamaModel/index.js | 20 + .../ollamaModel/sqlite.repository.js | 137 + src/common/repositories/whisperModel/index.js | 53 + src/common/services/cryptoService.js | 89 + src/common/services/localAIServiceBase.js | 277 ++ src/common/services/localProgressTracker.js | 133 + src/common/services/modelStateService.js | 165 +- src/common/services/ollamaService.js | 809 ++++++ src/common/services/whisperService.js | 352 +++ src/common/utils/spawnHelper.js | 39 + src/electron/windowManager.js | 54 +- src/features/listen/stt/sttService.js | 98 +- src/features/settings/SettingsView.js | 454 +++- src/index.js | 350 ++- 24 files changed, 5127 insertions(+), 2409 deletions(-) create mode 100644 src/common/ai/providers/ollama.js create mode 100644 src/common/ai/providers/whisper.js create mode 100644 src/common/config/checksums.js create mode 100644 src/common/repositories/ollamaModel/index.js create mode 100644 src/common/repositories/ollamaModel/sqlite.repository.js create mode 100644 src/common/repositories/whisperModel/index.js create mode 100644 src/common/services/cryptoService.js create mode 100644 src/common/services/localAIServiceBase.js create mode 100644 src/common/services/localProgressTracker.js create mode 100644 src/common/services/ollamaService.js create mode 100644 src/common/services/whisperService.js create mode 100644 src/common/utils/spawnHelper.js diff --git a/README.md b/README.md index e5510e2..0afea2c 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ npm run setup **Currently Supporting:** - OpenAI API: Get OpenAI API Key [here](https://platform.openai.com/api-keys) - Gemini API: Get Gemini API Key [here](https://aistudio.google.com/apikey) -- Local LLM (WIP) +- Local LLM Ollama & Whisper ### Liquid Glass Design (coming soon) @@ -115,8 +115,6 @@ We have a list of [help wanted](https://github.com/pickle-com/glass/issues?q=is% | Status | Issue | Description | |--------|--------------------------------|---------------------------------------------------| -| 🚧 WIP | Local LLM Support | Supporting Local LLM to power AI answers | -| 🚧 WIP | Firebase Data Storage Issue | Session & ask should be saved in firebase for signup users | | 🚧 WIP | Liquid Glass | Liquid Glass UI for MacOS 26 | ### Changelog @@ -125,7 +123,7 @@ We have a list of [help wanted](https://github.com/pickle-com/glass/issues?q=is% - Jul 6: Full code refactoring has done. - Jul 7: Now support Claude, LLM/STT model selection - Jul 8: Now support Windows(beta), Improved AEC by Rust(to seperate mic/system audio), shortcut editing(beta) - +- Jul 8: Now support Local LLM & STT, Firebase Data Storage ## About Pickle diff --git a/electron-builder.yml b/electron-builder.yml index 79b81fb..174740b 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -34,6 +34,8 @@ extraResources: asarUnpack: - "src/assets/SystemAudioDump" + - "**/node_modules/sharp/**/*" + - "**/node_modules/@img/**/*" # Windows configuration win: diff --git a/package-lock.json b/package-lock.json index 889f3eb..115fcfb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pickle-glass", - "version": "0.2.3", + "version": "0.2.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pickle-glass", - "version": "0.2.3", + "version": "0.2.4", "hasInstallScript": true, "license": "GPL-3.0", "dependencies": { @@ -55,8 +55,6 @@ }, "node_modules/@anthropic-ai/sdk": { "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.56.0.tgz", - "integrity": "sha512-SLCB8M8+VMg1cpCucnA1XWHGWqVSZtIWzmOdDOEu3eTFZMB+A0sGZ1ESO5MHDnqrNTXz3safMrWx9x4rMZSOqA==", "license": "MIT", "bin": { "anthropic-ai-sdk": "bin/cli" @@ -64,8 +62,6 @@ }, "node_modules/@develar/schema-utils": { "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", "dev": true, "license": "MIT", "dependencies": { @@ -82,8 +78,6 @@ }, "node_modules/@electron-forge/cli": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-7.8.1.tgz", - "integrity": "sha512-QI3EShutfq9Y+2TWWrPjm4JZM3eSAKzoQvRZdVhAfVpUbyJ8K23VqJShg3kGKlPf9BXHAGvE+8LyH5s2yDr1qA==", "dev": true, "funding": [ { @@ -120,8 +114,6 @@ }, "node_modules/@electron-forge/core": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-7.8.1.tgz", - "integrity": "sha512-jkh0QPW5p0zmruu1E8+2XNufc4UMxy13WLJcm7hn9jbaXKLkMbKuEvhrN1tH/9uGp1mhr/t8sC4N67gP+gS87w==", "dev": true, "funding": [ { @@ -176,8 +168,6 @@ }, "node_modules/@electron-forge/core-utils": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/core-utils/-/core-utils-7.8.1.tgz", - "integrity": "sha512-mRoPLDNZgmjyOURE/K0D3Op53XGFmFRgfIvFC7c9S/BqsRpovVblrqI4XxPRdNmH9dvhd8On9gGz+XIYAKD3aQ==", "dev": true, "license": "MIT", "dependencies": { @@ -195,10 +185,62 @@ "node": ">= 16.4.0" } }, + "node_modules/@electron-forge/core-utils/node_modules/@electron/rebuild": { + "version": "3.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/node-gyp": "https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@electron-forge/core/node_modules/@electron/rebuild": { + "version": "3.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/node-gyp": "https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, "node_modules/@electron-forge/maker-base": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-7.8.1.tgz", - "integrity": "sha512-GUZqschGuEBzSzE0bMeDip65IDds48DZXzldlRwQ+85SYVA6RMU2AwDDqx3YiYsvP2OuxKruuqIJZtOF5ps4FQ==", "dev": true, "license": "MIT", "dependencies": { @@ -212,8 +254,6 @@ }, "node_modules/@electron-forge/maker-deb": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-deb/-/maker-deb-7.8.1.tgz", - "integrity": "sha512-tjjeesQtCP5Xht1X7gl4+K9bwoETPmQfBkOVAY/FZIxPj40uQh/hOUtLX2tYENNGNVZ1ryDYRs8TuPi+I41Vfw==", "dev": true, "license": "MIT", "dependencies": { @@ -229,8 +269,6 @@ }, "node_modules/@electron-forge/maker-dmg": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-dmg/-/maker-dmg-7.8.1.tgz", - "integrity": "sha512-l449QvY2Teu+J9rHnjkTHEm/wOJ1LRfmrQ2QkGtFoTRcqvFWdUAEN8nK2/08w3j2h6tvOY3QSUjRzXrhJZRNRA==", "dev": true, "license": "MIT", "dependencies": { @@ -247,8 +285,6 @@ }, "node_modules/@electron-forge/maker-rpm": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-rpm/-/maker-rpm-7.8.1.tgz", - "integrity": "sha512-TF6wylft3BHkw9zdHcxmjEPBZYgTIc0jE31skFnMEQ/aExbNRiNaCZvsXy+7ptTWZxhxUKRc9KHhLFRMCmOK8g==", "dev": true, "license": "MIT", "dependencies": { @@ -264,8 +300,6 @@ }, "node_modules/@electron-forge/maker-squirrel": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-squirrel/-/maker-squirrel-7.8.1.tgz", - "integrity": "sha512-qT1PMvT7ALF0ONOkxlA0oc0PiFuKCAKgoMPoxYo9gGOqFvnAb+TBcnLxflQ4ashE/ZkrHpykr4LcDJxqythQTA==", "dev": true, "license": "MIT", "dependencies": { @@ -282,8 +316,6 @@ }, "node_modules/@electron-forge/maker-zip": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-zip/-/maker-zip-7.8.1.tgz", - "integrity": "sha512-unIxEoV1lnK4BLVqCy3L2y897fTyg8nKY1WT4rrpv0MUKnQG4qmigDfST5zZNNHHaulEn/ElAic2GEiP7d6bhQ==", "dev": true, "license": "MIT", "dependencies": { @@ -299,8 +331,6 @@ }, "node_modules/@electron-forge/plugin-auto-unpack-natives": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/plugin-auto-unpack-natives/-/plugin-auto-unpack-natives-7.8.1.tgz", - "integrity": "sha512-4URAgWX9qqqKe6Bfad0VmpFRrwINYMODfKGd2nFQrfHxmBtdpXnsWlLwVGE/wGssIQaTMI5bWQ6F2RNeXTgnhA==", "dev": true, "license": "MIT", "dependencies": { @@ -313,8 +343,6 @@ }, "node_modules/@electron-forge/plugin-base": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/plugin-base/-/plugin-base-7.8.1.tgz", - "integrity": "sha512-iCZC2d7CbsZ9l6j5d+KPIiyQx0U1QBfWAbKnnQhWCSizjcrZ7A9V4sMFZeTO6+PVm48b/r9GFPm+slpgZtYQLg==", "dev": true, "license": "MIT", "dependencies": { @@ -326,8 +354,6 @@ }, "node_modules/@electron-forge/plugin-fuses": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/plugin-fuses/-/plugin-fuses-7.8.1.tgz", - "integrity": "sha512-dYTwvbV1HcDOIQ0wTybpdtPq6YoBYXIWBTb7DJuvFu/c/thj1eoEdnbwr8mT9hEivjlu5p4ls46n16P5EtZ0oA==", "dev": true, "license": "MIT", "dependencies": { @@ -343,8 +369,6 @@ }, "node_modules/@electron-forge/publisher-base": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/publisher-base/-/publisher-base-7.8.1.tgz", - "integrity": "sha512-z2C+C4pcFxyCXIFwXGDcxhU8qtVUPZa3sPL6tH5RuMxJi77768chLw2quDWk2/dfupcSELXcOMYCs7aLysCzeQ==", "dev": true, "license": "MIT", "dependencies": { @@ -356,8 +380,6 @@ }, "node_modules/@electron-forge/shared-types": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/shared-types/-/shared-types-7.8.1.tgz", - "integrity": "sha512-guLyGjIISKQQRWHX+ugmcjIOjn2q/BEzCo3ioJXFowxiFwmZw/oCZ2KlPig/t6dMqgUrHTH5W/F0WKu0EY4M+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -370,10 +392,35 @@ "node": ">= 16.4.0" } }, + "node_modules/@electron-forge/shared-types/node_modules/@electron/rebuild": { + "version": "3.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/node-gyp": "https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, "node_modules/@electron-forge/template-base": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/template-base/-/template-base-7.8.1.tgz", - "integrity": "sha512-k8jEUr0zWFWb16ZGho+Es2OFeKkcbTgbC6mcH4eNyF/sumh/4XZMcwRtX1i7EiZAYiL9sVxyI6KVwGu254g+0g==", "dev": true, "license": "MIT", "dependencies": { @@ -390,8 +437,6 @@ }, "node_modules/@electron-forge/template-vite": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/template-vite/-/template-vite-7.8.1.tgz", - "integrity": "sha512-qzSlJaBYYqQAbBdLk4DqAE3HCNz4yXbpkb+VC74ddL4JGwPdPU57DjCthr6YetKJ2FsOVy9ipovA8HX5UbXpAg==", "dev": true, "license": "MIT", "dependencies": { @@ -405,8 +450,6 @@ }, "node_modules/@electron-forge/template-vite-typescript": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/template-vite-typescript/-/template-vite-typescript-7.8.1.tgz", - "integrity": "sha512-CccQhwUjZcc6svzuOi3BtbDal591DzyX2J5GPa6mwVutDP8EMtqJL1VyOHdcWO/7XjI6GNAD0fiXySOJiUAECA==", "dev": true, "license": "MIT", "dependencies": { @@ -420,8 +463,6 @@ }, "node_modules/@electron-forge/template-webpack": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-7.8.1.tgz", - "integrity": "sha512-DA77o9kTCHrq+W211pyNP49DyAt0d1mzMp2gisyNz7a+iKvlv2DsMAeRieLoCQ44akb/z8ZsL0YLteSjKLy4AA==", "dev": true, "license": "MIT", "dependencies": { @@ -435,8 +476,6 @@ }, "node_modules/@electron-forge/template-webpack-typescript": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-7.8.1.tgz", - "integrity": "sha512-h922E+6zWwym1RT6WKD79BLTc4H8YxEMJ7wPWkBX59kw/exsTB/KFdiJq6r82ON5jSJ+Q8sDGqSmDWdyCfo+Gg==", "dev": true, "license": "MIT", "dependencies": { @@ -450,8 +489,6 @@ }, "node_modules/@electron-forge/tracer": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/tracer/-/tracer-7.8.1.tgz", - "integrity": "sha512-r2i7aHVp2fylGQSPDw3aTcdNfVX9cpL1iL2MKHrCRNwgrfR+nryGYg434T745GGm1rNQIv5Egdkh5G9xf00oWA==", "dev": true, "license": "MIT", "dependencies": { @@ -463,8 +500,6 @@ }, "node_modules/@electron/asar": { "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz", - "integrity": "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==", "dev": true, "license": "MIT", "dependencies": { @@ -481,8 +516,6 @@ }, "node_modules/@electron/asar/node_modules/commander": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true, "license": "MIT", "engines": { @@ -491,8 +524,6 @@ }, "node_modules/@electron/fuses": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@electron/fuses/-/fuses-1.8.0.tgz", - "integrity": "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==", "dev": true, "license": "MIT", "dependencies": { @@ -506,8 +537,6 @@ }, "node_modules/@electron/fuses/node_modules/fs-extra": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "license": "MIT", "dependencies": { @@ -522,8 +551,6 @@ }, "node_modules/@electron/get": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-3.1.0.tgz", - "integrity": "sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==", "dev": true, "license": "MIT", "dependencies": { @@ -544,8 +571,6 @@ }, "node_modules/@electron/get/node_modules/fs-extra": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "license": "MIT", "dependencies": { @@ -559,8 +584,6 @@ }, "node_modules/@electron/get/node_modules/jsonfile": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "license": "MIT", "optionalDependencies": { @@ -569,8 +592,6 @@ }, "node_modules/@electron/get/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -579,8 +600,6 @@ }, "node_modules/@electron/get/node_modules/universalify": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "license": "MIT", "engines": { @@ -614,8 +633,6 @@ }, "node_modules/@electron/node-gyp/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -624,9 +641,6 @@ }, "node_modules/@electron/node-gyp/node_modules/glob": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -645,8 +659,6 @@ }, "node_modules/@electron/node-gyp/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", "dependencies": { @@ -658,8 +670,6 @@ }, "node_modules/@electron/notarize": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz", - "integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==", "dev": true, "license": "MIT", "dependencies": { @@ -673,8 +683,6 @@ }, "node_modules/@electron/notarize/node_modules/fs-extra": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "license": "MIT", "dependencies": { @@ -689,8 +697,6 @@ }, "node_modules/@electron/osx-sign": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.3.tgz", - "integrity": "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -711,8 +717,6 @@ }, "node_modules/@electron/packager": { "version": "18.3.6", - "resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.3.6.tgz", - "integrity": "sha512-1eXHB5t+SQKvUiDpWGpvr90ZSSbXj+isrh3YbjCTjKT4bE4SQrKSBfukEAaBvp67+GXHFtCHjQgN9qSTFIge+Q==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -748,8 +752,6 @@ }, "node_modules/@electron/packager/node_modules/fs-extra": { "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", "dev": true, "license": "MIT", "dependencies": { @@ -761,39 +763,8 @@ "node": ">=14.14" } }, - "node_modules/@electron/rebuild": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.2.tgz", - "integrity": "sha512-19/KbIR/DAxbsCkiaGMXIdPnMCJLkcf8AvGnduJtWBs/CBwiAjY1apCqOLVxrXg+rtXFCngbXhBanWjxLUt1Mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.1.1", - "detect-libc": "^2.0.1", - "fs-extra": "^10.0.0", - "got": "^11.7.0", - "node-abi": "^3.45.0", - "node-api-version": "^0.2.0", - "ora": "^5.1.0", - "read-binary-file-arch": "^1.0.6", - "semver": "^7.3.5", - "tar": "^6.0.5", - "yargs": "^17.0.1" - }, - "bin": { - "electron-rebuild": "lib/cli.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, "node_modules/@electron/universal": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.3.tgz", - "integrity": "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==", "dev": true, "license": "MIT", "dependencies": { @@ -811,8 +782,6 @@ }, "node_modules/@electron/universal/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -821,8 +790,6 @@ }, "node_modules/@electron/universal/node_modules/fs-extra": { "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", "dev": true, "license": "MIT", "dependencies": { @@ -836,8 +803,6 @@ }, "node_modules/@electron/universal/node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -852,8 +817,6 @@ }, "node_modules/@electron/windows-sign": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz", - "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -872,8 +835,6 @@ }, "node_modules/@electron/windows-sign/node_modules/fs-extra": { "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", "dev": true, "license": "MIT", "dependencies": { @@ -887,86 +848,14 @@ }, "node_modules/@emnapi/runtime": { "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz", - "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==", "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz", - "integrity": "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.6.tgz", - "integrity": "sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.6.tgz", - "integrity": "sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.6.tgz", - "integrity": "sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.6.tgz", - "integrity": "sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==", "cpu": [ "arm64" ], @@ -980,373 +869,12 @@ "node": ">=18" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.6.tgz", - "integrity": "sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.6.tgz", - "integrity": "sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.6.tgz", - "integrity": "sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.6.tgz", - "integrity": "sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.6.tgz", - "integrity": "sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.6.tgz", - "integrity": "sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.6.tgz", - "integrity": "sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.6.tgz", - "integrity": "sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.6.tgz", - "integrity": "sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.6.tgz", - "integrity": "sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.6.tgz", - "integrity": "sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.6.tgz", - "integrity": "sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.6.tgz", - "integrity": "sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.6.tgz", - "integrity": "sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.6.tgz", - "integrity": "sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.6.tgz", - "integrity": "sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.6.tgz", - "integrity": "sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.6.tgz", - "integrity": "sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.6.tgz", - "integrity": "sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.6.tgz", - "integrity": "sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.6.tgz", - "integrity": "sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@fastify/busboy": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz", - "integrity": "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==", "license": "MIT" }, "node_modules/@firebase/ai": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-1.4.1.tgz", - "integrity": "sha512-bcusQfA/tHjUjBTnMx6jdoPMpDl3r8K15Z+snHz9wq0Foox0F/V+kNLXucEOHoTL2hTc9l+onZCyBJs2QoIC3g==", "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.3", @@ -1365,8 +893,6 @@ }, "node_modules/@firebase/analytics": { "version": "0.10.17", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.17.tgz", - "integrity": "sha512-n5vfBbvzduMou/2cqsnKrIes4auaBjdhg8QNA2ZQZ59QgtO2QiwBaXQZQE4O4sgB0Ds1tvLgUUkY+pwzu6/xEg==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1381,8 +907,6 @@ }, "node_modules/@firebase/analytics-compat": { "version": "0.2.23", - "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.23.tgz", - "integrity": "sha512-3AdO10RN18G5AzREPoFgYhW6vWXr3u+OYQv6pl3CX6Fky8QRk0AHurZlY3Q1xkXO0TDxIsdhO3y65HF7PBOJDw==", "license": "Apache-2.0", "dependencies": { "@firebase/analytics": "0.10.17", @@ -1397,14 +921,10 @@ }, "node_modules/@firebase/analytics-types": { "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", - "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", "license": "Apache-2.0" }, "node_modules/@firebase/app": { "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.2.tgz", - "integrity": "sha512-jwtMmJa1BXXDCiDx1vC6SFN/+HfYG53UkfJa6qeN5ogvOunzbFDO3wISZy5n9xgYFUrEP6M7e8EG++riHNTv9w==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1419,8 +939,6 @@ }, "node_modules/@firebase/app-check": { "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.10.1.tgz", - "integrity": "sha512-MgNdlms9Qb0oSny87pwpjKush9qUwCJhfmTJHDfrcKo4neLGiSeVE4qJkzP7EQTIUFKp84pbTxobSAXkiuQVYQ==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1437,8 +955,6 @@ }, "node_modules/@firebase/app-check-compat": { "version": "0.3.26", - "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.26.tgz", - "integrity": "sha512-PkX+XJMLDea6nmnopzFKlr+s2LMQGqdyT2DHdbx1v1dPSqOol2YzgpgymmhC67vitXVpNvS3m/AiWQWWhhRRPQ==", "license": "Apache-2.0", "dependencies": { "@firebase/app-check": "0.10.1", @@ -1457,20 +973,14 @@ }, "node_modules/@firebase/app-check-interop-types": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", - "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", "license": "Apache-2.0" }, "node_modules/@firebase/app-check-types": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", - "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", "license": "Apache-2.0" }, "node_modules/@firebase/app-compat": { "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.4.2.tgz", - "integrity": "sha512-LssbyKHlwLeiV8GBATyOyjmHcMpX/tFjzRUCS1jnwGAew1VsBB4fJowyS5Ud5LdFbYpJeS+IQoC+RQxpK7eH3Q==", "license": "Apache-2.0", "dependencies": { "@firebase/app": "0.13.2", @@ -1485,14 +995,10 @@ }, "node_modules/@firebase/app-types": { "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", "license": "Apache-2.0" }, "node_modules/@firebase/auth": { "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", - "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1515,8 +1021,6 @@ }, "node_modules/@firebase/auth-compat": { "version": "0.5.28", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.28.tgz", - "integrity": "sha512-HpMSo/cc6Y8IX7bkRIaPPqT//Jt83iWy5rmDWeThXQCAImstkdNo3giFLORJwrZw2ptiGkOij64EH1ztNJzc7Q==", "license": "Apache-2.0", "dependencies": { "@firebase/auth": "1.10.8", @@ -1534,14 +1038,10 @@ }, "node_modules/@firebase/auth-interop-types": { "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", - "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", "license": "Apache-2.0" }, "node_modules/@firebase/auth-types": { "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", - "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", @@ -1550,8 +1050,6 @@ }, "node_modules/@firebase/component": { "version": "0.6.18", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.18.tgz", - "integrity": "sha512-n28kPCkE2dL2U28fSxZJjzPPVpKsQminJ6NrzcKXAI0E/lYC8YhfwpyllScqVEvAI3J2QgJZWYgrX+1qGI+SQQ==", "license": "Apache-2.0", "dependencies": { "@firebase/util": "1.12.1", @@ -1563,8 +1061,6 @@ }, "node_modules/@firebase/data-connect": { "version": "0.3.10", - "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.10.tgz", - "integrity": "sha512-VMVk7zxIkgwlVQIWHOKFahmleIjiVFwFOjmakXPd/LDgaB/5vzwsB5DWIYo+3KhGxWpidQlR8geCIn39YflJIQ==", "license": "Apache-2.0", "dependencies": { "@firebase/auth-interop-types": "0.2.4", @@ -1579,8 +1075,6 @@ }, "node_modules/@firebase/database": { "version": "1.0.20", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.20.tgz", - "integrity": "sha512-H9Rpj1pQ1yc9+4HQOotFGLxqAXwOzCHsRSRjcQFNOr8lhUt6LeYjf0NSRL04sc4X0dWe8DsCvYKxMYvFG/iOJw==", "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.3", @@ -1597,8 +1091,6 @@ }, "node_modules/@firebase/database-compat": { "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.11.tgz", - "integrity": "sha512-itEsHARSsYS95+udF/TtIzNeQ0Uhx4uIna0sk4E0wQJBUnLc/G1X6D7oRljoOuwwCezRLGvWBRyNrugv/esOEw==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1614,8 +1106,6 @@ }, "node_modules/@firebase/database-types": { "version": "1.0.15", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.15.tgz", - "integrity": "sha512-XWHJ0VUJ0k2E9HDMlKxlgy/ZuTa9EvHCGLjaKSUvrQnwhgZuRU5N3yX6SZ+ftf2hTzZmfRkv+b3QRvGg40bKNw==", "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.9.3", @@ -1624,8 +1114,6 @@ }, "node_modules/@firebase/firestore": { "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.8.0.tgz", - "integrity": "sha512-QSRk+Q1/CaabKyqn3C32KSFiOdZpSqI9rpLK5BHPcooElumOBooPFa6YkDdiT+/KhJtel36LdAacha9BptMj2A==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1645,8 +1133,6 @@ }, "node_modules/@firebase/firestore-compat": { "version": "0.3.53", - "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.53.tgz", - "integrity": "sha512-qI3yZL8ljwAYWrTousWYbemay2YZa+udLWugjdjju2KODWtLG94DfO4NALJgPLv8CVGcDHNFXoyQexdRA0Cz8Q==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1664,8 +1150,6 @@ }, "node_modules/@firebase/firestore-types": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", - "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", @@ -1674,8 +1158,6 @@ }, "node_modules/@firebase/functions": { "version": "0.12.9", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.9.tgz", - "integrity": "sha512-FG95w6vjbUXN84Ehezc2SDjGmGq225UYbHrb/ptkRT7OTuCiQRErOQuyt1jI1tvcDekdNog+anIObihNFz79Lg==", "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.3", @@ -1694,8 +1176,6 @@ }, "node_modules/@firebase/functions-compat": { "version": "0.3.26", - "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.26.tgz", - "integrity": "sha512-A798/6ff5LcG2LTWqaGazbFYnjBW8zc65YfID/en83ALmkhu2b0G8ykvQnLtakbV9ajrMYPn7Yc/XcYsZIUsjA==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1713,14 +1193,10 @@ }, "node_modules/@firebase/functions-types": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", - "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", "license": "Apache-2.0" }, "node_modules/@firebase/installations": { "version": "0.6.18", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.18.tgz", - "integrity": "sha512-NQ86uGAcvO8nBRwVltRL9QQ4Reidc/3whdAasgeWCPIcrhOKDuNpAALa6eCVryLnK14ua2DqekCOX5uC9XbU/A==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1734,8 +1210,6 @@ }, "node_modules/@firebase/installations-compat": { "version": "0.2.18", - "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.18.tgz", - "integrity": "sha512-aLFohRpJO5kKBL/XYL4tN+GdwEB/Q6Vo9eZOM/6Kic7asSUgmSfGPpGUZO1OAaSRGwF4Lqnvi1f/f9VZnKzChw==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1750,8 +1224,6 @@ }, "node_modules/@firebase/installations-types": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", - "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x" @@ -1759,8 +1231,6 @@ }, "node_modules/@firebase/logger": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", - "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -1771,8 +1241,6 @@ }, "node_modules/@firebase/messaging": { "version": "0.12.22", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.22.tgz", - "integrity": "sha512-GJcrPLc+Hu7nk+XQ70Okt3M1u1eRr2ZvpMbzbc54oTPJZySHcX9ccZGVFcsZbSZ6o1uqumm8Oc7OFkD3Rn1/og==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1788,8 +1256,6 @@ }, "node_modules/@firebase/messaging-compat": { "version": "0.2.22", - "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.22.tgz", - "integrity": "sha512-5ZHtRnj6YO6f/QPa/KU6gryjmX4Kg33Kn4gRpNU6M1K47Gm8kcQwPkX7erRUYEH1mIWptfvjvXMHWoZaWjkU7A==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1803,14 +1269,10 @@ }, "node_modules/@firebase/messaging-interop-types": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", - "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", "license": "Apache-2.0" }, "node_modules/@firebase/performance": { "version": "0.7.7", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.7.tgz", - "integrity": "sha512-JTlTQNZKAd4+Q5sodpw6CN+6NmwbY72av3Lb6wUKTsL7rb3cuBIhQSrslWbVz0SwK3x0ZNcqX24qtRbwKiv+6w==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1826,8 +1288,6 @@ }, "node_modules/@firebase/performance-compat": { "version": "0.2.20", - "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.20.tgz", - "integrity": "sha512-XkFK5NmOKCBuqOKWeRgBUFZZGz9SzdTZp4OqeUg+5nyjapTiZ4XoiiUL8z7mB2q+63rPmBl7msv682J3rcDXIQ==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1843,14 +1303,10 @@ }, "node_modules/@firebase/performance-types": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", - "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", "license": "Apache-2.0" }, "node_modules/@firebase/remote-config": { "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.5.tgz", - "integrity": "sha512-fU0c8HY0vrVHwC+zQ/fpXSqHyDMuuuglV94VF6Yonhz8Fg2J+KOowPGANM0SZkLvVOYpTeWp3ZmM+F6NjwWLnw==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1865,8 +1321,6 @@ }, "node_modules/@firebase/remote-config-compat": { "version": "0.2.18", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.18.tgz", - "integrity": "sha512-YiETpldhDy7zUrnS8e+3l7cNs0sL7+tVAxvVYU0lu7O+qLHbmdtAxmgY+wJqWdW2c9nDvBFec7QiF58pEUu0qQ==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1882,14 +1336,10 @@ }, "node_modules/@firebase/remote-config-types": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", - "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", "license": "Apache-2.0" }, "node_modules/@firebase/storage": { "version": "0.13.14", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.14.tgz", - "integrity": "sha512-xTq5ixxORzx+bfqCpsh+o3fxOsGoDjC1nO0Mq2+KsOcny3l7beyBhP/y1u5T6mgsFQwI1j6oAkbT5cWdDBx87g==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1905,8 +1355,6 @@ }, "node_modules/@firebase/storage-compat": { "version": "0.3.24", - "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.24.tgz", - "integrity": "sha512-XHn2tLniiP7BFKJaPZ0P8YQXKiVJX+bMyE2j2YWjYfaddqiJnROJYqSomwW6L3Y+gZAga35ONXUJQju6MB6SOQ==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.18", @@ -1924,8 +1372,6 @@ }, "node_modules/@firebase/storage-types": { "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", - "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", @@ -1934,8 +1380,6 @@ }, "node_modules/@firebase/util": { "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.1.tgz", - "integrity": "sha512-zGlBn/9Dnya5ta9bX/fgEoNC3Cp8s6h+uYPYaDieZsFOAdHP/ExzQ/eaDgxD3GOROdPkLKpvKY0iIzr9adle0w==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -1947,21 +1391,15 @@ }, "node_modules/@firebase/webchannel-wrapper": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", - "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==", "license": "Apache-2.0" }, "node_modules/@gar/promisify": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", "dev": true, "license": "MIT" }, "node_modules/@google-cloud/firestore": { "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.2.tgz", - "integrity": "sha512-BQCSbjWJndCZ6bj8BSGhi4EM1TDFs9HgZXXsJ7d2kEPo+x64fB3OnQE8ffmn3vWADqeAmYBPaMPF/k6PHETXKA==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -1977,8 +1415,6 @@ }, "node_modules/@google-cloud/paginator": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", - "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -1991,8 +1427,6 @@ }, "node_modules/@google-cloud/projectify": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", - "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", "license": "Apache-2.0", "optional": true, "engines": { @@ -2001,8 +1435,6 @@ }, "node_modules/@google-cloud/promisify": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", - "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", "license": "Apache-2.0", "optional": true, "engines": { @@ -2011,8 +1443,6 @@ }, "node_modules/@google-cloud/storage": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.16.0.tgz", - "integrity": "sha512-7/5LRgykyOfQENcm6hDKP8SX/u9XxE5YOiWOkgkwcoO+cG8xT/cyOvp9wwN3IxfdYgpHs8CE7Nq2PKX2lNaEXw==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -2038,8 +1468,6 @@ }, "node_modules/@google-cloud/storage/node_modules/mime": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", "license": "MIT", "optional": true, "bin": { @@ -2051,8 +1479,6 @@ }, "node_modules/@google-cloud/storage/node_modules/uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "license": "MIT", "optional": true, "bin": { @@ -2061,8 +1487,6 @@ }, "node_modules/@google/genai": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.8.0.tgz", - "integrity": "sha512-n3KiMFesQCy2R9iSdBIuJ0JWYQ1HZBJJkmt4PPZMGZKvlgHhBAGw1kUMyX+vsAIzprN3lK45DI755lm70wPOOg==", "license": "Apache-2.0", "dependencies": { "google-auth-library": "^9.14.2", @@ -2084,8 +1508,6 @@ }, "node_modules/@google/generative-ai": { "version": "0.24.1", - "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz", - "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==", "license": "Apache-2.0", "engines": { "node": ">=18.0.0" @@ -2093,8 +1515,6 @@ }, "node_modules/@grpc/grpc-js": { "version": "1.9.15", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", - "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", "license": "Apache-2.0", "dependencies": { "@grpc/proto-loader": "^0.7.8", @@ -2106,8 +1526,6 @@ }, "node_modules/@grpc/proto-loader": { "version": "0.7.15", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", - "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", "license": "Apache-2.0", "dependencies": { "lodash.camelcase": "^4.3.0", @@ -2124,14 +1542,10 @@ }, "node_modules/@hapi/hoek": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", "license": "BSD-3-Clause" }, "node_modules/@hapi/topo": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.0.0" @@ -2139,8 +1553,6 @@ }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz", - "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==", "cpu": [ "arm64" ], @@ -2159,32 +1571,8 @@ "@img/sharp-libvips-darwin-arm64": "1.1.0" } }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz", - "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.1.0" - } - }, "node_modules/@img/sharp-libvips-darwin-arm64": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", - "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", "cpu": [ "arm64" ], @@ -2197,22 +1585,6 @@ "url": "https://opencollective.com/libvips" } }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", - "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, "node_modules/@img/sharp-libvips-linux-arm": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", @@ -2535,8 +1907,6 @@ }, "node_modules/@isaacs/balanced-match": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", "dev": true, "license": "MIT", "engines": { @@ -2545,8 +1915,6 @@ }, "node_modules/@isaacs/brace-expansion": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", "dev": true, "license": "MIT", "dependencies": { @@ -2558,8 +1926,6 @@ }, "node_modules/@isaacs/cliui": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, "license": "ISC", "dependencies": { @@ -2576,15 +1942,11 @@ }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "license": "MIT", "dependencies": { @@ -2601,8 +1963,6 @@ }, "node_modules/@js-sdsl/ordered-map": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", "license": "MIT", "optional": true, "funding": { @@ -2612,8 +1972,6 @@ }, "node_modules/@malept/cross-spawn-promise": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", - "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", "dev": true, "funding": [ { @@ -2635,8 +1993,6 @@ }, "node_modules/@malept/flatpak-bundler": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", - "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2651,8 +2007,6 @@ }, "node_modules/@malept/flatpak-bundler/node_modules/fs-extra": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2667,8 +2021,6 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "license": "MIT", "dependencies": { @@ -2681,8 +2033,6 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "license": "MIT", "engines": { @@ -2691,8 +2041,6 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "license": "MIT", "dependencies": { @@ -2705,8 +2053,6 @@ }, "node_modules/@npmcli/fs": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", - "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", "dev": true, "license": "ISC", "dependencies": { @@ -2719,9 +2065,6 @@ }, "node_modules/@npmcli/move-file": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", - "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "deprecated": "This functionality has been moved to @npmcli/fs", "dev": true, "license": "MIT", "dependencies": { @@ -2734,8 +2077,6 @@ }, "node_modules/@opentelemetry/api": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "license": "Apache-2.0", "optional": true, "engines": { @@ -2744,8 +2085,6 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, "license": "MIT", "optional": true, @@ -2755,32 +2094,22 @@ }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1", @@ -2789,38 +2118,26 @@ }, "node_modules/@protobufjs/float": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "license": "BSD-3-Clause" }, "node_modules/@sideway/address": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.0.0" @@ -2828,20 +2145,14 @@ }, "node_modules/@sideway/formula": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", "license": "BSD-3-Clause" }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", "license": "BSD-3-Clause" }, "node_modules/@sindresorhus/is": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, "license": "MIT", "engines": { @@ -2853,8 +2164,6 @@ }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, "license": "MIT", "dependencies": { @@ -2866,8 +2175,6 @@ }, "node_modules/@tootallnate/once": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "devOptional": true, "license": "MIT", "engines": { @@ -2876,8 +2183,6 @@ }, "node_modules/@types/appdmg": { "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@types/appdmg/-/appdmg-0.5.5.tgz", - "integrity": "sha512-G+n6DgZTZFOteITE30LnWj+HRVIGr7wMlAiLWOO02uJFWVEitaPU9JVXm9wJokkgshBawb2O1OykdcsmkkZfgg==", "dev": true, "license": "MIT", "optional": true, @@ -2887,8 +2192,6 @@ }, "node_modules/@types/body-parser": { "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "license": "MIT", "dependencies": { "@types/connect": "*", @@ -2897,8 +2200,6 @@ }, "node_modules/@types/cacheable-request": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "dev": true, "license": "MIT", "dependencies": { @@ -2910,15 +2211,11 @@ }, "node_modules/@types/caseless": { "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", "license": "MIT", "optional": true }, "node_modules/@types/connect": { "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -2926,8 +2223,6 @@ }, "node_modules/@types/debug": { "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2936,8 +2231,6 @@ }, "node_modules/@types/express": { "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", - "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", "license": "MIT", "dependencies": { "@types/body-parser": "*", @@ -2948,8 +2241,6 @@ }, "node_modules/@types/express-serve-static-core": { "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -2960,8 +2251,6 @@ }, "node_modules/@types/fs-extra": { "version": "9.0.13", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", - "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", "dev": true, "license": "MIT", "dependencies": { @@ -2970,21 +2259,15 @@ }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "dev": true, "license": "MIT" }, "node_modules/@types/http-errors": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", "license": "MIT" }, "node_modules/@types/jsonwebtoken": { "version": "9.0.10", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", - "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", "license": "MIT", "dependencies": { "@types/ms": "*", @@ -2993,8 +2276,6 @@ }, "node_modules/@types/keyv": { "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "dev": true, "license": "MIT", "dependencies": { @@ -3003,27 +2284,19 @@ }, "node_modules/@types/long": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", "license": "MIT", "optional": true }, "node_modules/@types/mime": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "license": "MIT" }, "node_modules/@types/ms": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, "node_modules/@types/node": { "version": "20.19.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.4.tgz", - "integrity": "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -3031,8 +2304,6 @@ }, "node_modules/@types/node-fetch": { "version": "2.6.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -3041,8 +2312,6 @@ }, "node_modules/@types/plist": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", - "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==", "dev": true, "license": "MIT", "optional": true, @@ -3053,20 +2322,14 @@ }, "node_modules/@types/qs": { "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "license": "MIT" }, "node_modules/@types/request": { "version": "2.48.12", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", - "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", "license": "MIT", "optional": true, "dependencies": { @@ -3078,8 +2341,6 @@ }, "node_modules/@types/request/node_modules/form-data": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.3.tgz", - "integrity": "sha512-XHIrMD0NpDrNM/Ckf7XJiBbLl57KEhT3+i3yY+eWm+cqYZJQTZrKo8Y8AWKnuV5GT4scfuUGt9LzNoIx3dU1nQ==", "license": "MIT", "optional": true, "dependencies": { @@ -3095,8 +2356,6 @@ }, "node_modules/@types/responselike": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", - "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", "dev": true, "license": "MIT", "dependencies": { @@ -3105,8 +2364,6 @@ }, "node_modules/@types/send": { "version": "0.17.5", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", - "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", "license": "MIT", "dependencies": { "@types/mime": "^1", @@ -3115,8 +2372,6 @@ }, "node_modules/@types/serve-static": { "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", - "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", "license": "MIT", "dependencies": { "@types/http-errors": "*", @@ -3126,23 +2381,17 @@ }, "node_modules/@types/tough-cookie": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "license": "MIT", "optional": true }, "node_modules/@types/verror": { "version": "1.10.11", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", - "integrity": "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==", "dev": true, "license": "MIT", "optional": true }, "node_modules/@types/yauzl": { "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "license": "MIT", "optional": true, @@ -3152,8 +2401,6 @@ }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", "dev": true, "license": "MIT", "engines": { @@ -3162,22 +2409,16 @@ }, "node_modules/7zip-bin": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz", - "integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==", "dev": true, "license": "MIT" }, "node_modules/abbrev": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "license": "ISC" }, "node_modules/abort-controller": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" @@ -3188,8 +2429,6 @@ }, "node_modules/accepts": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "license": "MIT", "dependencies": { "mime-types": "~2.1.34", @@ -3201,8 +2440,6 @@ }, "node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "license": "MIT", "engines": { "node": ">= 14" @@ -3210,8 +2447,6 @@ }, "node_modules/agentkeepalive": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", - "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", "license": "MIT", "dependencies": { "humanize-ms": "^1.2.1" @@ -3222,8 +2457,6 @@ }, "node_modules/aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "license": "MIT", "dependencies": { @@ -3236,8 +2469,6 @@ }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", "dependencies": { @@ -3253,8 +2484,6 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -3270,8 +2499,6 @@ }, "node_modules/ajv-formats/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -3286,14 +2513,10 @@ }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/ajv-keywords": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -3302,8 +2525,6 @@ }, "node_modules/ansi-escapes": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", - "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", "dev": true, "license": "MIT", "dependencies": { @@ -3318,8 +2539,6 @@ }, "node_modules/ansi-escapes/node_modules/type-fest": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -3331,8 +2550,6 @@ }, "node_modules/ansi-regex": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, "license": "MIT", "engines": { @@ -3344,8 +2561,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3359,8 +2574,6 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "license": "ISC", "dependencies": { @@ -3373,15 +2586,11 @@ }, "node_modules/app-builder-bin": { "version": "5.0.0-alpha.12", - "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz", - "integrity": "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==", "dev": true, "license": "MIT" }, "node_modules/app-builder-lib": { "version": "26.0.12", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.0.12.tgz", - "integrity": "sha512-+/CEPH1fVKf6HowBUs6LcAIoRcjeqgvAeoSE+cl7Y7LndyQ9ViGPYibNk7wmhMHzNgHIuIbw4nWADPO+4mjgWw==", "dev": true, "license": "MIT", "dependencies": { @@ -3429,8 +2638,6 @@ }, "node_modules/app-builder-lib/node_modules/@electron/asar": { "version": "3.2.18", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.18.tgz", - "integrity": "sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==", "dev": true, "license": "MIT", "dependencies": { @@ -3447,8 +2654,6 @@ }, "node_modules/app-builder-lib/node_modules/@electron/asar/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -3460,8 +2665,6 @@ }, "node_modules/app-builder-lib/node_modules/@electron/osx-sign": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.1.tgz", - "integrity": "sha512-BAfviURMHpmb1Yb50YbCxnOY0wfwaLXH5KJ4+80zS0gUkzDX3ec23naTlEqKsN+PwYn+a1cCzM7BJ4Wcd3sGzw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3482,8 +2685,6 @@ }, "node_modules/app-builder-lib/node_modules/@electron/osx-sign/node_modules/isbinaryfile": { "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", "dev": true, "license": "MIT", "engines": { @@ -3495,12 +2696,10 @@ }, "node_modules/app-builder-lib/node_modules/@electron/rebuild": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.0.tgz", - "integrity": "sha512-VW++CNSlZwMYP7MyXEbrKjpzEwhB5kDNbzGtiPEjwYysqyTCF+YbNJ210Dj3AjWsGSV4iEEwNkmJN9yGZmVvmw==", "dev": true, "license": "MIT", "dependencies": { - "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "@electron/node-gyp": "https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2", "@malept/cross-spawn-promise": "^2.0.0", "chalk": "^4.0.0", "debug": "^4.1.1", @@ -3524,8 +2723,6 @@ }, "node_modules/app-builder-lib/node_modules/@electron/universal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz", - "integrity": "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==", "dev": true, "license": "MIT", "dependencies": { @@ -3543,8 +2740,6 @@ }, "node_modules/app-builder-lib/node_modules/@electron/universal/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3553,8 +2748,6 @@ }, "node_modules/app-builder-lib/node_modules/@electron/universal/node_modules/fs-extra": { "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", "dev": true, "license": "MIT", "dependencies": { @@ -3568,8 +2761,6 @@ }, "node_modules/app-builder-lib/node_modules/@electron/universal/node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -3584,8 +2775,6 @@ }, "node_modules/app-builder-lib/node_modules/commander": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true, "license": "MIT", "engines": { @@ -3594,8 +2783,6 @@ }, "node_modules/app-builder-lib/node_modules/dotenv": { "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -3607,8 +2794,6 @@ }, "node_modules/app-builder-lib/node_modules/isbinaryfile": { "version": "5.0.4", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.4.tgz", - "integrity": "sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==", "dev": true, "license": "MIT", "engines": { @@ -3620,8 +2805,6 @@ }, "node_modules/app-builder-lib/node_modules/minimatch": { "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", "dev": true, "license": "ISC", "dependencies": { @@ -3636,8 +2819,6 @@ }, "node_modules/app-builder-lib/node_modules/pe-library": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz", - "integrity": "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==", "dev": true, "license": "MIT", "engines": { @@ -3651,8 +2832,6 @@ }, "node_modules/app-builder-lib/node_modules/resedit": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/resedit/-/resedit-1.7.2.tgz", - "integrity": "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==", "dev": true, "license": "MIT", "dependencies": { @@ -3669,8 +2848,6 @@ }, "node_modules/appdmg": { "version": "0.6.6", - "resolved": "https://registry.npmjs.org/appdmg/-/appdmg-0.6.6.tgz", - "integrity": "sha512-GRmFKlCG+PWbcYF4LUNonTYmy0GjguDy6Jh9WP8mpd0T6j80XIJyXBiWlD0U+MLNhqV9Nhx49Gl9GpVToulpLg==", "dev": true, "license": "MIT", "optional": true, @@ -3699,20 +2876,14 @@ }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, "node_modules/array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, "node_modules/arrify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "license": "MIT", "optional": true, "engines": { @@ -3721,8 +2892,6 @@ }, "node_modules/assert-plus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true, "license": "MIT", "optional": true, @@ -3732,8 +2901,6 @@ }, "node_modules/astral-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, "license": "MIT", "optional": true, @@ -3743,16 +2910,12 @@ }, "node_modules/async": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true, "license": "MIT", "optional": true }, "node_modules/async-exit-hook": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", - "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", "dev": true, "license": "MIT", "engines": { @@ -3761,8 +2924,6 @@ }, "node_modules/async-retry": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", "license": "MIT", "optional": true, "dependencies": { @@ -3771,14 +2932,10 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/at-least-node": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true, "license": "ISC", "engines": { @@ -3787,8 +2944,6 @@ }, "node_modules/atomically": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", - "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", "license": "MIT", "engines": { "node": ">=10.12.0" @@ -3796,8 +2951,6 @@ }, "node_modules/author-regex": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", - "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==", "dev": true, "license": "MIT", "engines": { @@ -3806,8 +2959,6 @@ }, "node_modules/axios": { "version": "1.10.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", - "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -3817,15 +2968,11 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "license": "MIT" }, "node_modules/base32-encode": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/base32-encode/-/base32-encode-1.2.0.tgz", - "integrity": "sha512-cHFU8XeRyx0GgmoWi5qHMCVRiqU6J3MHWxVgun7jggCBUpVzm1Ir7M9dYr2whjSNc3tFeXfQ/oZjQu/4u55h9A==", "dev": true, "license": "MIT", "optional": true, @@ -3835,8 +2982,6 @@ }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -3855,8 +3000,6 @@ }, "node_modules/better-sqlite3": { "version": "9.6.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.6.0.tgz", - "integrity": "sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -3866,8 +3009,6 @@ }, "node_modules/bignumber.js": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.0.tgz", - "integrity": "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==", "license": "MIT", "engines": { "node": "*" @@ -3875,8 +3016,6 @@ }, "node_modules/binary-extensions": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "license": "MIT", "engines": { @@ -3888,8 +3027,6 @@ }, "node_modules/bindings": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "license": "MIT", "dependencies": { "file-uri-to-path": "1.0.0" @@ -3897,8 +3034,6 @@ }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -3908,15 +3043,11 @@ }, "node_modules/bluebird": { "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true, "license": "MIT" }, "node_modules/body-parser": { "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -3939,8 +3070,6 @@ }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -3948,8 +3077,6 @@ }, "node_modules/body-parser/node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -3960,23 +3087,16 @@ }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/boolean": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "license": "MIT", "optional": true }, "node_modules/bplist-creator": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", - "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", "dev": true, "license": "MIT", "optional": true, @@ -3986,8 +3106,6 @@ }, "node_modules/brace-expansion": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -3997,8 +3115,6 @@ }, "node_modules/braces": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { @@ -4010,8 +3126,6 @@ }, "node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -4034,8 +3148,6 @@ }, "node_modules/buffer-crc32": { "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, "license": "MIT", "engines": { @@ -4044,21 +3156,15 @@ }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", "license": "BSD-3-Clause" }, "node_modules/buffer-from": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, "license": "MIT" }, "node_modules/builder-util": { "version": "26.0.11", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.0.11.tgz", - "integrity": "sha512-xNjXfsldUEe153h1DraD0XvDOpqGR0L5eKFkdReB7eFW5HqysDZFfly4rckda6y9dF39N3pkPlOblcfHKGw+uA==", "dev": true, "license": "MIT", "dependencies": { @@ -4083,8 +3189,6 @@ }, "node_modules/builder-util-runtime": { "version": "9.3.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.3.1.tgz", - "integrity": "sha512-2/egrNDDnRaxVwK3A+cJq6UOlqOdedGA7JPqCeJjN2Zjk1/QB/6QUi3b714ScIGS7HafFXTyzJEOr5b44I3kvQ==", "license": "MIT", "dependencies": { "debug": "^4.3.4", @@ -4096,8 +3200,6 @@ }, "node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -4105,8 +3207,6 @@ }, "node_modules/cacache": { "version": "16.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", - "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", "dev": true, "license": "ISC", "dependencies": { @@ -4135,8 +3235,6 @@ }, "node_modules/cacache/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4145,9 +3243,6 @@ }, "node_modules/cacache/node_modules/glob": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -4166,8 +3261,6 @@ }, "node_modules/cacache/node_modules/lru-cache": { "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, "license": "ISC", "engines": { @@ -4176,8 +3269,6 @@ }, "node_modules/cacache/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", "dependencies": { @@ -4189,8 +3280,6 @@ }, "node_modules/cacheable-lookup": { "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", "dev": true, "license": "MIT", "engines": { @@ -4199,8 +3288,6 @@ }, "node_modules/cacheable-request": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, "license": "MIT", "dependencies": { @@ -4218,8 +3305,6 @@ }, "node_modules/cacheable-request/node_modules/get-stream": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "license": "MIT", "dependencies": { @@ -4234,8 +3319,6 @@ }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4247,8 +3330,6 @@ }, "node_modules/call-bound": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -4263,8 +3344,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { @@ -4280,8 +3359,6 @@ }, "node_modules/chokidar": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -4305,8 +3382,6 @@ }, "node_modules/chownr": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true, "license": "ISC", "engines": { @@ -4315,8 +3390,6 @@ }, "node_modules/chrome-trace-event": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, "license": "MIT", "engines": { @@ -4325,15 +3398,11 @@ }, "node_modules/chromium-pickle-js": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", "dev": true, "license": "MIT" }, "node_modules/ci-info": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ { @@ -4348,8 +3417,6 @@ }, "node_modules/clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, "license": "MIT", "engines": { @@ -4358,8 +3425,6 @@ }, "node_modules/cli-cursor": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "dev": true, "license": "MIT", "dependencies": { @@ -4374,8 +3439,6 @@ }, "node_modules/cli-spinners": { "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, "license": "MIT", "engines": { @@ -4387,8 +3450,6 @@ }, "node_modules/cli-truncate": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, "license": "MIT", "optional": true, @@ -4405,8 +3466,6 @@ }, "node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -4419,8 +3478,6 @@ }, "node_modules/cliui/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" @@ -4428,8 +3485,6 @@ }, "node_modules/cliui/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -4440,8 +3495,6 @@ }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -4457,8 +3510,6 @@ }, "node_modules/clone": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, "license": "MIT", "engines": { @@ -4467,8 +3518,6 @@ }, "node_modules/clone-response": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", "dev": true, "license": "MIT", "dependencies": { @@ -4480,8 +3529,6 @@ }, "node_modules/color": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1", @@ -4493,8 +3540,6 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4505,14 +3550,10 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/color-string": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "license": "MIT", "dependencies": { "color-name": "^1.0.0", @@ -4521,15 +3562,11 @@ }, "node_modules/colorette": { "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true, "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -4540,8 +3577,6 @@ }, "node_modules/commander": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, "license": "MIT", "engines": { @@ -4550,8 +3585,6 @@ }, "node_modules/compare-version": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", "dev": true, "license": "MIT", "engines": { @@ -4560,15 +3593,11 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "license": "MIT" }, "node_modules/conf": { "version": "10.2.0", - "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", - "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", "license": "MIT", "dependencies": { "ajv": "^8.6.3", @@ -4591,8 +3620,6 @@ }, "node_modules/conf/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -4607,14 +3634,10 @@ }, "node_modules/conf/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/config-file-ts": { "version": "0.2.8-rc1", - "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.8-rc1.tgz", - "integrity": "sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==", "dev": true, "license": "MIT", "dependencies": { @@ -4624,8 +3647,6 @@ }, "node_modules/config-file-ts/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4634,8 +3655,6 @@ }, "node_modules/config-file-ts/node_modules/glob": { "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "license": "ISC", "dependencies": { @@ -4655,8 +3674,6 @@ }, "node_modules/config-file-ts/node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -4671,8 +3688,6 @@ }, "node_modules/config-file-ts/node_modules/minipass": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "license": "ISC", "engines": { @@ -4681,8 +3696,6 @@ }, "node_modules/content-disposition": { "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -4693,8 +3706,6 @@ }, "node_modules/content-type": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -4702,8 +3713,6 @@ }, "node_modules/cookie": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -4711,22 +3720,16 @@ }, "node_modules/cookie-signature": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", "dev": true, "license": "MIT", "optional": true }, "node_modules/cors": { "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -4738,8 +3741,6 @@ }, "node_modules/crc": { "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", "dev": true, "license": "MIT", "optional": true, @@ -4749,15 +3750,11 @@ }, "node_modules/cross-dirname": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/cross-dirname/-/cross-dirname-0.1.0.tgz", - "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==", "dev": true, "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -4771,8 +3768,6 @@ }, "node_modules/cross-zip": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-4.0.1.tgz", - "integrity": "sha512-n63i0lZ0rvQ6FXiGQ+/JFCKAUyPFhLQYJIqKaa+tSJtfKeULF/IDNDAbdnSIxgS4NTuw2b0+lj8LzfITuq+ZxQ==", "dev": true, "funding": [ { @@ -4795,14 +3790,10 @@ }, "node_modules/csstype": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, "node_modules/date-time": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", - "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", "dev": true, "license": "MIT", "dependencies": { @@ -4814,8 +3805,6 @@ }, "node_modules/debounce-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", - "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", "license": "MIT", "dependencies": { "mimic-fn": "^3.0.0" @@ -4829,8 +3818,6 @@ }, "node_modules/debug": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -4846,8 +3833,6 @@ }, "node_modules/decompress-response": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" @@ -4861,8 +3846,6 @@ }, "node_modules/decompress-response/node_modules/mimic-response": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "license": "MIT", "engines": { "node": ">=10" @@ -4873,8 +3856,6 @@ }, "node_modules/deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "license": "MIT", "engines": { "node": ">=4.0.0" @@ -4882,8 +3863,6 @@ }, "node_modules/defaults": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, "license": "MIT", "dependencies": { @@ -4895,8 +3874,6 @@ }, "node_modules/defer-to-connect": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", "dev": true, "license": "MIT", "engines": { @@ -4905,8 +3882,6 @@ }, "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "license": "MIT", "optional": true, @@ -4924,8 +3899,6 @@ }, "node_modules/define-properties": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "license": "MIT", "optional": true, @@ -4943,8 +3916,6 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -4952,8 +3923,6 @@ }, "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -4961,8 +3930,6 @@ }, "node_modules/destroy": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "license": "MIT", "engines": { "node": ">= 0.8", @@ -4971,8 +3938,6 @@ }, "node_modules/detect-libc": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", "license": "Apache-2.0", "engines": { "node": ">=8" @@ -4980,16 +3945,12 @@ }, "node_modules/detect-node": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true, "license": "MIT", "optional": true }, "node_modules/dir-compare": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz", - "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4999,8 +3960,6 @@ }, "node_modules/dmg-builder": { "version": "26.0.12", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.0.12.tgz", - "integrity": "sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w==", "dev": true, "license": "MIT", "dependencies": { @@ -5017,8 +3976,6 @@ }, "node_modules/dmg-license": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", - "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", "dev": true, "license": "MIT", "optional": true, @@ -5044,8 +4001,6 @@ }, "node_modules/dot-prop": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", "license": "MIT", "dependencies": { "is-obj": "^2.0.0" @@ -5059,8 +4014,6 @@ }, "node_modules/dotenv": { "version": "17.0.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.0.1.tgz", - "integrity": "sha512-GLjkduuAL7IMJg/ZnOPm9AnWKJ82mSE2tzXLaJ/6hD6DhwGfZaXG77oB8qbReyiczNxnbxQKyh0OE5mXq0bAHA==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -5071,8 +4024,6 @@ }, "node_modules/dotenv-expand": { "version": "11.0.7", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", - "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5087,8 +4038,6 @@ }, "node_modules/dotenv-expand/node_modules/dotenv": { "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -5100,8 +4049,6 @@ }, "node_modules/ds-store": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ds-store/-/ds-store-0.1.6.tgz", - "integrity": "sha512-kY21M6Lz+76OS3bnCzjdsJSF7LBpLYGCVfavW8TgQD2XkcqIZ86W0y9qUDZu6fp7SIZzqosMDW2zi7zVFfv4hw==", "dev": true, "license": "MIT", "optional": true, @@ -5113,8 +4060,6 @@ }, "node_modules/dunder-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -5127,8 +4072,6 @@ }, "node_modules/duplexify": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", - "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", "license": "MIT", "optional": true, "dependencies": { @@ -5140,15 +4083,11 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true, "license": "MIT" }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -5156,14 +4095,10 @@ }, "node_modules/ee-first": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, "node_modules/ejs": { "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5178,8 +4113,6 @@ }, "node_modules/electron": { "version": "30.5.1", - "resolved": "https://registry.npmjs.org/electron/-/electron-30.5.1.tgz", - "integrity": "sha512-AhL7+mZ8Lg14iaNfoYTkXQ2qee8mmsQyllKdqxlpv/zrKgfxz6jNVtcRRbQtLxtF8yzcImWdfTQROpYiPumdbw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5197,8 +4130,6 @@ }, "node_modules/electron-builder": { "version": "26.0.12", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.0.12.tgz", - "integrity": "sha512-cD1kz5g2sgPTMFHjLxfMjUK5JABq3//J4jPswi93tOPFz6btzXYtK5NrDt717NRbukCUDOrrvmYVOWERlqoiXA==", "dev": true, "license": "MIT", "dependencies": { @@ -5223,8 +4154,6 @@ }, "node_modules/electron-builder-squirrel-windows": { "version": "26.0.12", - "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.0.12.tgz", - "integrity": "sha512-kpwXM7c/ayRUbYVErQbsZ0nQZX4aLHQrPEG9C4h9vuJCXylwFH8a7Jgi2VpKIObzCXO7LKHiCw4KdioFLFOgqA==", "dev": true, "license": "MIT", "peer": true, @@ -5236,8 +4165,6 @@ }, "node_modules/electron-installer-common": { "version": "0.10.4", - "resolved": "https://registry.npmjs.org/electron-installer-common/-/electron-installer-common-0.10.4.tgz", - "integrity": "sha512-8gMNPXfAqUE5CfXg8RL0vXpLE9HAaPkgLXVoHE3BMUzogMWenf4LmwQ27BdCUrEhkjrKl+igs2IHJibclR3z3Q==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -5264,8 +4191,6 @@ }, "node_modules/electron-installer-common/node_modules/@malept/cross-spawn-promise": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", "dev": true, "funding": [ { @@ -5288,8 +4213,6 @@ }, "node_modules/electron-installer-common/node_modules/fs-extra": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "license": "MIT", "optional": true, @@ -5305,8 +4228,6 @@ }, "node_modules/electron-installer-debian": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/electron-installer-debian/-/electron-installer-debian-3.2.0.tgz", - "integrity": "sha512-58ZrlJ1HQY80VucsEIG9tQ//HrTlG6sfofA3nRGr6TmkX661uJyu4cMPPh6kXW+aHdq/7+q25KyQhDrXvRL7jw==", "dev": true, "license": "MIT", "optional": true, @@ -5333,8 +4254,6 @@ }, "node_modules/electron-installer-debian/node_modules/@malept/cross-spawn-promise": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", "dev": true, "funding": [ { @@ -5357,8 +4276,6 @@ }, "node_modules/electron-installer-debian/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "optional": true, @@ -5368,8 +4285,6 @@ }, "node_modules/electron-installer-debian/node_modules/cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "license": "ISC", "optional": true, @@ -5381,8 +4296,6 @@ }, "node_modules/electron-installer-debian/node_modules/fs-extra": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "license": "MIT", "optional": true, @@ -5398,8 +4311,6 @@ }, "node_modules/electron-installer-debian/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "optional": true, @@ -5412,8 +4323,6 @@ }, "node_modules/electron-installer-debian/node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "optional": true, @@ -5431,8 +4340,6 @@ }, "node_modules/electron-installer-debian/node_modules/yargs": { "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "license": "MIT", "optional": true, @@ -5451,8 +4358,6 @@ }, "node_modules/electron-installer-debian/node_modules/yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "license": "ISC", "optional": true, @@ -5462,8 +4367,6 @@ }, "node_modules/electron-installer-dmg": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/electron-installer-dmg/-/electron-installer-dmg-5.0.1.tgz", - "integrity": "sha512-qOa1aAQdX57C+vzhDk3549dd/PRlNL4F8y736MTD1a43qptD+PvHY97Bo9gSf+OZ8iUWE7BrYSpk/FgLUe40EA==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -5484,8 +4387,6 @@ }, "node_modules/electron-installer-redhat": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/electron-installer-redhat/-/electron-installer-redhat-3.4.0.tgz", - "integrity": "sha512-gEISr3U32Sgtj+fjxUAlSDo3wyGGq6OBx7rF5UdpIgbnpUvMN4W5uYb0ThpnAZ42VEJh/3aODQXHbFS4f5J3Iw==", "dev": true, "license": "MIT", "optional": true, @@ -5511,8 +4412,6 @@ }, "node_modules/electron-installer-redhat/node_modules/@malept/cross-spawn-promise": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", "dev": true, "funding": [ { @@ -5535,8 +4434,6 @@ }, "node_modules/electron-installer-redhat/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "optional": true, @@ -5546,8 +4443,6 @@ }, "node_modules/electron-installer-redhat/node_modules/cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "license": "ISC", "optional": true, @@ -5559,8 +4454,6 @@ }, "node_modules/electron-installer-redhat/node_modules/fs-extra": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "license": "MIT", "optional": true, @@ -5576,8 +4469,6 @@ }, "node_modules/electron-installer-redhat/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "optional": true, @@ -5590,8 +4481,6 @@ }, "node_modules/electron-installer-redhat/node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "optional": true, @@ -5609,8 +4498,6 @@ }, "node_modules/electron-installer-redhat/node_modules/yargs": { "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "license": "MIT", "optional": true, @@ -5629,8 +4516,6 @@ }, "node_modules/electron-installer-redhat/node_modules/yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "license": "ISC", "optional": true, @@ -5640,8 +4525,6 @@ }, "node_modules/electron-is-dev": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz", - "integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==", "dev": true, "license": "MIT" }, @@ -5668,8 +4551,6 @@ }, "node_modules/electron-publish": { "version": "26.0.11", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.0.11.tgz", - "integrity": "sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==", "dev": true, "license": "MIT", "dependencies": { @@ -5685,8 +4566,6 @@ }, "node_modules/electron-reloader": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/electron-reloader/-/electron-reloader-1.2.3.tgz", - "integrity": "sha512-aDnACAzNg0QvQhzw7LYOx/nVS10mEtbuG6M0QQvNQcLnJEwFs6is+EGRCnM+KQlQ4KcTbdwnt07nd7ZjHpY4iw==", "dev": true, "license": "MIT", "dependencies": { @@ -5702,8 +4581,6 @@ }, "node_modules/electron-squirrel-startup": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/electron-squirrel-startup/-/electron-squirrel-startup-1.0.1.tgz", - "integrity": "sha512-sTfFIHGku+7PsHLJ7v0dRcZNkALrV+YEozINTW8X1nM//e5O3L+rfYuvSW00lmGHnYmUjARZulD8F2V8ISI9RA==", "license": "Apache-2.0", "dependencies": { "debug": "^2.2.0" @@ -5711,8 +4588,6 @@ }, "node_modules/electron-squirrel-startup/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -5720,14 +4595,10 @@ }, "node_modules/electron-squirrel-startup/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/electron-store": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.2.0.tgz", - "integrity": "sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw==", "license": "MIT", "dependencies": { "conf": "^10.2.0", @@ -5739,8 +4610,6 @@ }, "node_modules/electron-updater": { "version": "6.6.2", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.6.2.tgz", - "integrity": "sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw==", "license": "MIT", "dependencies": { "builder-util-runtime": "9.3.1", @@ -5755,8 +4624,6 @@ }, "node_modules/electron-winstaller": { "version": "5.4.0", - "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.4.0.tgz", - "integrity": "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5776,8 +4643,6 @@ }, "node_modules/electron-winstaller/node_modules/fs-extra": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, "license": "MIT", "dependencies": { @@ -5791,8 +4656,6 @@ }, "node_modules/electron-winstaller/node_modules/jsonfile": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "license": "MIT", "optionalDependencies": { @@ -5801,8 +4664,6 @@ }, "node_modules/electron-winstaller/node_modules/universalify": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "license": "MIT", "engines": { @@ -5811,8 +4672,6 @@ }, "node_modules/electron/node_modules/@electron/get": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", - "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5833,8 +4692,6 @@ }, "node_modules/electron/node_modules/fs-extra": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "license": "MIT", "dependencies": { @@ -5848,8 +4705,6 @@ }, "node_modules/electron/node_modules/jsonfile": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "license": "MIT", "optionalDependencies": { @@ -5858,8 +4713,6 @@ }, "node_modules/electron/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -5868,8 +4721,6 @@ }, "node_modules/electron/node_modules/universalify": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "license": "MIT", "engines": { @@ -5878,22 +4729,16 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/encode-utf8": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", "dev": true, "license": "MIT", "optional": true }, "node_modules/encodeurl": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -5901,8 +4746,6 @@ }, "node_modules/encoding": { "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "license": "MIT", "optional": true, "dependencies": { @@ -5911,8 +4754,6 @@ }, "node_modules/end-of-stream": { "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "license": "MIT", "dependencies": { "once": "^1.4.0" @@ -5920,8 +4761,6 @@ }, "node_modules/env-paths": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "license": "MIT", "engines": { "node": ">=6" @@ -5929,15 +4768,11 @@ }, "node_modules/err-code": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", "dev": true, "license": "MIT" }, "node_modules/error-ex": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "license": "MIT", "dependencies": { @@ -5946,8 +4781,6 @@ }, "node_modules/es-define-property": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -5955,8 +4788,6 @@ }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -5964,8 +4795,6 @@ }, "node_modules/es-object-atoms": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -5976,8 +4805,6 @@ }, "node_modules/es-set-tostringtag": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -5991,16 +4818,12 @@ }, "node_modules/es6-error": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true, "license": "MIT", "optional": true }, "node_modules/esbuild": { "version": "0.25.6", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz", - "integrity": "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -6041,8 +4864,6 @@ }, "node_modules/escalade": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { "node": ">=6" @@ -6050,14 +4871,10 @@ }, "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "optional": true, @@ -6070,8 +4887,6 @@ }, "node_modules/etag": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -6079,8 +4894,6 @@ }, "node_modules/event-target-shim": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", "engines": { "node": ">=6" @@ -6088,15 +4901,11 @@ }, "node_modules/eventemitter3": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "dev": true, "license": "MIT" }, "node_modules/execa": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "license": "MIT", "dependencies": { @@ -6114,8 +4923,6 @@ }, "node_modules/execa/node_modules/cross-spawn": { "version": "6.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "dev": true, "license": "MIT", "dependencies": { @@ -6131,8 +4938,6 @@ }, "node_modules/execa/node_modules/path-key": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true, "license": "MIT", "engines": { @@ -6141,8 +4946,6 @@ }, "node_modules/execa/node_modules/semver": { "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "license": "ISC", "bin": { @@ -6151,8 +4954,6 @@ }, "node_modules/execa/node_modules/shebang-command": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, "license": "MIT", "dependencies": { @@ -6164,8 +4965,6 @@ }, "node_modules/execa/node_modules/shebang-regex": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true, "license": "MIT", "engines": { @@ -6174,8 +4973,6 @@ }, "node_modules/execa/node_modules/which": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "license": "ISC", "dependencies": { @@ -6187,8 +4984,6 @@ }, "node_modules/expand-template": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "license": "(MIT OR WTFPL)", "engines": { "node": ">=6" @@ -6196,15 +4991,11 @@ }, "node_modules/exponential-backoff": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", - "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", "dev": true, "license": "Apache-2.0" }, "node_modules/express": { "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -6249,8 +5040,6 @@ }, "node_modules/express/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -6258,20 +5047,14 @@ }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/extend": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, "node_modules/extract-zip": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -6291,8 +5074,6 @@ }, "node_modules/extract-zip/node_modules/get-stream": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "license": "MIT", "dependencies": { @@ -6307,8 +5088,6 @@ }, "node_modules/extsprintf": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", - "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", "dev": true, "engines": [ "node >=0.6.0" @@ -6318,8 +5097,6 @@ }, "node_modules/farmhash-modern": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", - "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -6327,14 +5104,10 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { @@ -6350,15 +5123,11 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, "node_modules/fast-uri": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", "funding": [ { "type": "github", @@ -6373,8 +5142,6 @@ }, "node_modules/fast-xml-parser": { "version": "4.5.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", - "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", "funding": [ { "type": "github", @@ -6392,8 +5159,6 @@ }, "node_modules/fastq": { "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, "license": "ISC", "dependencies": { @@ -6402,8 +5167,6 @@ }, "node_modules/faye-websocket": { "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" @@ -6414,8 +5177,6 @@ }, "node_modules/fd-slicer": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, "license": "MIT", "dependencies": { @@ -6424,14 +5185,10 @@ }, "node_modules/file-uri-to-path": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "license": "MIT" }, "node_modules/filelist": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -6440,8 +5197,6 @@ }, "node_modules/filelist/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6450,8 +5205,6 @@ }, "node_modules/filelist/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", "dependencies": { @@ -6463,8 +5216,6 @@ }, "node_modules/filename-reserved-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", "dev": true, "license": "MIT", "engines": { @@ -6473,8 +5224,6 @@ }, "node_modules/filenamify": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", "dev": true, "license": "MIT", "dependencies": { @@ -6491,8 +5240,6 @@ }, "node_modules/fill-range": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { @@ -6504,8 +5251,6 @@ }, "node_modules/finalhandler": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -6522,8 +5267,6 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -6531,14 +5274,10 @@ }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { @@ -6554,8 +5293,6 @@ }, "node_modules/firebase": { "version": "11.10.0", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.10.0.tgz", - "integrity": "sha512-nKBXoDzF0DrXTBQJlZa+sbC5By99ysYU1D6PkMRYknm0nCW7rJly47q492Ht7Ndz5MeYSBuboKuhS1e6mFC03w==", "license": "Apache-2.0", "dependencies": { "@firebase/ai": "1.4.1", @@ -6590,8 +5327,6 @@ }, "node_modules/firebase-admin": { "version": "13.4.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.4.0.tgz", - "integrity": "sha512-Y8DcyKK+4pl4B93ooiy1G8qvdyRMkcNFfBSh+8rbVcw4cW8dgG0VXCCTp5NUwub8sn9vSPsOwpb9tE2OuFmcfQ==", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -6615,8 +5350,6 @@ }, "node_modules/firebase-admin/node_modules/@types/node": { "version": "22.16.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.0.tgz", - "integrity": "sha512-B2egV9wALML1JCpv3VQoQ+yesQKAmNMBIAY7OteVrikcOcAkWm+dGL6qpeCktPjAv6N1JLnhbNiqS35UpFyBsQ==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -6624,8 +5357,6 @@ }, "node_modules/flora-colossus": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-2.0.0.tgz", - "integrity": "sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA==", "dev": true, "license": "MIT", "dependencies": { @@ -6638,8 +5369,6 @@ }, "node_modules/fmix": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", - "integrity": "sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==", "dev": true, "license": "MIT", "optional": true, @@ -6649,8 +5378,6 @@ }, "node_modules/follow-redirects": { "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", @@ -6669,8 +5396,6 @@ }, "node_modules/foreground-child": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, "license": "ISC", "dependencies": { @@ -6686,8 +5411,6 @@ }, "node_modules/foreground-child/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "license": "ISC", "engines": { @@ -6699,8 +5422,6 @@ }, "node_modules/form-data": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -6715,14 +5436,10 @@ }, "node_modules/form-data-encoder": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", - "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", "license": "MIT" }, "node_modules/formdata-node": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", - "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", "license": "MIT", "dependencies": { "node-domexception": "1.0.0", @@ -6734,8 +5451,6 @@ }, "node_modules/forwarded": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -6743,8 +5458,6 @@ }, "node_modules/fresh": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -6752,14 +5465,10 @@ }, "node_modules/fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "license": "MIT" }, "node_modules/fs-extra": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -6772,8 +5481,6 @@ }, "node_modules/fs-minipass": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, "license": "ISC", "dependencies": { @@ -6785,8 +5492,6 @@ }, "node_modules/fs-temp": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-1.2.1.tgz", - "integrity": "sha512-okTwLB7/Qsq82G6iN5zZJFsOfZtx2/pqrA7Hk/9fvy+c+eJS9CvgGXT2uNxwnI14BDY9L/jQPkaBgSvlKfSW9w==", "dev": true, "license": "MIT", "optional": true, @@ -6796,10 +5501,7 @@ }, "node_modules/fs-xattr": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/fs-xattr/-/fs-xattr-0.3.1.tgz", - "integrity": "sha512-UVqkrEW0GfDabw4C3HOrFlxKfx0eeigfRne69FxSBdHIP8Qt5Sq6Pu3RM9KmMlkygtC4pPKkj5CiPO5USnj2GA==", "dev": true, - "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -6811,30 +5513,11 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, "license": "ISC" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6842,15 +5525,11 @@ }, "node_modules/functional-red-black-tree": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "license": "MIT", "optional": true }, "node_modules/galactus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/galactus/-/galactus-1.0.0.tgz", - "integrity": "sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6864,17 +5543,12 @@ }, "node_modules/gar": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/gar/-/gar-1.0.4.tgz", - "integrity": "sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "license": "MIT", "optional": true }, "node_modules/gaxios": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", - "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", @@ -6889,8 +5563,6 @@ }, "node_modules/gaxios/node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", "engines": { "node": ">=8" @@ -6901,8 +5573,6 @@ }, "node_modules/gaxios/node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -6914,8 +5584,6 @@ }, "node_modules/gcp-metadata": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", - "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", "license": "Apache-2.0", "dependencies": { "gaxios": "^6.1.1", @@ -6928,8 +5596,6 @@ }, "node_modules/generate-function": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", "dev": true, "license": "MIT", "optional": true, @@ -6939,8 +5605,6 @@ }, "node_modules/generate-object-property": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", "dev": true, "license": "MIT", "optional": true, @@ -6950,8 +5614,6 @@ }, "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -6959,8 +5621,6 @@ }, "node_modules/get-folder-size": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-2.0.1.tgz", - "integrity": "sha512-+CEb+GDCM7tkOS2wdMKTn9vU7DgnKUTuDlehkNJKNSovdCOVxs14OfKCk4cvSaR3za4gj+OBdl9opPN9xrJ0zA==", "dev": true, "license": "MIT", "optional": true, @@ -6974,8 +5634,6 @@ }, "node_modules/get-intrinsic": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -6998,8 +5656,6 @@ }, "node_modules/get-package-info": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", - "integrity": "sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==", "dev": true, "license": "MIT", "dependencies": { @@ -7014,8 +5670,6 @@ }, "node_modules/get-package-info/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "license": "MIT", "dependencies": { @@ -7024,15 +5678,11 @@ }, "node_modules/get-package-info/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, "license": "MIT" }, "node_modules/get-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -7044,8 +5694,6 @@ }, "node_modules/get-stream": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "license": "MIT", "dependencies": { @@ -7057,15 +5705,10 @@ }, "node_modules/github-from-package": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "license": "MIT" }, "node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -7085,8 +5728,6 @@ }, "node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "license": "ISC", "dependencies": { @@ -7098,8 +5739,6 @@ }, "node_modules/global-agent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", "dev": true, "license": "BSD-3-Clause", "optional": true, @@ -7117,8 +5756,6 @@ }, "node_modules/global-dirs": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", "dev": true, "license": "MIT", "dependencies": { @@ -7133,8 +5770,6 @@ }, "node_modules/globalthis": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "license": "MIT", "optional": true, @@ -7151,8 +5786,6 @@ }, "node_modules/goober": { "version": "2.1.16", - "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", - "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", "license": "MIT", "peerDependencies": { "csstype": "^3.0.10" @@ -7160,8 +5793,6 @@ }, "node_modules/google-auth-library": { "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -7177,8 +5808,6 @@ }, "node_modules/google-gax": { "version": "4.6.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.6.1.tgz", - "integrity": "sha512-V6eky/xz2mcKfAd1Ioxyd6nmA61gao3n01C+YeuIwu3vzM9EDR6wcVzMSIbLMDXWeoi9SHYctXuKYC5uJUT3eQ==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -7201,8 +5830,6 @@ }, "node_modules/google-gax/node_modules/@grpc/grpc-js": { "version": "1.13.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.4.tgz", - "integrity": "sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -7215,8 +5842,6 @@ }, "node_modules/google-gax/node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -7229,8 +5854,6 @@ }, "node_modules/google-logging-utils": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", - "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -7238,8 +5861,6 @@ }, "node_modules/gopd": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -7250,8 +5871,6 @@ }, "node_modules/got": { "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "dev": true, "license": "MIT", "dependencies": { @@ -7276,14 +5895,10 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, "node_modules/gtoken": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", "license": "MIT", "dependencies": { "gaxios": "^6.0.0", @@ -7295,8 +5910,6 @@ }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { @@ -7305,8 +5918,6 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "license": "MIT", "optional": true, @@ -7319,8 +5930,6 @@ }, "node_modules/has-symbols": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -7331,8 +5940,6 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -7346,8 +5953,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -7358,8 +5963,6 @@ }, "node_modules/hosted-git-info": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, "license": "ISC", "dependencies": { @@ -7371,8 +5974,6 @@ }, "node_modules/html-entities": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", - "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", "funding": [ { "type": "github", @@ -7388,15 +5989,11 @@ }, "node_modules/http-cache-semantics": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", "dev": true, "license": "BSD-2-Clause" }, "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "license": "MIT", "dependencies": { "depd": "2.0.0", @@ -7411,14 +6008,10 @@ }, "node_modules/http-parser-js": { "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", "license": "MIT" }, "node_modules/http-proxy-agent": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "license": "MIT", "dependencies": { @@ -7431,8 +6024,6 @@ }, "node_modules/http2-wrapper": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "dev": true, "license": "MIT", "dependencies": { @@ -7445,8 +6036,6 @@ }, "node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", "dependencies": { "agent-base": "^7.1.2", @@ -7458,8 +6047,6 @@ }, "node_modules/humanize-ms": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "license": "MIT", "dependencies": { "ms": "^2.0.0" @@ -7467,8 +6054,6 @@ }, "node_modules/iconv-corefoundation": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", - "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", "dev": true, "license": "MIT", "optional": true, @@ -7485,16 +6070,12 @@ }, "node_modules/iconv-corefoundation/node_modules/node-addon-api": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", "dev": true, "license": "MIT", "optional": true }, "node_modules/iconv-lite": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -7506,14 +6087,10 @@ }, "node_modules/idb": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", "license": "ISC" }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -7532,8 +6109,6 @@ }, "node_modules/image-size": { "version": "0.7.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz", - "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==", "dev": true, "license": "MIT", "optional": true, @@ -7546,8 +6121,6 @@ }, "node_modules/imul": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", - "integrity": "sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==", "dev": true, "license": "MIT", "optional": true, @@ -7557,8 +6130,6 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { @@ -7567,8 +6138,6 @@ }, "node_modules/indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, "license": "MIT", "engines": { @@ -7577,16 +6146,11 @@ }, "node_modules/infer-owner": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", "dev": true, "license": "ISC" }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "license": "ISC", "dependencies": { @@ -7596,14 +6160,10 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/ini": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true, "license": "ISC", "engines": { @@ -7612,8 +6172,6 @@ }, "node_modules/interpret": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, "license": "MIT", "engines": { @@ -7622,8 +6180,6 @@ }, "node_modules/ip-address": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "dev": true, "license": "MIT", "dependencies": { @@ -7636,8 +6192,6 @@ }, "node_modules/ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -7645,15 +6199,11 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true, "license": "MIT" }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "license": "MIT", "dependencies": { @@ -7665,8 +6215,6 @@ }, "node_modules/is-ci": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7678,8 +6226,6 @@ }, "node_modules/is-core-module": { "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { @@ -7694,8 +6240,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { @@ -7704,8 +6248,6 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { "node": ">=8" @@ -7713,8 +6255,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { @@ -7726,8 +6266,6 @@ }, "node_modules/is-interactive": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, "license": "MIT", "engines": { @@ -7736,23 +6274,17 @@ }, "node_modules/is-lambda": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", "dev": true, "license": "MIT" }, "node_modules/is-my-ip-valid": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz", - "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==", "dev": true, "license": "MIT", "optional": true }, "node_modules/is-my-json-valid": { "version": "2.20.6", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", - "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", "dev": true, "license": "MIT", "optional": true, @@ -7766,8 +6298,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", "engines": { @@ -7776,8 +6306,6 @@ }, "node_modules/is-obj": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "license": "MIT", "engines": { "node": ">=8" @@ -7785,16 +6313,12 @@ }, "node_modules/is-property": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", "dev": true, "license": "MIT", "optional": true }, "node_modules/is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true, "license": "MIT", "engines": { @@ -7803,8 +6327,6 @@ }, "node_modules/is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "license": "MIT", "engines": { @@ -7816,8 +6338,6 @@ }, "node_modules/isbinaryfile": { "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", "dev": true, "license": "MIT", "engines": { @@ -7829,15 +6349,11 @@ }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, "node_modules/jackspeak": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -7852,8 +6368,6 @@ }, "node_modules/jake": { "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -7871,15 +6385,11 @@ }, "node_modules/jake/node_modules/async": { "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true, "license": "MIT" }, "node_modules/jiti": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", "dev": true, "license": "MIT", "bin": { @@ -7888,8 +6398,6 @@ }, "node_modules/joi": { "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.3.0", @@ -7901,8 +6409,6 @@ }, "node_modules/jose": { "version": "4.15.9", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", - "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -7910,8 +6416,6 @@ }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -7922,15 +6426,11 @@ }, "node_modules/jsbn": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", "dev": true, "license": "MIT" }, "node_modules/json-bigint": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" @@ -7938,36 +6438,26 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/json-schema-typed": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", - "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==", "license": "BSD-2-Clause" }, "node_modules/json-stringify-safe": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true, "license": "ISC", "optional": true }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", "bin": { @@ -7979,8 +6469,6 @@ }, "node_modules/jsonfile": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -7991,8 +6479,6 @@ }, "node_modules/jsonpointer": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true, "license": "MIT", "optional": true, @@ -8002,8 +6488,6 @@ }, "node_modules/jsonwebtoken": { "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "license": "MIT", "dependencies": { "jws": "^3.2.2", @@ -8024,8 +6508,6 @@ }, "node_modules/jsonwebtoken/node_modules/jwa": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", - "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", "license": "MIT", "dependencies": { "buffer-equal-constant-time": "^1.0.1", @@ -8035,8 +6517,6 @@ }, "node_modules/jsonwebtoken/node_modules/jws": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", "license": "MIT", "dependencies": { "jwa": "^1.4.1", @@ -8045,8 +6525,6 @@ }, "node_modules/junk": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", - "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", "dev": true, "license": "MIT", "engines": { @@ -8055,8 +6533,6 @@ }, "node_modules/jwa": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", "license": "MIT", "dependencies": { "buffer-equal-constant-time": "^1.0.1", @@ -8066,8 +6542,6 @@ }, "node_modules/jwks-rsa": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", - "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", "license": "MIT", "dependencies": { "@types/express": "^4.17.20", @@ -8083,8 +6557,6 @@ }, "node_modules/jws": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", "license": "MIT", "dependencies": { "jwa": "^2.0.0", @@ -8110,8 +6582,6 @@ }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", "dependencies": { @@ -8120,19 +6590,13 @@ }, "node_modules/lazy-val": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", - "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", "license": "MIT" }, "node_modules/limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + "version": "1.1.5" }, "node_modules/listr2": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz", - "integrity": "sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==", "dev": true, "license": "MIT", "dependencies": { @@ -8149,8 +6613,6 @@ }, "node_modules/listr2/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "license": "MIT", "engines": { @@ -8162,8 +6624,6 @@ }, "node_modules/listr2/node_modules/cli-truncate": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", "dev": true, "license": "MIT", "dependencies": { @@ -8179,15 +6639,11 @@ }, "node_modules/listr2/node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, "license": "MIT" }, "node_modules/listr2/node_modules/is-fullwidth-code-point": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, "license": "MIT", "engines": { @@ -8199,8 +6655,6 @@ }, "node_modules/listr2/node_modules/slice-ansi": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8216,8 +6670,6 @@ }, "node_modules/listr2/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "license": "MIT", "dependencies": { @@ -8234,8 +6686,6 @@ }, "node_modules/load-json-file": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8250,8 +6700,6 @@ }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { @@ -8266,89 +6714,59 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, "node_modules/lodash.camelcase": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "license": "MIT" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", "license": "MIT" }, "node_modules/lodash.escaperegexp": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", "license": "MIT" }, "node_modules/lodash.get": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", "dev": true, "license": "MIT" }, "node_modules/lodash.includes": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", "license": "MIT" }, "node_modules/lodash.isboolean": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", "license": "MIT" }, "node_modules/lodash.isequal": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", "license": "MIT" }, "node_modules/lodash.isinteger": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", "license": "MIT" }, "node_modules/lodash.isnumber": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", "license": "MIT" }, "node_modules/lodash.isstring": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", "license": "MIT" }, "node_modules/lodash.once": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "license": "MIT", "dependencies": { @@ -8364,8 +6782,6 @@ }, "node_modules/log-update": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", - "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", "dev": true, "license": "MIT", "dependencies": { @@ -8384,8 +6800,6 @@ }, "node_modules/log-update/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "license": "MIT", "engines": { @@ -8397,8 +6811,6 @@ }, "node_modules/log-update/node_modules/is-fullwidth-code-point": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, "license": "MIT", "engines": { @@ -8410,8 +6822,6 @@ }, "node_modules/log-update/node_modules/slice-ansi": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8427,14 +6837,10 @@ }, "node_modules/long": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", "license": "Apache-2.0" }, "node_modules/lowercase-keys": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true, "license": "MIT", "engines": { @@ -8443,8 +6849,6 @@ }, "node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -8455,8 +6859,6 @@ }, "node_modules/lru-memoizer": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", - "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", "license": "MIT", "dependencies": { "lodash.clonedeep": "^4.5.0", @@ -8465,10 +6867,7 @@ }, "node_modules/macos-alias": { "version": "0.2.12", - "resolved": "https://registry.npmjs.org/macos-alias/-/macos-alias-0.2.12.tgz", - "integrity": "sha512-yiLHa7cfJcGRFq4FrR4tMlpNHb4Vy4mWnpajlSSIFM5k4Lv8/7BbbDLzCAVogWNl0LlLhizRp1drXv0hK9h0Yw==", "dev": true, - "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -8480,8 +6879,6 @@ }, "node_modules/make-fetch-happen": { "version": "10.2.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", - "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", "dev": true, "license": "ISC", "dependencies": { @@ -8508,8 +6905,6 @@ }, "node_modules/make-fetch-happen/node_modules/agent-base": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8521,8 +6916,6 @@ }, "node_modules/make-fetch-happen/node_modules/http-proxy-agent": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, "license": "MIT", "dependencies": { @@ -8536,8 +6929,6 @@ }, "node_modules/make-fetch-happen/node_modules/https-proxy-agent": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "license": "MIT", "dependencies": { @@ -8550,8 +6941,6 @@ }, "node_modules/make-fetch-happen/node_modules/lru-cache": { "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, "license": "ISC", "engines": { @@ -8560,8 +6949,6 @@ }, "node_modules/map-age-cleaner": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dev": true, "license": "MIT", "dependencies": { @@ -8573,8 +6960,6 @@ }, "node_modules/matcher": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", "dev": true, "license": "MIT", "optional": true, @@ -8587,8 +6972,6 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -8596,8 +6979,6 @@ }, "node_modules/media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -8605,8 +6986,6 @@ }, "node_modules/mem": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "dev": true, "license": "MIT", "dependencies": { @@ -8620,8 +6999,6 @@ }, "node_modules/mem/node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, "license": "MIT", "engines": { @@ -8630,8 +7007,6 @@ }, "node_modules/merge-descriptors": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8639,8 +7014,6 @@ }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "license": "MIT", "engines": { @@ -8649,8 +7022,6 @@ }, "node_modules/methods": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -8658,8 +7029,6 @@ }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -8672,8 +7041,6 @@ }, "node_modules/mime": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, "license": "MIT", "bin": { @@ -8685,8 +7052,6 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -8694,8 +7059,6 @@ }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -8706,8 +7069,6 @@ }, "node_modules/mimic-fn": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", "license": "MIT", "engines": { "node": ">=8" @@ -8715,8 +7076,6 @@ }, "node_modules/mimic-response": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true, "license": "MIT", "engines": { @@ -8725,8 +7084,6 @@ }, "node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -8738,8 +7095,6 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8747,8 +7102,6 @@ }, "node_modules/minipass": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, "license": "ISC", "dependencies": { @@ -8760,8 +7113,6 @@ }, "node_modules/minipass-collect": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", "dev": true, "license": "ISC", "dependencies": { @@ -8773,8 +7124,6 @@ }, "node_modules/minipass-fetch": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", - "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", "dev": true, "license": "MIT", "dependencies": { @@ -8791,8 +7140,6 @@ }, "node_modules/minipass-flush": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "dev": true, "license": "ISC", "dependencies": { @@ -8804,8 +7151,6 @@ }, "node_modules/minipass-pipeline": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "dev": true, "license": "ISC", "dependencies": { @@ -8817,8 +7162,6 @@ }, "node_modules/minipass-sized": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", "dev": true, "license": "ISC", "dependencies": { @@ -8830,8 +7173,6 @@ }, "node_modules/minizlib": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, "license": "MIT", "dependencies": { @@ -8844,8 +7185,6 @@ }, "node_modules/mkdirp": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, "license": "MIT", "bin": { @@ -8857,20 +7196,14 @@ }, "node_modules/mkdirp-classic": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "license": "MIT" }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/murmur-32": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/murmur-32/-/murmur-32-0.2.0.tgz", - "integrity": "sha512-ZkcWZudylwF+ir3Ld1n7gL6bI2mQAzXvSobPwVtu8aYi2sbXeipeSkdcanRLzIofLcM5F53lGaKm2dk7orBi7Q==", "dev": true, "license": "MIT", "optional": true, @@ -8882,22 +7215,16 @@ }, "node_modules/nan": { "version": "2.22.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", - "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==", "dev": true, "license": "MIT", "optional": true }, "node_modules/napi-build-utils": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -8905,15 +7232,11 @@ }, "node_modules/nice-try": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true, "license": "MIT" }, "node_modules/node-abi": { "version": "3.75.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", - "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", "license": "MIT", "dependencies": { "semver": "^7.3.5" @@ -8934,8 +7257,6 @@ }, "node_modules/node-api-version": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.1.tgz", - "integrity": "sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -8944,9 +7265,6 @@ }, "node_modules/node-domexception": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", "funding": [ { "type": "github", @@ -8964,8 +7282,6 @@ }, "node_modules/node-fetch": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -8984,8 +7300,6 @@ }, "node_modules/node-forge": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" @@ -8993,8 +7307,6 @@ }, "node_modules/node-gyp-build": { "version": "4.8.4", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", - "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "license": "MIT", "optional": true, "bin": { @@ -9005,8 +7317,6 @@ }, "node_modules/nopt": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", "dev": true, "license": "ISC", "dependencies": { @@ -9021,8 +7331,6 @@ }, "node_modules/normalize-package-data": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -9034,15 +7342,11 @@ }, "node_modules/normalize-package-data/node_modules/hosted-git-info": { "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true, "license": "ISC" }, "node_modules/normalize-package-data/node_modules/semver": { "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "license": "ISC", "bin": { @@ -9051,8 +7355,6 @@ }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "license": "MIT", "engines": { @@ -9061,8 +7363,6 @@ }, "node_modules/normalize-url": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true, "license": "MIT", "engines": { @@ -9074,8 +7374,6 @@ }, "node_modules/npm-run-path": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", "dev": true, "license": "MIT", "dependencies": { @@ -9087,8 +7385,6 @@ }, "node_modules/npm-run-path/node_modules/path-key": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true, "license": "MIT", "engines": { @@ -9097,8 +7393,6 @@ }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -9106,8 +7400,6 @@ }, "node_modules/object-hash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "license": "MIT", "optional": true, "engines": { @@ -9116,8 +7408,6 @@ }, "node_modules/object-inspect": { "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -9128,8 +7418,6 @@ }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "license": "MIT", "optional": true, @@ -9139,8 +7427,6 @@ }, "node_modules/on-finished": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -9151,8 +7437,6 @@ }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { "wrappy": "1" @@ -9160,8 +7444,6 @@ }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -9175,8 +7457,6 @@ }, "node_modules/onetime/node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "license": "MIT", "engines": { "node": ">=6" @@ -9184,8 +7464,6 @@ }, "node_modules/openai": { "version": "4.104.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz", - "integrity": "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==", "license": "Apache-2.0", "dependencies": { "@types/node": "^18.11.18", @@ -9214,8 +7492,6 @@ }, "node_modules/openai/node_modules/@types/node": { "version": "18.19.115", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.115.tgz", - "integrity": "sha512-kNrFiTgG4a9JAn1LMQeLOv3MvXIPokzXziohMrMsvpYgLpdEt/mMiVYc4sGKtDfyxM5gIDF4VgrPRyCw4fHOYg==", "license": "MIT", "dependencies": { "undici-types": "~5.26.4" @@ -9223,14 +7499,10 @@ }, "node_modules/openai/node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "license": "MIT" }, "node_modules/ora": { "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9253,8 +7525,6 @@ }, "node_modules/ora/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -9263,8 +7533,6 @@ }, "node_modules/ora/node_modules/cli-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "license": "MIT", "dependencies": { @@ -9276,8 +7544,6 @@ }, "node_modules/ora/node_modules/restore-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "license": "MIT", "dependencies": { @@ -9290,8 +7556,6 @@ }, "node_modules/ora/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -9303,8 +7567,6 @@ }, "node_modules/p-cancelable": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "dev": true, "license": "MIT", "engines": { @@ -9313,8 +7575,6 @@ }, "node_modules/p-defer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", "dev": true, "license": "MIT", "engines": { @@ -9323,8 +7583,6 @@ }, "node_modules/p-finally": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "dev": true, "license": "MIT", "engines": { @@ -9333,8 +7591,6 @@ }, "node_modules/p-is-promise": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", "dev": true, "license": "MIT", "engines": { @@ -9343,8 +7599,6 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -9359,8 +7613,6 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -9375,8 +7627,6 @@ }, "node_modules/p-map": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9391,8 +7641,6 @@ }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "license": "MIT", "engines": { "node": ">=6" @@ -9400,15 +7648,11 @@ }, "node_modules/package-json-from-dist": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/parse-author": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", - "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==", "dev": true, "license": "MIT", "dependencies": { @@ -9420,8 +7664,6 @@ }, "node_modules/parse-color": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", - "integrity": "sha512-fuDHYgFHJGbpGMgw9skY/bj3HL/Jrn4l/5rSspy00DoT4RyLnDcRvPxdZ+r6OFwIsgAuhDh4I09tAId4mI12bw==", "dev": true, "license": "MIT", "optional": true, @@ -9431,15 +7673,11 @@ }, "node_modules/parse-color/node_modules/color-convert": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", - "integrity": "sha512-RwBeO/B/vZR3dfKL1ye/vx8MHZ40ugzpyfeVG5GsiuGnrlMWe2o8wxBbLCpw9CsxV+wHuzYlCiWnybrIA0ling==", "dev": true, "optional": true }, "node_modules/parse-json": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9451,8 +7689,6 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -9460,8 +7696,6 @@ }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { @@ -9470,8 +7704,6 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "license": "MIT", "engines": { @@ -9480,8 +7712,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { @@ -9490,15 +7720,11 @@ }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true, "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -9514,15 +7740,11 @@ }, "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, "license": "ISC" }, "node_modules/path-scurry/node_modules/minipass": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "license": "ISC", "engines": { @@ -9531,14 +7753,10 @@ }, "node_modules/path-to-regexp": { "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, "node_modules/path-type": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9550,8 +7768,6 @@ }, "node_modules/pe-library": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-1.0.1.tgz", - "integrity": "sha512-nh39Mo1eGWmZS7y+mK/dQIqg7S1lp38DpRxkyoHf0ZcUs/HDc+yyTjuOtTvSMZHmfSLuSQaX945u05Y2Q6UWZg==", "dev": true, "license": "MIT", "engines": { @@ -9565,15 +7781,11 @@ }, "node_modules/pend": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true, "license": "MIT" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { @@ -9585,8 +7797,6 @@ }, "node_modules/pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, "license": "MIT", "engines": { @@ -9595,8 +7805,6 @@ }, "node_modules/pkg-up": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "license": "MIT", "dependencies": { "find-up": "^3.0.0" @@ -9607,8 +7815,6 @@ }, "node_modules/pkg-up/node_modules/find-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "license": "MIT", "dependencies": { "locate-path": "^3.0.0" @@ -9619,8 +7825,6 @@ }, "node_modules/pkg-up/node_modules/locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "license": "MIT", "dependencies": { "p-locate": "^3.0.0", @@ -9632,8 +7836,6 @@ }, "node_modules/pkg-up/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -9647,8 +7849,6 @@ }, "node_modules/pkg-up/node_modules/p-locate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "license": "MIT", "dependencies": { "p-limit": "^2.0.0" @@ -9659,8 +7859,6 @@ }, "node_modules/pkg-up/node_modules/path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "license": "MIT", "engines": { "node": ">=4" @@ -9668,8 +7866,6 @@ }, "node_modules/plist": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", - "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9683,8 +7879,6 @@ }, "node_modules/postject": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", - "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", "dev": true, "license": "MIT", "dependencies": { @@ -9699,8 +7893,6 @@ }, "node_modules/postject/node_modules/commander": { "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, "license": "MIT", "engines": { @@ -9709,8 +7901,6 @@ }, "node_modules/prebuild-install": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", "license": "MIT", "dependencies": { "detect-libc": "^2.0.0", @@ -9735,8 +7925,6 @@ }, "node_modules/proc-log": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", - "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", "dev": true, "license": "ISC", "engines": { @@ -9745,8 +7933,6 @@ }, "node_modules/progress": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, "license": "MIT", "engines": { @@ -9755,15 +7941,11 @@ }, "node_modules/promise-inflight": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", "dev": true, "license": "ISC" }, "node_modules/promise-retry": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", "dev": true, "license": "MIT", "dependencies": { @@ -9776,8 +7958,6 @@ }, "node_modules/promise-retry/node_modules/retry": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, "license": "MIT", "engines": { @@ -9786,8 +7966,6 @@ }, "node_modules/proto3-json-serializer": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", - "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -9799,8 +7977,6 @@ }, "node_modules/protobufjs": { "version": "7.5.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", - "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { @@ -9823,8 +7999,6 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -9836,14 +8010,10 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, "node_modules/pump": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -9852,8 +8022,6 @@ }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { @@ -9862,8 +8030,6 @@ }, "node_modules/qs": { "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" @@ -9877,8 +8043,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -9898,8 +8062,6 @@ }, "node_modules/quick-lru": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true, "license": "MIT", "engines": { @@ -9911,8 +8073,6 @@ }, "node_modules/random-path": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/random-path/-/random-path-0.1.2.tgz", - "integrity": "sha512-4jY0yoEaQ5v9StCl5kZbNIQlg1QheIDBrdkDn53EynpPb9FgO6//p3X/tgMnrC45XN6QZCzU1Xz/+pSSsJBpRw==", "dev": true, "license": "MIT", "optional": true, @@ -9923,8 +8083,6 @@ }, "node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -9932,8 +8090,6 @@ }, "node_modules/raw-body": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -9947,8 +8103,6 @@ }, "node_modules/raw-body/node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -9959,8 +8113,6 @@ }, "node_modules/rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", @@ -9974,14 +8126,10 @@ }, "node_modules/rc/node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "license": "ISC" }, "node_modules/react": { "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "license": "MIT", "peer": true, "engines": { @@ -9990,8 +8138,6 @@ }, "node_modules/react-dom": { "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", "license": "MIT", "peer": true, "dependencies": { @@ -10003,8 +8149,6 @@ }, "node_modules/react-hot-toast": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.2.tgz", - "integrity": "sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==", "license": "MIT", "dependencies": { "csstype": "^3.1.3", @@ -10020,8 +8164,6 @@ }, "node_modules/read-binary-file-arch": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz", - "integrity": "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==", "dev": true, "license": "MIT", "dependencies": { @@ -10033,8 +8175,6 @@ }, "node_modules/read-pkg": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", "dev": true, "license": "MIT", "dependencies": { @@ -10048,8 +8188,6 @@ }, "node_modules/read-pkg-up": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", "dev": true, "license": "MIT", "dependencies": { @@ -10062,8 +8200,6 @@ }, "node_modules/read-pkg-up/node_modules/find-up": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10075,8 +8211,6 @@ }, "node_modules/read-pkg-up/node_modules/locate-path": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "license": "MIT", "dependencies": { @@ -10089,8 +8223,6 @@ }, "node_modules/read-pkg-up/node_modules/p-limit": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "license": "MIT", "dependencies": { @@ -10102,8 +8234,6 @@ }, "node_modules/read-pkg-up/node_modules/p-locate": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, "license": "MIT", "dependencies": { @@ -10115,8 +8245,6 @@ }, "node_modules/read-pkg-up/node_modules/p-try": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true, "license": "MIT", "engines": { @@ -10125,8 +8253,6 @@ }, "node_modules/read-pkg-up/node_modules/path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, "license": "MIT", "engines": { @@ -10135,8 +8261,6 @@ }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -10149,8 +8273,6 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", "dependencies": { @@ -10162,8 +8284,6 @@ }, "node_modules/rechoir": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10175,8 +8295,6 @@ }, "node_modules/repeat-string": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "dev": true, "license": "MIT", "optional": true, @@ -10186,8 +8304,6 @@ }, "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10195,8 +8311,6 @@ }, "node_modules/require-from-string": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10204,8 +8318,6 @@ }, "node_modules/resedit": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resedit/-/resedit-2.0.3.tgz", - "integrity": "sha512-oTeemxwoMuxxTYxXUwjkrOPfngTQehlv0/HoYFNkB4uzsP1Un1A9nI8JQKGOFkxpqkC7qkMs0lUsGrvUlbLNUA==", "dev": true, "license": "MIT", "dependencies": { @@ -10222,8 +8334,6 @@ }, "node_modules/resolve": { "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "license": "MIT", "dependencies": { @@ -10243,15 +8353,11 @@ }, "node_modules/resolve-alpn": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", "dev": true, "license": "MIT" }, "node_modules/responselike": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dev": true, "license": "MIT", "dependencies": { @@ -10263,8 +8369,6 @@ }, "node_modules/restore-cursor": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, "license": "MIT", "dependencies": { @@ -10280,8 +8384,6 @@ }, "node_modules/retry": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "license": "MIT", "optional": true, "engines": { @@ -10290,8 +8392,6 @@ }, "node_modules/retry-request": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", "license": "MIT", "optional": true, "dependencies": { @@ -10305,8 +8405,6 @@ }, "node_modules/reusify": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { @@ -10316,16 +8414,11 @@ }, "node_modules/rfdc": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true, "license": "MIT" }, "node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -10340,8 +8433,6 @@ }, "node_modules/roarr": { "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", "dev": true, "license": "BSD-3-Clause", "optional": true, @@ -10359,8 +8450,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -10383,8 +8472,6 @@ }, "node_modules/rxjs": { "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -10392,8 +8479,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -10412,14 +8497,10 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, "node_modules/sanitize-filename": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", - "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", "dev": true, "license": "WTFPL OR ISC", "dependencies": { @@ -10428,21 +8509,15 @@ }, "node_modules/sax": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", "license": "ISC" }, "node_modules/scheduler": { "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", "license": "MIT", "peer": true }, "node_modules/semver": { "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -10453,16 +8528,12 @@ }, "node_modules/semver-compare": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", "dev": true, "license": "MIT", "optional": true }, "node_modules/send": { "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -10485,8 +8556,6 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -10494,14 +8563,10 @@ }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -10509,8 +8574,6 @@ }, "node_modules/send/node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "license": "MIT", "bin": { "mime": "cli.js" @@ -10521,8 +8584,6 @@ }, "node_modules/serialize-error": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", "dev": true, "license": "MIT", "optional": true, @@ -10538,8 +8599,6 @@ }, "node_modules/serialize-error/node_modules/type-fest": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true, "license": "(MIT OR CC0-1.0)", "optional": true, @@ -10552,8 +8611,6 @@ }, "node_modules/serve-static": { "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", @@ -10567,14 +8624,10 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, "node_modules/sharp": { "version": "0.34.2", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", - "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -10612,10 +8665,46 @@ "@img/sharp-win32-x64": "0.34.2" } }, + "node_modules/sharp/node_modules/@img/sharp-darwin-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz", + "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.1.0" + } + }, + "node_modules/sharp/node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", + "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", "dependencies": { @@ -10627,8 +8716,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", "engines": { @@ -10637,8 +8724,6 @@ }, "node_modules/side-channel": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -10656,8 +8741,6 @@ }, "node_modules/side-channel-list": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -10672,8 +8755,6 @@ }, "node_modules/side-channel-map": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -10690,8 +8771,6 @@ }, "node_modules/side-channel-weakmap": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -10709,15 +8788,11 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, "license": "ISC" }, "node_modules/simple-concat": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "funding": [ { "type": "github", @@ -10736,8 +8811,6 @@ }, "node_modules/simple-get": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "funding": [ { "type": "github", @@ -10761,8 +8834,6 @@ }, "node_modules/simple-swizzle": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "license": "MIT", "dependencies": { "is-arrayish": "^0.3.1" @@ -10770,14 +8841,10 @@ }, "node_modules/simple-swizzle/node_modules/is-arrayish": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", "license": "MIT" }, "node_modules/simple-update-notifier": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", "dev": true, "license": "MIT", "dependencies": { @@ -10789,8 +8856,6 @@ }, "node_modules/slice-ansi": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, "license": "MIT", "optional": true, @@ -10805,8 +8870,6 @@ }, "node_modules/smart-buffer": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, "license": "MIT", "engines": { @@ -10816,8 +8879,6 @@ }, "node_modules/socks": { "version": "2.8.5", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", - "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", "dev": true, "license": "MIT", "dependencies": { @@ -10831,8 +8892,6 @@ }, "node_modules/socks-proxy-agent": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", "dev": true, "license": "MIT", "dependencies": { @@ -10846,8 +8905,6 @@ }, "node_modules/socks-proxy-agent/node_modules/agent-base": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10859,8 +8916,6 @@ }, "node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -10869,8 +8924,6 @@ }, "node_modules/source-map-support": { "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "license": "MIT", "dependencies": { @@ -10880,8 +8933,6 @@ }, "node_modules/spdx-correct": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -10891,15 +8942,11 @@ }, "node_modules/spdx-exceptions": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true, "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -10909,22 +8956,16 @@ }, "node_modules/spdx-license-ids": { "version": "3.0.21", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", - "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", "dev": true, "license": "CC0-1.0" }, "node_modules/sprintf-js": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/ssri": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", "dev": true, "license": "ISC", "dependencies": { @@ -10936,8 +8977,6 @@ }, "node_modules/stat-mode": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", - "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", "dev": true, "license": "MIT", "engines": { @@ -10946,8 +8985,6 @@ }, "node_modules/statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -10955,8 +8992,6 @@ }, "node_modules/stream-buffers": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", - "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", "dev": true, "license": "Unlicense", "optional": true, @@ -10966,8 +9001,6 @@ }, "node_modules/stream-events": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", "license": "MIT", "optional": true, "dependencies": { @@ -10976,15 +9009,11 @@ }, "node_modules/stream-shift": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", "license": "MIT", "optional": true }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -10992,8 +9021,6 @@ }, "node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -11007,8 +9034,6 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { @@ -11022,8 +9047,6 @@ }, "node_modules/string-width-cjs/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -11032,8 +9055,6 @@ }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -11045,8 +9066,6 @@ }, "node_modules/string-width/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" @@ -11054,8 +9073,6 @@ }, "node_modules/string-width/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -11066,8 +9083,6 @@ }, "node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11083,8 +9098,6 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -11096,8 +9109,6 @@ }, "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -11106,8 +9117,6 @@ }, "node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, "license": "MIT", "engines": { @@ -11116,8 +9125,6 @@ }, "node_modules/strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", "dev": true, "license": "MIT", "engines": { @@ -11126,8 +9133,6 @@ }, "node_modules/strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11135,8 +9140,6 @@ }, "node_modules/strip-outer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", "dev": true, "license": "MIT", "dependencies": { @@ -11148,8 +9151,6 @@ }, "node_modules/strip-outer/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "license": "MIT", "engines": { @@ -11158,8 +9159,6 @@ }, "node_modules/strnum": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", - "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", "funding": [ { "type": "github", @@ -11171,23 +9170,16 @@ }, "node_modules/stubs": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", "license": "MIT", "optional": true }, "node_modules/sudo-prompt": { "version": "9.2.1", - "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", - "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "license": "MIT" }, "node_modules/sumchecker": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11199,8 +9191,6 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { @@ -11212,8 +9202,6 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, "license": "MIT", "engines": { @@ -11225,8 +9213,6 @@ }, "node_modules/tar": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, "license": "ISC", "dependencies": { @@ -11243,8 +9229,6 @@ }, "node_modules/tar-fs": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", - "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", "license": "MIT", "dependencies": { "chownr": "^1.1.1", @@ -11255,14 +9239,10 @@ }, "node_modules/tar-fs/node_modules/chownr": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "license": "ISC" }, "node_modules/tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "license": "MIT", "dependencies": { "bl": "^4.0.3", @@ -11277,8 +9257,6 @@ }, "node_modules/tar/node_modules/minipass": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, "license": "ISC", "engines": { @@ -11287,8 +9265,6 @@ }, "node_modules/teeny-request": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -11304,8 +9280,6 @@ }, "node_modules/teeny-request/node_modules/agent-base": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "license": "MIT", "optional": true, "dependencies": { @@ -11317,8 +9291,6 @@ }, "node_modules/teeny-request/node_modules/http-proxy-agent": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "license": "MIT", "optional": true, "dependencies": { @@ -11332,8 +9304,6 @@ }, "node_modules/teeny-request/node_modules/https-proxy-agent": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "license": "MIT", "optional": true, "dependencies": { @@ -11346,8 +9316,6 @@ }, "node_modules/teeny-request/node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -11360,8 +9328,6 @@ }, "node_modules/temp": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", - "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", "dev": true, "license": "MIT", "dependencies": { @@ -11374,8 +9340,6 @@ }, "node_modules/temp-file": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", - "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", "dev": true, "license": "MIT", "dependencies": { @@ -11385,8 +9349,6 @@ }, "node_modules/temp/node_modules/mkdirp": { "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "license": "MIT", "dependencies": { @@ -11398,9 +9360,6 @@ }, "node_modules/temp/node_modules/rimraf": { "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -11412,8 +9371,6 @@ }, "node_modules/time-zone": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", - "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", "dev": true, "license": "MIT", "engines": { @@ -11422,8 +9379,6 @@ }, "node_modules/tiny-async-pool": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-1.3.0.tgz", - "integrity": "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==", "dev": true, "license": "MIT", "dependencies": { @@ -11432,8 +9387,6 @@ }, "node_modules/tiny-async-pool/node_modules/semver": { "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "license": "ISC", "bin": { @@ -11442,22 +9395,16 @@ }, "node_modules/tiny-each-async": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tiny-each-async/-/tiny-each-async-2.0.3.tgz", - "integrity": "sha512-5ROII7nElnAirvFn8g7H7MtpfV1daMcyfTGQwsn/x2VtyV+VPiO5CjReCJtWLvoKTDEDmZocf3cNPraiMnBXLA==", "dev": true, "license": "MIT", "optional": true }, "node_modules/tiny-typed-emitter": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", - "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==", "license": "MIT" }, "node_modules/tmp": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, "license": "MIT", "engines": { @@ -11466,8 +9413,6 @@ }, "node_modules/tmp-promise": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", - "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11476,8 +9421,6 @@ }, "node_modules/tn1150": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/tn1150/-/tn1150-0.1.0.tgz", - "integrity": "sha512-DbplOfQFkqG5IHcDyyrs/lkvSr3mPUVsFf/RbDppOshs22yTPnSJWEe6FkYd1txAwU/zcnR905ar2fi4kwF29w==", "dev": true, "license": "MIT", "optional": true, @@ -11490,16 +9433,12 @@ }, "node_modules/to-data-view": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", - "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", "dev": true, "license": "MIT", "optional": true }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11511,8 +9450,6 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", "engines": { "node": ">=0.6" @@ -11520,14 +9457,10 @@ }, "node_modules/tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, "node_modules/trim-repeated": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", "dev": true, "license": "MIT", "dependencies": { @@ -11539,8 +9472,6 @@ }, "node_modules/trim-repeated/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "license": "MIT", "engines": { @@ -11549,8 +9480,6 @@ }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", "dev": true, "license": "WTFPL", "dependencies": { @@ -11559,14 +9488,10 @@ }, "node_modules/tslib": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/tunnel-agent": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -11577,8 +9502,6 @@ }, "node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" @@ -11589,8 +9512,6 @@ }, "node_modules/type-is": { "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "license": "MIT", "dependencies": { "media-typer": "0.3.0", @@ -11602,8 +9523,6 @@ }, "node_modules/typescript": { "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -11616,14 +9535,10 @@ }, "node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, "node_modules/unique-filename": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", - "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", "dev": true, "license": "ISC", "dependencies": { @@ -11635,8 +9550,6 @@ }, "node_modules/unique-slug": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", - "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", "dev": true, "license": "ISC", "dependencies": { @@ -11648,8 +9561,6 @@ }, "node_modules/universalify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -11657,8 +9568,6 @@ }, "node_modules/unorm": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", - "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", "dev": true, "license": "MIT or GPL-2.0", "optional": true, @@ -11668,8 +9577,6 @@ }, "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -11677,8 +9584,6 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -11687,8 +9592,6 @@ }, "node_modules/username": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz", - "integrity": "sha512-PCKbdWw85JsYMvmCv5GH3kXmM66rCd9m1hBEDutPNv94b/pqCMT4NtcKyeWYvLFiE8b+ha1Jdl8XAaUdPn5QTg==", "dev": true, "license": "MIT", "dependencies": { @@ -11701,21 +9604,15 @@ }, "node_modules/utf8-byte-length": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", - "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", "dev": true, "license": "(WTFPL OR MIT)" }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "license": "MIT", "engines": { "node": ">= 0.4.0" @@ -11723,8 +9620,6 @@ }, "node_modules/uuid": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -11736,8 +9631,6 @@ }, "node_modules/validate-npm-package-license": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11747,8 +9640,6 @@ }, "node_modules/validator": { "version": "13.15.15", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz", - "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -11756,8 +9647,6 @@ }, "node_modules/vary": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -11765,8 +9654,6 @@ }, "node_modules/verror": { "version": "1.10.1", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", - "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", "dev": true, "license": "MIT", "optional": true, @@ -11781,8 +9668,6 @@ }, "node_modules/wait-on": { "version": "8.0.3", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.3.tgz", - "integrity": "sha512-nQFqAFzZDeRxsu7S3C7LbuxslHhk+gnJZHyethuGKAn2IVleIbTB9I3vJSQiSR+DifUqmdzfPMoMPJfLqMF2vw==", "license": "MIT", "dependencies": { "axios": "^1.8.2", @@ -11800,8 +9685,6 @@ }, "node_modules/wcwidth": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, "license": "MIT", "dependencies": { @@ -11810,8 +9693,6 @@ }, "node_modules/web-streams-polyfill": { "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", "license": "MIT", "engines": { "node": ">= 14" @@ -11819,20 +9700,14 @@ }, "node_modules/web-vitals": { "version": "4.2.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", - "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", "license": "Apache-2.0" }, "node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, "node_modules/websocket-driver": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", @@ -11845,8 +9720,6 @@ }, "node_modules/websocket-extensions": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "license": "Apache-2.0", "engines": { "node": ">=0.8.0" @@ -11854,8 +9727,6 @@ }, "node_modules/whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "license": "MIT", "dependencies": { "tr46": "~0.0.3", @@ -11864,8 +9735,6 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { @@ -11880,8 +9749,6 @@ }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", "optional": true, @@ -11891,8 +9758,6 @@ }, "node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11910,8 +9775,6 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { @@ -11928,8 +9791,6 @@ }, "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -11938,8 +9799,6 @@ }, "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -11951,8 +9810,6 @@ }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "license": "MIT", "engines": { @@ -11964,15 +9821,11 @@ }, "node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, "license": "MIT" }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "license": "MIT", "dependencies": { @@ -11989,14 +9842,10 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, "node_modules/ws": { "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -12016,8 +9865,6 @@ }, "node_modules/xmlbuilder": { "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "dev": true, "license": "MIT", "engines": { @@ -12026,8 +9873,6 @@ }, "node_modules/xtend": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, "license": "MIT", "optional": true, @@ -12037,8 +9882,6 @@ }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "license": "ISC", "engines": { "node": ">=10" @@ -12046,14 +9889,10 @@ }, "node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -12070,8 +9909,6 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "license": "ISC", "engines": { "node": ">=12" @@ -12079,8 +9916,6 @@ }, "node_modules/yauzl": { "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, "license": "MIT", "dependencies": { @@ -12090,8 +9925,6 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "devOptional": true, "license": "MIT", "engines": { @@ -12103,8 +9936,6 @@ }, "node_modules/zod": { "version": "3.25.75", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.75.tgz", - "integrity": "sha512-OhpzAmVzabPOL6C3A3gpAifqr9MqihV/Msx3gor2b2kviCgcb+HM9SEOpMWwwNp9MRunWnhtAKUoo0AHhjyPPg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -12112,8 +9943,6 @@ }, "node_modules/zod-to-json-schema": { "version": "3.24.6", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", - "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", "license": "ISC", "peerDependencies": { "zod": "^3.24.1" diff --git a/package.json b/package.json index e84cb27..c2e8594 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "pickle-glass", "productName": "Glass", - "version": "0.2.3", + "version": "0.2.4", "description": "Cl*ely for Free", "main": "src/index.js", @@ -76,4 +76,4 @@ "optionalDependencies": { "electron-liquid-glass": "^1.0.1" } -} +} \ No newline at end of file diff --git a/src/app/ApiKeyHeader.js b/src/app/ApiKeyHeader.js index 92962c8..4f1a3b3 100644 --- a/src/app/ApiKeyHeader.js +++ b/src/app/ApiKeyHeader.js @@ -1,4 +1,5 @@ import { html, css, LitElement } from "../assets/lit-core-2.7.4.min.js" +import { getOllamaProgressTracker } from "../common/services/localProgressTracker.js" export class ApiKeyHeader extends LitElement { //////// after_modelStateService //////// @@ -9,7 +10,16 @@ export class ApiKeyHeader extends LitElement { sttProvider: { type: String }, isLoading: { type: Boolean }, errorMessage: { type: String }, + successMessage: { type: String }, providers: { type: Object, state: true }, + modelSuggestions: { type: Array, state: true }, + userModelHistory: { type: Array, state: true }, + selectedLlmModel: { type: String, state: true }, + selectedSttModel: { type: String, state: true }, + ollamaStatus: { type: Object, state: true }, + installingModel: { type: String, state: true }, + installProgress: { type: Number, state: true }, + whisperInstallingModels: { type: Object, state: true }, } //////// after_modelStateService //////// @@ -132,6 +142,29 @@ export class ApiKeyHeader extends LitElement { height: 14px; text-align: center; margin-bottom: 4px; + opacity: 1; + transition: opacity 0.3s ease; + } + + .success-message { + color: rgba(74, 222, 128, 0.9); + font-weight: 500; + font-size: 11px; + height: 14px; + text-align: center; + margin-bottom: 4px; + opacity: 1; + transition: opacity 0.3s ease; + } + + .message-fade-out { + animation: fadeOut 3s ease-in-out forwards; + } + + @keyframes fadeOut { + 0% { opacity: 1; } + 66% { opacity: 1; } + 100% { opacity: 0; } } .api-input { @@ -266,12 +299,62 @@ export class ApiKeyHeader extends LitElement { this.wasJustDragged = false this.isLoading = false this.errorMessage = "" + this.successMessage = "" + this.messageTimestamp = 0 //////// after_modelStateService //////// this.llmApiKey = ""; this.sttApiKey = ""; this.llmProvider = "openai"; this.sttProvider = "openai"; this.providers = { llm: [], stt: [] }; // 초기화 + // Ollama related + this.modelSuggestions = []; + this.userModelHistory = []; + this.selectedLlmModel = ""; + this.selectedSttModel = ""; + this.ollamaStatus = { installed: false, running: false }; + this.installingModel = null; + this.installProgress = 0; + this.progressTracker = getOllamaProgressTracker(); + this.whisperInstallingModels = {}; + + // Professional operation management system + this.activeOperations = new Map(); + this.operationTimeouts = new Map(); + this.connectionState = 'idle'; // idle, connecting, connected, failed, disconnected + this.lastStateChange = Date.now(); + this.retryCount = 0; + this.maxRetries = 3; + this.baseRetryDelay = 1000; + + // Backpressure and resource management + this.operationQueue = []; + this.maxConcurrentOperations = 2; + this.maxQueueSize = 5; + this.operationMetrics = { + totalOperations: 0, + successfulOperations: 0, + failedOperations: 0, + timeouts: 0, + averageResponseTime: 0 + }; + + // Configuration + this.ipcTimeout = 10000; // 10s for IPC calls + this.operationTimeout = 15000; // 15s for complex operations + + // Health monitoring system + this.healthCheck = { + enabled: false, + intervalId: null, + intervalMs: 30000, // 30s + lastCheck: 0, + consecutiveFailures: 0, + maxFailures: 3 + }; + + // Load user model history from localStorage + this.loadUserModelHistory(); this.loadProviderConfig(); //////// after_modelStateService //////// @@ -283,6 +366,11 @@ export class ApiKeyHeader extends LitElement { this.handleAnimationEnd = this.handleAnimationEnd.bind(this) this.handleUsePicklesKey = this.handleUsePicklesKey.bind(this) this.handleProviderChange = this.handleProviderChange.bind(this) + this.handleLlmProviderChange = this.handleLlmProviderChange.bind(this) + this.handleSttProviderChange = this.handleSttProviderChange.bind(this) + this.handleMessageFadeEnd = this.handleMessageFadeEnd.bind(this) + this.handleModelKeyPress = this.handleModelKeyPress.bind(this) + this.handleSttModelChange = this.handleSttModelChange.bind(this) } reset() { @@ -297,30 +385,53 @@ export class ApiKeyHeader extends LitElement { async loadProviderConfig() { if (!window.require) return; const { ipcRenderer } = window.require('electron'); - const config = await ipcRenderer.invoke('model:get-provider-config'); - const llmProviders = []; - const sttProviders = []; + try { + const [config, ollamaStatus] = await Promise.all([ + ipcRenderer.invoke('model:get-provider-config'), + ipcRenderer.invoke('ollama:get-status') + ]); + + const llmProviders = []; + const sttProviders = []; - for (const id in config) { - // 'openai-glass' 같은 가상 Provider는 UI에 표시하지 않음 - if (id.includes('-glass')) continue; + for (const id in config) { + // 'openai-glass' 같은 가상 Provider는 UI에 표시하지 않음 + if (id.includes('-glass')) continue; + const hasLlmModels = config[id].llmModels.length > 0 || id === 'ollama'; + const hasSttModels = config[id].sttModels.length > 0 || id === 'whisper'; - if (config[id].llmModels.length > 0) { - llmProviders.push({ id, name: config[id].name }); + if (hasLlmModels) { + llmProviders.push({ id, name: config[id].name }); + } + if (hasSttModels) { + sttProviders.push({ id, name: config[id].name }); + } } - if (config[id].sttModels.length > 0) { - sttProviders.push({ id, name: config[id].name }); + + this.providers = { llm: llmProviders, stt: sttProviders }; + + // 기본 선택 값 설정 + if (llmProviders.length > 0) this.llmProvider = llmProviders[0].id; + if (sttProviders.length > 0) this.sttProvider = sttProviders[0].id; + + // Ollama 상태 및 모델 제안 로드 + if (ollamaStatus?.success) { + this.ollamaStatus = { + installed: ollamaStatus.installed, + running: ollamaStatus.running + }; + + // Load model suggestions if Ollama is running + if (ollamaStatus.running) { + await this.loadModelSuggestions(); + } } + + this.requestUpdate(); + } catch (error) { + console.error('[ApiKeyHeader] Failed to load provider config:', error); } - - this.providers = { llm: llmProviders, stt: sttProviders }; - - // 기본 선택 값 설정 - if (llmProviders.length > 0) this.llmProvider = llmProviders[0].id; - if (sttProviders.length > 0) this.sttProvider = sttProviders[0].id; - - this.requestUpdate(); } async handleMouseDown(e) { @@ -380,7 +491,7 @@ export class ApiKeyHeader extends LitElement { handleInput(e) { this.apiKey = e.target.value - this.errorMessage = "" + this.clearMessages() console.log("Input changed:", this.apiKey?.length || 0, "chars") this.requestUpdate() @@ -391,17 +502,878 @@ export class ApiKeyHeader extends LitElement { } }) } + + clearMessages() { + this.errorMessage = "" + this.successMessage = "" + this.messageTimestamp = 0 + } handleProviderChange(e) { this.selectedProvider = e.target.value - this.errorMessage = "" + this.clearMessages() console.log("Provider changed to:", this.selectedProvider) this.requestUpdate() } + async handleLlmProviderChange(e) { + // Cancel any active operations first + this._cancelAllActiveOperations(); + + this.llmProvider = e.target.value; + this.errorMessage = ""; + this.successMessage = ""; + + // Reset retry state + this.retryCount = 0; + + if (this.llmProvider === 'ollama') { + console.log('[ApiKeyHeader] Ollama selected, initiating connection...'); + await this._initializeOllamaConnection(); + // Start health monitoring for Ollama + this._startHealthMonitoring(); + } else { + this._updateConnectionState('idle', 'Non-Ollama provider selected'); + // Stop health monitoring for non-Ollama providers + this._stopHealthMonitoring(); + } + + this.requestUpdate(); + } + + async _initializeOllamaConnection() { + try { + // Progressive connection attempt with exponential backoff + await this._attemptOllamaConnection(); + } catch (error) { + console.error('[ApiKeyHeader] Initial Ollama connection failed:', error.message); + + if (this.retryCount < this.maxRetries) { + const delay = this.baseRetryDelay * Math.pow(2, this.retryCount); + console.log(`[ApiKeyHeader] Retrying Ollama connection in ${delay}ms (attempt ${this.retryCount + 1}/${this.maxRetries})`); + + this.retryCount++; + + // Use proper Promise-based delay instead of setTimeout + await new Promise(resolve => { + const retryTimeoutId = setTimeout(() => { + this._initializeOllamaConnection(); + resolve(); + }, delay); + + // Store timeout for cleanup + this.operationTimeouts.set(`retry_${this.retryCount}`, retryTimeoutId); + }); + } else { + this._updateConnectionState('failed', `Connection failed after ${this.maxRetries} attempts`); + } + } + } + + async _attemptOllamaConnection() { + await this.refreshOllamaStatus(); + } + + _cancelAllActiveOperations() { + console.log(`[ApiKeyHeader] Cancelling ${this.activeOperations.size} active operations and ${this.operationQueue.length} queued operations`); + + // Cancel active operations + for (const [operationType, operation] of this.activeOperations) { + this._cancelOperation(operationType); + } + + // Cancel queued operations + for (const queuedOp of this.operationQueue) { + queuedOp.reject(new Error(`Operation ${queuedOp.type} cancelled during cleanup`)); + } + this.operationQueue.length = 0; + + // Clean up all timeouts + for (const [timeoutId, timeout] of this.operationTimeouts) { + clearTimeout(timeout); + } + this.operationTimeouts.clear(); + } + + /** + * Get operation metrics for monitoring + */ + getOperationMetrics() { + return { + ...this.operationMetrics, + activeOperations: this.activeOperations.size, + queuedOperations: this.operationQueue.length, + successRate: this.operationMetrics.totalOperations > 0 ? + (this.operationMetrics.successfulOperations / this.operationMetrics.totalOperations) * 100 : 0 + }; + } + + /** + * Adaptive backpressure based on system performance + */ + _adjustBackpressureThresholds() { + const metrics = this.getOperationMetrics(); + + // Reduce concurrent operations if success rate is low + if (metrics.successRate < 70 && this.maxConcurrentOperations > 1) { + this.maxConcurrentOperations = Math.max(1, this.maxConcurrentOperations - 1); + console.log(`[ApiKeyHeader] Reduced max concurrent operations to ${this.maxConcurrentOperations} (success rate: ${metrics.successRate.toFixed(1)}%)`); + } + + // Increase if performance is good + if (metrics.successRate > 90 && metrics.averageResponseTime < 3000 && this.maxConcurrentOperations < 3) { + this.maxConcurrentOperations++; + console.log(`[ApiKeyHeader] Increased max concurrent operations to ${this.maxConcurrentOperations}`); + } + } + + /** + * Professional health monitoring system + */ + _startHealthMonitoring() { + if (this.healthCheck.enabled) return; + + this.healthCheck.enabled = true; + this.healthCheck.intervalId = setInterval(() => { + this._performHealthCheck(); + }, this.healthCheck.intervalMs); + + console.log(`[ApiKeyHeader] Health monitoring started (interval: ${this.healthCheck.intervalMs}ms)`); + } + + _stopHealthMonitoring() { + if (!this.healthCheck.enabled) return; + + this.healthCheck.enabled = false; + if (this.healthCheck.intervalId) { + clearInterval(this.healthCheck.intervalId); + this.healthCheck.intervalId = null; + } + + console.log('[ApiKeyHeader] Health monitoring stopped'); + } + + async _performHealthCheck() { + // Only perform health check if Ollama is selected and we're in a stable state + if (this.llmProvider !== 'ollama' || this.connectionState === 'connecting') { + return; + } + + const now = Date.now(); + this.healthCheck.lastCheck = now; + + try { + // Lightweight health check - just ping the service + const isHealthy = await this._executeOperation('health_check', async () => { + if (!window.require) return false; + const { ipcRenderer } = window.require('electron'); + const result = await ipcRenderer.invoke('ollama:get-status'); + return result?.success && result?.running; + }, { timeout: 5000, priority: 'low' }); + + if (isHealthy) { + this.healthCheck.consecutiveFailures = 0; + + // Update state if we were previously failed + if (this.connectionState === 'failed') { + this._updateConnectionState('connected', 'Health check recovered'); + } + } else { + this._handleHealthCheckFailure(); + } + + // Adjust thresholds based on performance + this._adjustBackpressureThresholds(); + + } catch (error) { + console.warn('[ApiKeyHeader] Health check failed:', error.message); + this._handleHealthCheckFailure(); + } + } + + _handleHealthCheckFailure() { + this.healthCheck.consecutiveFailures++; + + if (this.healthCheck.consecutiveFailures >= this.healthCheck.maxFailures) { + console.warn(`[ApiKeyHeader] Health check failed ${this.healthCheck.consecutiveFailures} times, marking as disconnected`); + this._updateConnectionState('failed', 'Service health check failed'); + + // Increase health check frequency when having issues + this.healthCheck.intervalMs = Math.max(10000, this.healthCheck.intervalMs / 2); + this._restartHealthMonitoring(); + } + } + + _restartHealthMonitoring() { + this._stopHealthMonitoring(); + this._startHealthMonitoring(); + } + + /** + * Get comprehensive health status + */ + getHealthStatus() { + return { + connection: { + state: this.connectionState, + lastStateChange: this.lastStateChange, + timeSinceLastChange: Date.now() - this.lastStateChange + }, + operations: this.getOperationMetrics(), + health: { + enabled: this.healthCheck.enabled, + lastCheck: this.healthCheck.lastCheck, + timeSinceLastCheck: this.healthCheck.lastCheck > 0 ? Date.now() - this.healthCheck.lastCheck : null, + consecutiveFailures: this.healthCheck.consecutiveFailures, + intervalMs: this.healthCheck.intervalMs + }, + ollama: { + provider: this.llmProvider, + status: this.ollamaStatus, + selectedModel: this.selectedLlmModel + } + }; + } + + async handleSttProviderChange(e) { + this.sttProvider = e.target.value; + this.errorMessage = ""; + this.successMessage = ""; + + if (this.sttProvider === 'ollama') { + console.warn('[ApiKeyHeader] Ollama does not support STT yet. Please select Whisper or another provider.'); + this.errorMessage = 'Ollama does not support STT yet. Please select Whisper or another STT provider.'; + this.messageTimestamp = Date.now(); + + // Auto-select Whisper if available + const whisperProvider = this.providers.stt.find(p => p.id === 'whisper'); + if (whisperProvider) { + this.sttProvider = 'whisper'; + console.log('[ApiKeyHeader] Auto-selected Whisper for STT'); + } + } + + this.requestUpdate(); + } + + /** + * Professional operation management with backpressure control + */ + async _executeOperation(operationType, operation, options = {}) { + const operationId = `${operationType}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; + const timeout = options.timeout || this.ipcTimeout; + const priority = options.priority || 'normal'; // high, normal, low + + // Backpressure control + if (this.activeOperations.size >= this.maxConcurrentOperations) { + if (this.operationQueue.length >= this.maxQueueSize) { + throw new Error(`Operation queue full (${this.maxQueueSize}), rejecting ${operationType}`); + } + + console.log(`[ApiKeyHeader] Queuing operation ${operationType} (${this.activeOperations.size} active)`); + return this._queueOperation(operationId, operationType, operation, options); + } + + return this._executeImmediately(operationId, operationType, operation, timeout); + } + + async _queueOperation(operationId, operationType, operation, options) { + return new Promise((resolve, reject) => { + const queuedOperation = { + id: operationId, + type: operationType, + operation, + options, + resolve, + reject, + queuedAt: Date.now(), + priority: options.priority || 'normal' + }; + + // Insert based on priority (high priority first) + if (options.priority === 'high') { + this.operationQueue.unshift(queuedOperation); + } else { + this.operationQueue.push(queuedOperation); + } + + console.log(`[ApiKeyHeader] Queued ${operationType} (queue size: ${this.operationQueue.length})`); + }); + } + + async _executeImmediately(operationId, operationType, operation, timeout) { + const startTime = Date.now(); + this.operationMetrics.totalOperations++; + + // Check if similar operation is already running + if (this.activeOperations.has(operationType)) { + console.log(`[ApiKeyHeader] Operation ${operationType} already in progress, cancelling previous`); + this._cancelOperation(operationType); + } + + // Create cancellation mechanism + const cancellationPromise = new Promise((_, reject) => { + const timeoutId = setTimeout(() => { + this.operationMetrics.timeouts++; + reject(new Error(`Operation ${operationType} timeout after ${timeout}ms`)); + }, timeout); + + this.operationTimeouts.set(operationId, timeoutId); + }); + + const operationPromise = Promise.race([ + operation(), + cancellationPromise + ]); + + this.activeOperations.set(operationType, { + id: operationId, + promise: operationPromise, + startTime + }); + + try { + const result = await operationPromise; + this._recordOperationSuccess(startTime); + return result; + } catch (error) { + this._recordOperationFailure(error, operationType); + throw error; + } finally { + this._cleanupOperation(operationId, operationType); + this._processQueue(); + } + } + + _recordOperationSuccess(startTime) { + this.operationMetrics.successfulOperations++; + const responseTime = Date.now() - startTime; + this._updateAverageResponseTime(responseTime); + } + + _recordOperationFailure(error, operationType) { + this.operationMetrics.failedOperations++; + + if (error.message.includes('timeout')) { + console.error(`[ApiKeyHeader] Operation ${operationType} timed out`); + this._updateConnectionState('failed', `Timeout: ${error.message}`); + } + } + + _updateAverageResponseTime(responseTime) { + const totalOps = this.operationMetrics.successfulOperations; + this.operationMetrics.averageResponseTime = + ((this.operationMetrics.averageResponseTime * (totalOps - 1)) + responseTime) / totalOps; + } + + async _processQueue() { + if (this.operationQueue.length === 0 || this.activeOperations.size >= this.maxConcurrentOperations) { + return; + } + + const queuedOp = this.operationQueue.shift(); + if (!queuedOp) return; + + const queueTime = Date.now() - queuedOp.queuedAt; + console.log(`[ApiKeyHeader] Processing queued operation ${queuedOp.type} (waited ${queueTime}ms)`); + + try { + const result = await this._executeImmediately( + queuedOp.id, + queuedOp.type, + queuedOp.operation, + queuedOp.options.timeout || this.ipcTimeout + ); + queuedOp.resolve(result); + } catch (error) { + queuedOp.reject(error); + } + } + + _cancelOperation(operationType) { + const operation = this.activeOperations.get(operationType); + if (operation) { + this._cleanupOperation(operation.id, operationType); + console.log(`[ApiKeyHeader] Cancelled operation: ${operationType}`); + } + } + + _cleanupOperation(operationId, operationType) { + if (this.operationTimeouts.has(operationId)) { + clearTimeout(this.operationTimeouts.get(operationId)); + this.operationTimeouts.delete(operationId); + } + this.activeOperations.delete(operationType); + } + + _updateConnectionState(newState, reason = '') { + if (this.connectionState !== newState) { + console.log(`[ApiKeyHeader] Connection state: ${this.connectionState} -> ${newState} (${reason})`); + this.connectionState = newState; + this.lastStateChange = Date.now(); + + // Update UI based on state + this._handleStateChange(newState, reason); + } + } + + _handleStateChange(state, reason) { + switch (state) { + case 'connecting': + this.installingModel = 'Connecting to Ollama...'; + this.installProgress = 10; + break; + case 'failed': + this.errorMessage = reason || 'Connection failed'; + this.installingModel = null; + this.installProgress = 0; + this.messageTimestamp = Date.now(); + break; + case 'connected': + this.installingModel = null; + this.installProgress = 0; + break; + case 'disconnected': + this.ollamaStatus = { installed: false, running: false }; + break; + } + this.requestUpdate(); + } + + async refreshOllamaStatus() { + if (!window.require) return; + + try { + this._updateConnectionState('connecting', 'Checking Ollama status'); + + const result = await this._executeOperation('ollama_status', async () => { + const { ipcRenderer } = window.require('electron'); + return await ipcRenderer.invoke('ollama:get-status'); + }); + + if (result?.success) { + this.ollamaStatus = { + installed: result.installed, + running: result.running + }; + + this._updateConnectionState('connected', 'Status updated successfully'); + + // Load model suggestions if Ollama is running + if (result.running) { + await this.loadModelSuggestions(); + } + } else { + this._updateConnectionState('failed', result?.error || 'Status check failed'); + } + } catch (error) { + console.error('[ApiKeyHeader] Failed to refresh Ollama status:', error.message); + this._updateConnectionState('failed', error.message); + } + } + + async loadModelSuggestions() { + if (!window.require) return; + + try { + const result = await this._executeOperation('model_suggestions', async () => { + const { ipcRenderer } = window.require('electron'); + return await ipcRenderer.invoke('ollama:get-model-suggestions'); + }); + + if (result?.success) { + this.modelSuggestions = result.suggestions || []; + + // 기본 모델 선택 (설치된 모델 중 첫 번째) + if (!this.selectedLlmModel && this.modelSuggestions.length > 0) { + const installedModel = this.modelSuggestions.find(m => m.status === 'installed'); + if (installedModel) { + this.selectedLlmModel = installedModel.name; + } + } + this.requestUpdate(); + } else { + console.warn('[ApiKeyHeader] Model suggestions request unsuccessful:', result?.error); + } + } catch (error) { + console.error('[ApiKeyHeader] Failed to load model suggestions:', error.message); + } + } + + async ensureOllamaReady() { + if (!window.require) return false; + + try { + this._updateConnectionState('connecting', 'Ensuring Ollama is ready'); + + const result = await this._executeOperation('ollama_ensure_ready', async () => { + const { ipcRenderer } = window.require('electron'); + return await ipcRenderer.invoke('ollama:ensure-ready'); + }, { timeout: this.operationTimeout }); + + if (result?.success) { + await this.refreshOllamaStatus(); + this._updateConnectionState('connected', 'Ollama ready'); + return true; + } else { + const errorMsg = `Failed to setup Ollama: ${result?.error || 'Unknown error'}`; + this._updateConnectionState('failed', errorMsg); + return false; + } + } catch (error) { + console.error('[ApiKeyHeader] Failed to ensure Ollama ready:', error.message); + this._updateConnectionState('failed', `Error setting up Ollama: ${error.message}`); + return false; + } + } + + async ensureOllamaReadyWithUI() { + if (!window.require) return false; + const { ipcRenderer } = window.require("electron"); + + this.installingModel = "Setting up Ollama"; + this.installProgress = 0; + this.clearMessages(); + this.requestUpdate(); + + const progressHandler = (event, data) => { + let baseProgress = 0; + let stageTotal = 0; + + switch (data.stage) { + case "downloading": + baseProgress = 0; + stageTotal = 70; + break; + case "mounting": + baseProgress = 70; + stageTotal = 10; + break; + case "installing": + baseProgress = 80; + stageTotal = 10; + break; + case "linking": + baseProgress = 90; + stageTotal = 5; + break; + case "cleanup": + baseProgress = 95; + stageTotal = 3; + break; + case "starting": + baseProgress = 98; + stageTotal = 2; + break; + } + + const overallProgress = baseProgress + (data.progress / 100) * stageTotal; + + this.installingModel = data.message; + this.installProgress = Math.round(overallProgress); + this.requestUpdate(); + }; + + let operationCompleted = false; + const completionTimeout = setTimeout(async () => { + if (!operationCompleted) { + console.log("[ApiKeyHeader] Operation timeout, checking status manually..."); + await this._handleOllamaSetupCompletion(true); + } + }, 15000); // 15 second timeout + + const completionHandler = async (event, result) => { + if (operationCompleted) return; + operationCompleted = true; + clearTimeout(completionTimeout); + + ipcRenderer.removeListener("ollama:install-progress", progressHandler); + await this._handleOllamaSetupCompletion(result.success, result.error); + }; + + ipcRenderer.once("ollama:install-complete", completionHandler); + ipcRenderer.on("ollama:install-progress", progressHandler); + + try { + let result; + if (!this.ollamaStatus.installed) { + console.log("[ApiKeyHeader] Ollama not installed. Starting installation."); + result = await ipcRenderer.invoke("ollama:install"); + } else { + console.log("[ApiKeyHeader] Ollama installed. Starting service."); + result = await ipcRenderer.invoke("ollama:start-service"); + } + + // If IPC call succeeds but no event received, handle completion manually + if (result?.success && !operationCompleted) { + setTimeout(async () => { + if (!operationCompleted) { + operationCompleted = true; + clearTimeout(completionTimeout); + await this._handleOllamaSetupCompletion(true); + } + }, 2000); + } + + } catch (error) { + operationCompleted = true; + clearTimeout(completionTimeout); + console.error("[ApiKeyHeader] Ollama setup failed:", error); + ipcRenderer.removeListener("ollama:install-progress", progressHandler); + ipcRenderer.removeListener("ollama:install-complete", completionHandler); + await this._handleOllamaSetupCompletion(false, error.message); + } + } + + async _handleOllamaSetupCompletion(success, errorMessage = null) { + this.installingModel = null; + this.installProgress = 0; + + if (success) { + await this.refreshOllamaStatus(); + this.successMessage = "✓ Ollama is ready!"; + } else { + this.errorMessage = `Setup failed: ${errorMessage || "Unknown error"}`; + } + this.messageTimestamp = Date.now(); + this.requestUpdate(); + } + + async handleModelInput(e) { + const modelName = e.target.value.trim(); + this.selectedLlmModel = modelName; + this.clearMessages(); + + // Save to user history if it's a valid model name + if (modelName && modelName.length > 2) { + this.saveToUserHistory(modelName); + } + + this.requestUpdate(); + } + + async handleModelKeyPress(e) { + if (e.key === 'Enter' && this.selectedLlmModel?.trim()) { + e.preventDefault(); + console.log(`[ApiKeyHeader] Enter pressed, installing model: ${this.selectedLlmModel}`); + + // Check if Ollama is ready first + const ollamaReady = await this.ensureOllamaReady(); + if (!ollamaReady) { + this.errorMessage = 'Failed to setup Ollama'; + this.messageTimestamp = Date.now(); + this.requestUpdate(); + return; + } + + // Install the model + await this.installModel(this.selectedLlmModel); + } + } + + loadUserModelHistory() { + try { + const saved = localStorage.getItem('ollama-model-history'); + if (saved) { + this.userModelHistory = JSON.parse(saved); + } + } catch (error) { + console.error('[ApiKeyHeader] Failed to load model history:', error); + this.userModelHistory = []; + } + } + + saveToUserHistory(modelName) { + if (!modelName || !modelName.trim()) return; + + // Remove if already exists (to move to front) + this.userModelHistory = this.userModelHistory.filter(m => m !== modelName); + + // Add to front + this.userModelHistory.unshift(modelName); + + // Keep only last 20 entries + this.userModelHistory = this.userModelHistory.slice(0, 20); + + // Save to localStorage + try { + localStorage.setItem('ollama-model-history', JSON.stringify(this.userModelHistory)); + } catch (error) { + console.error('[ApiKeyHeader] Failed to save model history:', error); + } + } + + getCombinedModelSuggestions() { + const combined = []; + + // Add installed models first (from Ollama CLI) + for (const model of this.modelSuggestions) { + combined.push({ + name: model.name, + status: 'installed', + size: model.size || 'Unknown', + source: 'installed' + }); + } + + // Add user history models that aren't already installed + const installedNames = this.modelSuggestions.map(m => m.name); + for (const modelName of this.userModelHistory) { + if (!installedNames.includes(modelName)) { + combined.push({ + name: modelName, + status: 'history', + size: 'Unknown', + source: 'history' + }); + } + } + + return combined; + } + + async installModel(modelName) { + if (!modelName?.trim()) { + throw new Error('Invalid model name'); + } + + this.installingModel = modelName; + this.installProgress = 0; + this.clearMessages(); + this.requestUpdate(); + + const { ipcRenderer } = window.require('electron'); + let progressHandler = null; + + try { + console.log(`[ApiKeyHeader] Installing model via Ollama REST API: ${modelName}`); + + // Create robust progress handler with timeout protection + progressHandler = (event, data) => { + if (data.model === modelName && !this._isOperationCancelled(modelName)) { + const progress = Math.round(Math.max(0, Math.min(100, data.progress || 0))); + + if (progress !== this.installProgress) { + this.installProgress = progress; + console.log(`[ApiKeyHeader] API Progress: ${progress}% for ${modelName} (${data.status || 'downloading'})`); + this.requestUpdate(); + } + } + }; + + // Set up progress tracking + ipcRenderer.on('ollama:pull-progress', progressHandler); + + // Execute the model pull with timeout + const installPromise = ipcRenderer.invoke('ollama:pull-model', modelName); + const timeoutPromise = new Promise((_, reject) => + setTimeout(() => reject(new Error('Installation timeout after 10 minutes')), 600000) + ); + + const result = await Promise.race([installPromise, timeoutPromise]); + + if (result.success) { + console.log(`[ApiKeyHeader] Model ${modelName} installed successfully via API`); + this.installProgress = 100; + this.requestUpdate(); + + // Brief pause to show completion + await new Promise(resolve => setTimeout(resolve, 300)); + + // Refresh status and show success + await this.refreshOllamaStatus(); + this.successMessage = `✓ ${modelName} ready`; + this.messageTimestamp = Date.now(); + } else { + throw new Error(result.error || 'Installation failed'); + } + } catch (error) { + console.error(`[ApiKeyHeader] Model installation failed:`, error); + this.errorMessage = `Failed: ${error.message}`; + this.messageTimestamp = Date.now(); + } finally { + // Comprehensive cleanup + if (progressHandler) { + ipcRenderer.removeListener('ollama:pull-progress', progressHandler); + } + + this.installingModel = null; + this.installProgress = 0; + this.requestUpdate(); + } + } + + _isOperationCancelled(modelName) { + return !this.installingModel || this.installingModel !== modelName; + } + + async downloadWhisperModel(modelId) { + if (!modelId?.trim()) { + console.warn('[ApiKeyHeader] Invalid Whisper model ID'); + return; + } + + console.log(`[ApiKeyHeader] Starting Whisper model download: ${modelId}`); + + // Mark as installing + this.whisperInstallingModels = { ...this.whisperInstallingModels, [modelId]: 0 }; + this.clearMessages(); + this.requestUpdate(); + + const { ipcRenderer } = window.require('electron'); + let progressHandler = null; + + try { + // Set up robust progress listener + progressHandler = (event, { modelId: id, progress }) => { + if (id === modelId) { + const cleanProgress = Math.round(Math.max(0, Math.min(100, progress || 0))); + this.whisperInstallingModels = { ...this.whisperInstallingModels, [modelId]: cleanProgress }; + console.log(`[ApiKeyHeader] Whisper download progress: ${cleanProgress}% for ${modelId}`); + this.requestUpdate(); + } + }; + + ipcRenderer.on('whisper:download-progress', progressHandler); + + // Start download with timeout protection + const downloadPromise = ipcRenderer.invoke('whisper:download-model', modelId); + const timeoutPromise = new Promise((_, reject) => + setTimeout(() => reject(new Error('Download timeout after 10 minutes')), 600000) + ); + + const result = await Promise.race([downloadPromise, timeoutPromise]); + + if (result?.success) { + this.successMessage = `✓ ${modelId} downloaded successfully`; + this.messageTimestamp = Date.now(); + console.log(`[ApiKeyHeader] Whisper model ${modelId} downloaded successfully`); + + // Auto-select the downloaded model + this.selectedSttModel = modelId; + } else { + this.errorMessage = `Failed to download ${modelId}: ${result?.error || 'Unknown error'}`; + this.messageTimestamp = Date.now(); + console.error(`[ApiKeyHeader] Whisper download failed:`, result?.error); + } + + } catch (error) { + console.error(`[ApiKeyHeader] Error downloading Whisper model ${modelId}:`, error); + this.errorMessage = `Error downloading ${modelId}: ${error.message}`; + this.messageTimestamp = Date.now(); + } finally { + // Cleanup + if (progressHandler) { + ipcRenderer.removeListener('whisper:download-progress', progressHandler); + } + delete this.whisperInstallingModels[modelId]; + this.requestUpdate(); + } + } + handlePaste(e) { e.preventDefault() - this.errorMessage = "" + this.clearMessages() const clipboardText = (e.clipboardData || window.clipboardData).getData("text") console.log("Paste event detected:", clipboardText?.substring(0, 10) + "...") @@ -430,39 +1402,127 @@ export class ApiKeyHeader extends LitElement { } //////// after_modelStateService //////// - async handleSubmit() { - console.log('[ApiKeyHeader] handleSubmit: Submitting API keys...'); - if (this.isLoading || !this.llmApiKey.trim() || !this.sttApiKey.trim()) { - this.errorMessage = "Please enter keys for both LLM and STT."; - return; + async handleSttModelChange(e) { + const modelId = e.target.value; + this.selectedSttModel = modelId; + + if (modelId && this.sttProvider === 'whisper') { + // Check if model needs to be downloaded + const isInstalling = this.whisperInstallingModels[modelId] !== undefined; + if (!isInstalling) { + console.log(`[ApiKeyHeader] Auto-installing Whisper model: ${modelId}`); + await this.downloadWhisperModel(modelId); + } } + + this.requestUpdate(); + } + async handleSubmit() { + console.log('[ApiKeyHeader] handleSubmit: Submitting...'); + this.isLoading = true; - this.errorMessage = ""; + this.clearMessages(); this.requestUpdate(); const { ipcRenderer } = window.require('electron'); + + try { + // Handle LLM provider + let llmResult; + if (this.llmProvider === 'ollama') { + // For Ollama ensure it's ready and validate model selection + if (!this.selectedLlmModel?.trim()) { + throw new Error('Please enter an Ollama model name'); + } + + const ollamaReady = await this.ensureOllamaReady(); + if (!ollamaReady) { + throw new Error('Failed to setup Ollama'); + } + + // Check if model is installed, if not install it + const selectedModel = this.getCombinedModelSuggestions().find(m => m.name === this.selectedLlmModel); + if (!selectedModel || selectedModel.status !== 'installed') { + console.log(`[ApiKeyHeader] Installing model ${this.selectedLlmModel}...`); + await this.installModel(this.selectedLlmModel); + } + + // Validate Ollama is working + llmResult = await ipcRenderer.invoke('model:validate-key', { + provider: 'ollama', + key: 'local' + }); + + if (llmResult.success) { + // Set the selected model + await ipcRenderer.invoke('model:set-selected-model', { + type: 'llm', + modelId: this.selectedLlmModel + }); + } + } else { + // For other providers, validate API key + if (!this.llmApiKey.trim()) { + throw new Error('Please enter LLM API key'); + } + + llmResult = await ipcRenderer.invoke('model:validate-key', { + provider: this.llmProvider, + key: this.llmApiKey.trim() + }); + } - console.log('[ApiKeyHeader] handleSubmit: Validating LLM key...'); - const llmValidation = ipcRenderer.invoke('model:validate-key', { provider: this.llmProvider, key: this.llmApiKey.trim() }); - const sttValidation = ipcRenderer.invoke('model:validate-key', { provider: this.sttProvider, key: this.sttApiKey.trim() }); + // Handle STT provider + let sttResult; + if (this.sttProvider === 'ollama') { + // Ollama doesn't support STT yet, so skip or use same as LLM validation + sttResult = { success: true }; + } else if (this.sttProvider === 'whisper') { + // For Whisper, just validate it's enabled (model download already handled in handleSttModelChange) + sttResult = await ipcRenderer.invoke('model:validate-key', { + provider: 'whisper', + key: 'local' + }); + + if (sttResult.success && this.selectedSttModel) { + // Set the selected model + await ipcRenderer.invoke('model:set-selected-model', { + type: 'stt', + modelId: this.selectedSttModel + }); + } + } else { + // For other providers, validate API key + if (!this.sttApiKey.trim()) { + throw new Error('Please enter STT API key'); + } + + sttResult = await ipcRenderer.invoke('model:validate-key', { + provider: this.sttProvider, + key: this.sttApiKey.trim() + }); + } - const [llmResult, sttResult] = await Promise.all([llmValidation, sttValidation]); - - if (llmResult.success && sttResult.success) { - console.log('[ApiKeyHeader] handleSubmit: Both LLM and STT keys are valid.'); - this.startSlideOutAnimation(); - } else { - console.log('[ApiKeyHeader] handleSubmit: Validation failed.'); - let errorParts = []; - if (!llmResult.success) errorParts.push(`LLM Key: ${llmResult.error || 'Invalid'}`); - if (!sttResult.success) errorParts.push(`STT Key: ${sttResult.error || 'Invalid'}`); - this.errorMessage = errorParts.join(' | '); + if (llmResult.success && sttResult.success) { + console.log('[ApiKeyHeader] handleSubmit: Validation successful.'); + this.startSlideOutAnimation(); + } else { + let errorParts = []; + if (!llmResult.success) errorParts.push(`LLM: ${llmResult.error || 'Invalid'}`); + if (!sttResult.success) errorParts.push(`STT: ${sttResult.error || 'Invalid'}`); + this.errorMessage = errorParts.join(' | '); + this.messageTimestamp = Date.now(); + } + } catch (error) { + console.error('[ApiKeyHeader] handleSubmit: Error:', error); + this.errorMessage = error.message; + this.messageTimestamp = Date.now(); } this.isLoading = false; this.requestUpdate(); -} + } //////// after_modelStateService //////// @@ -494,10 +1554,46 @@ export class ApiKeyHeader extends LitElement { if (e.target !== this || !this.classList.contains('sliding-out')) return; this.classList.remove("sliding-out"); this.classList.add("hidden"); - window.require('electron').ipcRenderer.invoke('get-current-user').then(userState => { - console.log('[ApiKeyHeader] handleAnimationEnd: User state updated:', userState); - this.stateUpdateCallback?.(userState); - }); + + console.log('[ApiKeyHeader] handleAnimationEnd: Animation completed, transitioning to next state...'); + + if (!window.require) { + console.error('[ApiKeyHeader] handleAnimationEnd: window.require not available'); + return; + } + + if (!this.stateUpdateCallback) { + console.error('[ApiKeyHeader] handleAnimationEnd: stateUpdateCallback not set! This will prevent transition to main window.'); + return; + } + + const { ipcRenderer } = window.require('electron'); + + ipcRenderer.invoke('get-current-user') + .then(userState => { + console.log('[ApiKeyHeader] handleAnimationEnd: User state retrieved:', userState); + + // Additional validation for local providers + return ipcRenderer.invoke('model:are-providers-configured').then(isConfigured => { + console.log('[ApiKeyHeader] handleAnimationEnd: Providers configured check:', isConfigured); + + if (!isConfigured) { + console.warn('[ApiKeyHeader] handleAnimationEnd: Providers still not configured, may return to ApiKey screen'); + } + + // Call the state update callback + this.stateUpdateCallback(userState); + }); + }) + .catch(error => { + console.error('[ApiKeyHeader] handleAnimationEnd: Error during state transition:', error); + + // Fallback: try to call callback with minimal state + if (this.stateUpdateCallback) { + console.log('[ApiKeyHeader] handleAnimationEnd: Attempting fallback state transition...'); + this.stateUpdateCallback({ isLoggedIn: false }); + } + }); } //////// after_modelStateService //////// @@ -505,41 +1601,346 @@ export class ApiKeyHeader extends LitElement { super.connectedCallback() this.addEventListener("animationend", this.handleAnimationEnd) } + + handleMessageFadeEnd(e) { + if (e.animationName === 'fadeOut') { + // Clear the message that finished fading + if (e.target.classList.contains('error-message')) { + this.errorMessage = ''; + } else if (e.target.classList.contains('success-message')) { + this.successMessage = ''; + } + this.messageTimestamp = 0; + this.requestUpdate(); + } + } disconnectedCallback() { super.disconnectedCallback() this.removeEventListener("animationend", this.handleAnimationEnd) + + // Professional cleanup of all resources + this._performCompleteCleanup(); + } + + _performCompleteCleanup() { + console.log('[ApiKeyHeader] Performing complete cleanup'); + + // Stop health monitoring + this._stopHealthMonitoring(); + + // Cancel all active operations + this._cancelAllActiveOperations(); + + // Cancel any ongoing installations when component is destroyed + if (this.installingModel) { + this.progressTracker.cancelInstallation(this.installingModel); + } + + // Cleanup event listeners + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.removeAllListeners('whisper:download-progress'); + ipcRenderer.removeAllListeners('ollama:install-progress'); + ipcRenderer.removeAllListeners('ollama:pull-progress'); + ipcRenderer.removeAllListeners('ollama:install-complete'); + } + + // Cancel any ongoing downloads + const downloadingModels = Object.keys(this.whisperInstallingModels); + if (downloadingModels.length > 0) { + console.log(`[ApiKeyHeader] Cancelling ${downloadingModels.length} ongoing Whisper downloads`); + downloadingModels.forEach(modelId => { + delete this.whisperInstallingModels[modelId]; + }); + } + + // Reset state + this.connectionState = 'disconnected'; + this.retryCount = 0; + + console.log('[ApiKeyHeader] Cleanup completed'); + } + + /** + * State machine-based Ollama UI rendering + */ + _renderOllamaStateUI() { + const state = this._getOllamaUIState(); + + switch (state.type) { + case 'connecting': + return this._renderConnectingState(state); + case 'install_required': + return this._renderInstallRequiredState(); + case 'start_required': + return this._renderStartRequiredState(); + case 'ready': + return this._renderReadyState(); + case 'failed': + return this._renderFailedState(state); + case 'installing': + return this._renderInstallingState(state); + default: + return this._renderUnknownState(); + } + } + + _getOllamaUIState() { + // State determination logic + if (this.connectionState === 'connecting') { + return { type: 'connecting', message: this.installingModel || 'Connecting to Ollama...' }; + } + + if (this.connectionState === 'failed') { + return { type: 'failed', message: this.errorMessage }; + } + + if (this.installingModel && this.installingModel.includes('Ollama')) { + return { type: 'installing', progress: this.installProgress }; + } + + if (!this.ollamaStatus.installed) { + return { type: 'install_required' }; + } + + if (!this.ollamaStatus.running) { + return { type: 'start_required' }; + } + + return { type: 'ready' }; + } + + _renderConnectingState(state) { + return html` +
+
+
+
+
+ ${this.installProgress}% +
+
+ `; + } + + _renderInstallRequiredState() { + return html` + + `; + } + + _renderStartRequiredState() { + return html` + + `; + } + + _renderReadyState() { + return html` + + + + ${this.getCombinedModelSuggestions().map(model => html` + + `)} + + + + ${this.renderModelStatus()} + + ${this.installingModel && !this.installingModel.includes('Ollama') ? html` +
+
+
+
+
+ ${this.installProgress}% +
+
+ ` : ''} + `; + } + + _renderFailedState(state) { + return html` +
+
+ Connection failed +
+
+ ${state.message || 'Unknown error'} +
+ +
+ `; + } + + _renderInstallingState(state) { + return html` +
+
+
+
+
+ ${state.progress}% +
+
+ `; + } + + _renderUnknownState() { + return html` +
+
+ Unknown state - Please refresh +
+
+ `; + } + + renderModelStatus() { + return ''; + } + + shouldFadeMessage(type) { + const hasMessage = type === 'error' ? this.errorMessage : this.successMessage; + return hasMessage && this.messageTimestamp > 0 && (Date.now() - this.messageTimestamp) > 100; } render() { - const isButtonDisabled = this.isLoading || !this.llmApiKey.trim() || !this.sttApiKey.trim(); + // Check if providers are selected and determine validation requirements + const llmNeedsApiKey = this.llmProvider !== 'ollama' && this.llmProvider !== 'whisper'; + const sttNeedsApiKey = this.sttProvider !== 'ollama' && this.sttProvider !== 'whisper'; + const llmNeedsModel = this.llmProvider === 'ollama'; + const sttNeedsModel = this.sttProvider === 'whisper'; + + // Simplified button disabled logic + const isButtonDisabled = this.isLoading || + this.installingModel || + Object.keys(this.whisperInstallingModels).length > 0 || + (llmNeedsApiKey && !this.llmApiKey.trim()) || + (sttNeedsApiKey && !this.sttApiKey.trim()) || + (llmNeedsModel && !this.selectedLlmModel?.trim()) || + (sttNeedsModel && !this.selectedSttModel); return html`
-

Enter Your API Keys

+ +

Configure AI Models

-
- ${this.providers.llm.map(p => html``)} - this.llmApiKey = e.target.value} ?disabled=${this.isLoading}> + + ${this.llmProvider === 'ollama' ? this._renderOllamaStateUI() : html` + + this.llmApiKey = e.target.value} ?disabled=${this.isLoading}> + `}
-
- ${this.providers.stt.map(p => html``)} - this.sttApiKey = e.target.value} ?disabled=${this.isLoading}> + + ${this.sttProvider === 'ollama' ? html` + +
+ STT not supported by Ollama +
+ ` : this.sttProvider === 'whisper' ? html` + + + + ${Object.entries(this.whisperInstallingModels).map(([modelId, progress]) => { + if (progress !== undefined) { + return html` +
+
+
+
+
+ ${progress}% +
+
+ `; + } + return ''; + })} + ` : html` + + this.sttApiKey = e.target.value} ?disabled=${this.isLoading}> + `}
-
${this.errorMessage}
+
+ ${this.errorMessage} +
+
+ ${this.successMessage} +
or
diff --git a/src/common/ai/factory.js b/src/common/ai/factory.js index ea86ff0..520ba06 100644 --- a/src/common/ai/factory.js +++ b/src/common/ai/factory.js @@ -57,6 +57,34 @@ const PROVIDERS = { ], sttModels: [], }, + 'ollama': { + name: 'Ollama (Local)', + handler: () => require("./providers/ollama"), + llmModels: [], // Dynamic models populated from installed Ollama models + sttModels: [], // Ollama doesn't support STT yet + }, + 'whisper': { + name: 'Whisper (Local)', + handler: () => { + // Only load in main process + if (typeof window === 'undefined') { + return require("./providers/whisper"); + } + // Return dummy for renderer + return { + createSTT: () => { throw new Error('Whisper STT is only available in main process'); }, + createLLM: () => { throw new Error('Whisper does not support LLM'); }, + createStreamingLLM: () => { throw new Error('Whisper does not support LLM'); } + }; + }, + llmModels: [], + sttModels: [ + { id: 'whisper-tiny', name: 'Whisper Tiny (39M)' }, + { id: 'whisper-base', name: 'Whisper Base (74M)' }, + { id: 'whisper-small', name: 'Whisper Small (244M)' }, + { id: 'whisper-medium', name: 'Whisper Medium (769M)' }, + ], + }, }; function sanitizeModelId(model) { diff --git a/src/common/ai/providers/ollama.js b/src/common/ai/providers/ollama.js new file mode 100644 index 0000000..c25e10c --- /dev/null +++ b/src/common/ai/providers/ollama.js @@ -0,0 +1,242 @@ +const http = require('http'); +const fetch = require('node-fetch'); + +function convertMessagesToOllamaFormat(messages) { + return messages.map(msg => { + if (Array.isArray(msg.content)) { + let textContent = ''; + const images = []; + + for (const part of msg.content) { + if (part.type === 'text') { + textContent += part.text; + } else if (part.type === 'image_url') { + const base64 = part.image_url.url.replace(/^data:image\/[^;]+;base64,/, ''); + images.push(base64); + } + } + + return { + role: msg.role, + content: textContent, + ...(images.length > 0 && { images }) + }; + } else { + return msg; + } + }); +} + +function createLLM({ + model, + temperature = 0.7, + maxTokens = 2048, + baseUrl = 'http://localhost:11434', + ...config +}) { + if (!model) { + throw new Error('Model parameter is required for Ollama LLM. Please specify a model name (e.g., "llama3.2:latest", "gemma3:4b")'); + } + return { + generateContent: async (parts) => { + let systemPrompt = ''; + const userContent = []; + + for (const part of parts) { + if (typeof part === 'string') { + if (systemPrompt === '' && part.includes('You are')) { + systemPrompt = part; + } else { + userContent.push(part); + } + } else if (part.inlineData) { + userContent.push({ + type: 'image', + image: `data:${part.inlineData.mimeType};base64,${part.inlineData.data}` + }); + } + } + + const messages = []; + if (systemPrompt) { + messages.push({ role: 'system', content: systemPrompt }); + } + messages.push({ role: 'user', content: userContent.join('\n') }); + + try { + const response = await fetch(`${baseUrl}/api/chat`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + model, + messages, + stream: false, + options: { + temperature, + num_predict: maxTokens, + } + }) + }); + + if (!response.ok) { + throw new Error(`Ollama API error: ${response.status} ${response.statusText}`); + } + + const result = await response.json(); + + return { + response: { + text: () => result.message.content + }, + raw: result + }; + } catch (error) { + console.error('Ollama LLM error:', error); + throw error; + } + }, + + chat: async (messages) => { + const ollamaMessages = convertMessagesToOllamaFormat(messages); + + try { + const response = await fetch(`${baseUrl}/api/chat`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + model, + messages: ollamaMessages, + stream: false, + options: { + temperature, + num_predict: maxTokens, + } + }) + }); + + if (!response.ok) { + throw new Error(`Ollama API error: ${response.status} ${response.statusText}`); + } + + const result = await response.json(); + + return { + content: result.message.content, + raw: result + }; + } catch (error) { + console.error('Ollama chat error:', error); + throw error; + } + } + }; +} + +function createStreamingLLM({ + model, + temperature = 0.7, + maxTokens = 2048, + baseUrl = 'http://localhost:11434', + ...config +}) { + if (!model) { + throw new Error('Model parameter is required for Ollama streaming LLM. Please specify a model name (e.g., "llama3.2:latest", "gemma3:4b")'); + } + return { + streamChat: async (messages) => { + console.log('[Ollama Provider] Starting streaming request'); + + const ollamaMessages = convertMessagesToOllamaFormat(messages); + console.log('[Ollama Provider] Converted messages for Ollama:', ollamaMessages); + + try { + const response = await fetch(`${baseUrl}/api/chat`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + model, + messages: ollamaMessages, + stream: true, + options: { + temperature, + num_predict: maxTokens, + } + }) + }); + + if (!response.ok) { + throw new Error(`Ollama API error: ${response.status} ${response.statusText}`); + } + + console.log('[Ollama Provider] Got streaming response'); + + const stream = new ReadableStream({ + async start(controller) { + let buffer = ''; + + try { + response.body.on('data', (chunk) => { + buffer += chunk.toString(); + const lines = buffer.split('\n'); + buffer = lines.pop() || ''; + + for (const line of lines) { + if (line.trim() === '') continue; + + try { + const data = JSON.parse(line); + + if (data.message?.content) { + const sseData = JSON.stringify({ + choices: [{ + delta: { + content: data.message.content + } + }] + }); + controller.enqueue(new TextEncoder().encode(`data: ${sseData}\n\n`)); + } + + if (data.done) { + controller.enqueue(new TextEncoder().encode('data: [DONE]\n\n')); + } + } catch (e) { + console.error('[Ollama Provider] Failed to parse chunk:', e); + } + } + }); + + response.body.on('end', () => { + controller.close(); + console.log('[Ollama Provider] Streaming completed'); + }); + + response.body.on('error', (error) => { + console.error('[Ollama Provider] Streaming error:', error); + controller.error(error); + }); + + } catch (error) { + console.error('[Ollama Provider] Streaming setup error:', error); + controller.error(error); + } + } + }); + + return { + ok: true, + body: stream + }; + + } catch (error) { + console.error('[Ollama Provider] Request error:', error); + throw error; + } + } + }; +} + +module.exports = { + createLLM, + createStreamingLLM +}; \ No newline at end of file diff --git a/src/common/ai/providers/whisper.js b/src/common/ai/providers/whisper.js new file mode 100644 index 0000000..abeaa06 --- /dev/null +++ b/src/common/ai/providers/whisper.js @@ -0,0 +1,231 @@ +let spawn, path, EventEmitter; + +if (typeof window === 'undefined') { + spawn = require('child_process').spawn; + path = require('path'); + EventEmitter = require('events').EventEmitter; +} else { + class DummyEventEmitter { + on() {} + emit() {} + removeAllListeners() {} + } + EventEmitter = DummyEventEmitter; +} + +class WhisperSTTSession extends EventEmitter { + constructor(model, whisperService, sessionId) { + super(); + this.model = model; + this.whisperService = whisperService; + this.sessionId = sessionId || `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; + this.process = null; + this.isRunning = false; + this.audioBuffer = Buffer.alloc(0); + this.processingInterval = null; + this.lastTranscription = ''; + } + + async initialize() { + try { + await this.whisperService.ensureModelAvailable(this.model); + this.isRunning = true; + this.startProcessingLoop(); + return true; + } catch (error) { + console.error('[WhisperSTT] Initialization error:', error); + this.emit('error', error); + return false; + } + } + + startProcessingLoop() { + this.processingInterval = setInterval(async () => { + const minBufferSize = 24000 * 2 * 0.15; + if (this.audioBuffer.length >= minBufferSize && !this.process) { + console.log(`[WhisperSTT-${this.sessionId}] Processing audio chunk, buffer size: ${this.audioBuffer.length}`); + await this.processAudioChunk(); + } + }, 1500); + } + + async processAudioChunk() { + if (!this.isRunning || this.audioBuffer.length === 0) return; + + const audioData = this.audioBuffer; + this.audioBuffer = Buffer.alloc(0); + + try { + const tempFile = await this.whisperService.saveAudioToTemp(audioData, this.sessionId); + + if (!tempFile || typeof tempFile !== 'string') { + console.error('[WhisperSTT] Invalid temp file path:', tempFile); + return; + } + + const whisperPath = await this.whisperService.getWhisperPath(); + const modelPath = await this.whisperService.getModelPath(this.model); + + if (!whisperPath || !modelPath) { + console.error('[WhisperSTT] Invalid whisper or model path:', { whisperPath, modelPath }); + return; + } + + this.process = spawn(whisperPath, [ + '-m', modelPath, + '-f', tempFile, + '--no-timestamps', + '--output-txt', + '--output-json', + '--language', 'auto', + '--threads', '4', + '--print-progress', 'false' + ]); + + let output = ''; + let errorOutput = ''; + + this.process.stdout.on('data', (data) => { + output += data.toString(); + }); + + this.process.stderr.on('data', (data) => { + errorOutput += data.toString(); + }); + + this.process.on('close', async (code) => { + this.process = null; + + if (code === 0 && output.trim()) { + const transcription = output.trim(); + if (transcription && transcription !== this.lastTranscription) { + this.lastTranscription = transcription; + console.log(`[WhisperSTT-${this.sessionId}] Transcription: "${transcription}"`); + this.emit('transcription', { + text: transcription, + timestamp: Date.now(), + confidence: 1.0, + sessionId: this.sessionId + }); + } + } else if (errorOutput) { + console.error(`[WhisperSTT-${this.sessionId}] Process error:`, errorOutput); + } + + await this.whisperService.cleanupTempFile(tempFile); + }); + + } catch (error) { + console.error('[WhisperSTT] Processing error:', error); + this.emit('error', error); + } + } + + sendRealtimeInput(audioData) { + if (!this.isRunning) { + console.warn(`[WhisperSTT-${this.sessionId}] Session not running, cannot accept audio`); + return; + } + + if (typeof audioData === 'string') { + try { + audioData = Buffer.from(audioData, 'base64'); + } catch (error) { + console.error('[WhisperSTT] Failed to decode base64 audio data:', error); + return; + } + } else if (audioData instanceof ArrayBuffer) { + audioData = Buffer.from(audioData); + } else if (!Buffer.isBuffer(audioData) && !(audioData instanceof Uint8Array)) { + console.error('[WhisperSTT] Invalid audio data type:', typeof audioData); + return; + } + + if (!Buffer.isBuffer(audioData)) { + audioData = Buffer.from(audioData); + } + + if (audioData.length > 0) { + this.audioBuffer = Buffer.concat([this.audioBuffer, audioData]); + // Log every 10th audio chunk to avoid spam + if (Math.random() < 0.1) { + console.log(`[WhisperSTT-${this.sessionId}] Received audio chunk: ${audioData.length} bytes, total buffer: ${this.audioBuffer.length} bytes`); + } + } + } + + async close() { + console.log(`[WhisperSTT-${this.sessionId}] Closing session`); + this.isRunning = false; + + if (this.processingInterval) { + clearInterval(this.processingInterval); + this.processingInterval = null; + } + + if (this.process) { + this.process.kill('SIGTERM'); + this.process = null; + } + + this.removeAllListeners(); + } +} + +class WhisperProvider { + constructor() { + this.whisperService = null; + } + + async initialize() { + if (!this.whisperService) { + const { WhisperService } = require('../../services/whisperService'); + this.whisperService = new WhisperService(); + await this.whisperService.initialize(); + } + } + + async createSTT(config) { + await this.initialize(); + + const model = config.model || 'whisper-tiny'; + const sessionType = config.sessionType || 'unknown'; + console.log(`[WhisperProvider] Creating ${sessionType} STT session with model: ${model}`); + + // Create unique session ID based on type + const sessionId = `${sessionType}_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`; + const session = new WhisperSTTSession(model, this.whisperService, sessionId); + + // Log session creation + console.log(`[WhisperProvider] Created session: ${sessionId}`); + + const initialized = await session.initialize(); + if (!initialized) { + throw new Error('Failed to initialize Whisper STT session'); + } + + if (config.callbacks) { + if (config.callbacks.onmessage) { + session.on('transcription', config.callbacks.onmessage); + } + if (config.callbacks.onerror) { + session.on('error', config.callbacks.onerror); + } + if (config.callbacks.onclose) { + session.on('close', config.callbacks.onclose); + } + } + + return session; + } + + async createLLM() { + throw new Error('Whisper provider does not support LLM functionality'); + } + + async createStreamingLLM() { + throw new Error('Whisper provider does not support streaming LLM functionality'); + } +} + +module.exports = new WhisperProvider(); \ No newline at end of file diff --git a/src/common/config/checksums.js b/src/common/config/checksums.js new file mode 100644 index 0000000..ff903cc --- /dev/null +++ b/src/common/config/checksums.js @@ -0,0 +1,46 @@ +const DOWNLOAD_CHECKSUMS = { + ollama: { + dmg: { + url: 'https://ollama.com/download/Ollama.dmg', + sha256: null // To be updated with actual checksum + }, + exe: { + url: 'https://ollama.com/download/OllamaSetup.exe', + sha256: null // To be updated with actual checksum + } + }, + whisper: { + models: { + 'whisper-tiny': { + url: 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.bin', + sha256: 'be07e048e1e599ad46341c8d2a135645097a538221678b7acdd1b1919c6e1b21' + }, + 'whisper-base': { + url: 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.bin', + sha256: '60ed5bc3dd14eea856493d334349b405782ddcaf0028d4b5df4088345fba2efe' + }, + 'whisper-small': { + url: 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin', + sha256: '1be3a9b2063867b937e64e2ec7483364a79917e157fa98c5d94b5c1fffea987b' + }, + 'whisper-medium': { + url: 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-medium.bin', + sha256: '6c14d5adee5f86394037b4e4e8b59f1673b6cee10e3cf0b11bbdbee79c156208' + } + }, + binaries: { + 'v1.7.6': { + windows: { + url: 'https://github.com/ggerganov/whisper.cpp/releases/download/v1.7.6/whisper-cpp-v1.7.6-win-x64.zip', + sha256: null // To be updated with actual checksum + }, + linux: { + url: 'https://github.com/ggerganov/whisper.cpp/releases/download/v1.7.6/whisper-cpp-v1.7.6-linux-x64.tar.gz', + sha256: null // To be updated with actual checksum + } + } + } + } +}; + +module.exports = { DOWNLOAD_CHECKSUMS }; \ No newline at end of file diff --git a/src/common/config/schema.js b/src/common/config/schema.js index 1db6de3..4dfc4ba 100644 --- a/src/common/config/schema.js +++ b/src/common/config/schema.js @@ -73,6 +73,23 @@ const LATEST_SCHEMA = { { name: 'created_at', type: 'INTEGER' }, { name: 'sync_state', type: 'TEXT DEFAULT \'clean\'' } ] + }, + ollama_models: { + columns: [ + { name: 'name', type: 'TEXT PRIMARY KEY' }, + { name: 'size', type: 'TEXT NOT NULL' }, + { name: 'installed', type: 'INTEGER DEFAULT 0' }, + { name: 'installing', type: 'INTEGER DEFAULT 0' } + ] + }, + whisper_models: { + columns: [ + { name: 'id', type: 'TEXT PRIMARY KEY' }, + { name: 'name', type: 'TEXT NOT NULL' }, + { name: 'size', type: 'TEXT NOT NULL' }, + { name: 'installed', type: 'INTEGER DEFAULT 0' }, + { name: 'installing', type: 'INTEGER DEFAULT 0' } + ] } }; diff --git a/src/common/repositories/ollamaModel/index.js b/src/common/repositories/ollamaModel/index.js new file mode 100644 index 0000000..bb924b5 --- /dev/null +++ b/src/common/repositories/ollamaModel/index.js @@ -0,0 +1,20 @@ +const sqliteRepository = require('./sqlite.repository'); + +// For now, we only use SQLite repository +// In the future, we could add cloud sync support + +function getRepository() { + return sqliteRepository; +} + +// Export all repository methods +module.exports = { + getAllModels: (...args) => getRepository().getAllModels(...args), + getModel: (...args) => getRepository().getModel(...args), + upsertModel: (...args) => getRepository().upsertModel(...args), + updateInstallStatus: (...args) => getRepository().updateInstallStatus(...args), + initializeDefaultModels: (...args) => getRepository().initializeDefaultModels(...args), + deleteModel: (...args) => getRepository().deleteModel(...args), + getInstalledModels: (...args) => getRepository().getInstalledModels(...args), + getInstallingModels: (...args) => getRepository().getInstallingModels(...args) +}; \ No newline at end of file diff --git a/src/common/repositories/ollamaModel/sqlite.repository.js b/src/common/repositories/ollamaModel/sqlite.repository.js new file mode 100644 index 0000000..a7a3361 --- /dev/null +++ b/src/common/repositories/ollamaModel/sqlite.repository.js @@ -0,0 +1,137 @@ +const sqliteClient = require('../../services/sqliteClient'); + +/** + * Get all Ollama models + */ +function getAllModels() { + const db = sqliteClient.getDb(); + const query = 'SELECT * FROM ollama_models ORDER BY name'; + + try { + return db.prepare(query).all() || []; + } catch (err) { + console.error('[OllamaModel Repository] Failed to get models:', err); + throw err; + } +} + +/** + * Get a specific model by name + */ +function getModel(name) { + const db = sqliteClient.getDb(); + const query = 'SELECT * FROM ollama_models WHERE name = ?'; + + try { + return db.prepare(query).get(name); + } catch (err) { + console.error('[OllamaModel Repository] Failed to get model:', err); + throw err; + } +} + +/** + * Create or update a model entry + */ +function upsertModel({ name, size, installed = false, installing = false }) { + const db = sqliteClient.getDb(); + const query = ` + INSERT INTO ollama_models (name, size, installed, installing) + VALUES (?, ?, ?, ?) + ON CONFLICT(name) DO UPDATE SET + size = excluded.size, + installed = excluded.installed, + installing = excluded.installing + `; + + try { + db.prepare(query).run(name, size, installed ? 1 : 0, installing ? 1 : 0); + return { success: true }; + } catch (err) { + console.error('[OllamaModel Repository] Failed to upsert model:', err); + throw err; + } +} + +/** + * Update installation status for a model + */ +function updateInstallStatus(name, installed, installing = false) { + const db = sqliteClient.getDb(); + const query = 'UPDATE ollama_models SET installed = ?, installing = ? WHERE name = ?'; + + try { + const result = db.prepare(query).run(installed ? 1 : 0, installing ? 1 : 0, name); + return { success: true, changes: result.changes }; + } catch (err) { + console.error('[OllamaModel Repository] Failed to update install status:', err); + throw err; + } +} + +/** + * Initialize default models - now done dynamically based on installed models + */ +function initializeDefaultModels() { + // Default models are now detected dynamically from Ollama installation + // This function maintains compatibility but doesn't hardcode any models + console.log('[OllamaModel Repository] Default models initialization skipped - using dynamic detection'); + return { success: true }; +} + +/** + * Delete a model entry + */ +function deleteModel(name) { + const db = sqliteClient.getDb(); + const query = 'DELETE FROM ollama_models WHERE name = ?'; + + try { + const result = db.prepare(query).run(name); + return { success: true, changes: result.changes }; + } catch (err) { + console.error('[OllamaModel Repository] Failed to delete model:', err); + throw err; + } +} + +/** + * Get installed models + */ +function getInstalledModels() { + const db = sqliteClient.getDb(); + const query = 'SELECT * FROM ollama_models WHERE installed = 1 ORDER BY name'; + + try { + return db.prepare(query).all() || []; + } catch (err) { + console.error('[OllamaModel Repository] Failed to get installed models:', err); + throw err; + } +} + +/** + * Get models currently being installed + */ +function getInstallingModels() { + const db = sqliteClient.getDb(); + const query = 'SELECT * FROM ollama_models WHERE installing = 1 ORDER BY name'; + + try { + return db.prepare(query).all() || []; + } catch (err) { + console.error('[OllamaModel Repository] Failed to get installing models:', err); + throw err; + } +} + +module.exports = { + getAllModels, + getModel, + upsertModel, + updateInstallStatus, + initializeDefaultModels, + deleteModel, + getInstalledModels, + getInstallingModels +}; \ No newline at end of file diff --git a/src/common/repositories/whisperModel/index.js b/src/common/repositories/whisperModel/index.js new file mode 100644 index 0000000..d796e24 --- /dev/null +++ b/src/common/repositories/whisperModel/index.js @@ -0,0 +1,53 @@ +const BaseModelRepository = require('../baseModel'); + +class WhisperModelRepository extends BaseModelRepository { + constructor(db, tableName = 'whisper_models') { + super(db, tableName); + } + + async initializeModels(availableModels) { + const existingModels = await this.getAll(); + const existingIds = new Set(existingModels.map(m => m.id)); + + for (const [modelId, modelInfo] of Object.entries(availableModels)) { + if (!existingIds.has(modelId)) { + await this.create({ + id: modelId, + name: modelInfo.name, + size: modelInfo.size, + installed: 0, + installing: 0 + }); + } + } + } + + async getInstalledModels() { + return this.findAll({ installed: 1 }); + } + + async setInstalled(modelId, installed = true) { + return this.update({ id: modelId }, { + installed: installed ? 1 : 0, + installing: 0 + }); + } + + async setInstalling(modelId, installing = true) { + return this.update({ id: modelId }, { + installing: installing ? 1 : 0 + }); + } + + async isInstalled(modelId) { + const model = await this.findOne({ id: modelId }); + return model && model.installed === 1; + } + + async isInstalling(modelId) { + const model = await this.findOne({ id: modelId }); + return model && model.installing === 1; + } +} + +module.exports = WhisperModelRepository; \ No newline at end of file diff --git a/src/common/services/cryptoService.js b/src/common/services/cryptoService.js new file mode 100644 index 0000000..79935e4 --- /dev/null +++ b/src/common/services/cryptoService.js @@ -0,0 +1,89 @@ +const crypto = require('crypto'); +const { app } = require('electron'); +const os = require('os'); + +class CryptoService { + constructor() { + this.algorithm = 'aes-256-gcm'; + this.saltLength = 32; + this.tagLength = 16; + this.ivLength = 16; + this.iterations = 100000; + this.keyLength = 32; + this._derivedKey = null; + } + + _getMachineId() { + const machineInfo = `${os.hostname()}-${os.platform()}-${os.arch()}`; + const appPath = app.getPath('userData'); + return crypto.createHash('sha256').update(machineInfo + appPath).digest('hex'); + } + + _deriveKey() { + if (this._derivedKey) return this._derivedKey; + + const machineId = this._getMachineId(); + const salt = crypto.createHash('sha256').update('pickle-glass-salt').digest(); + this._derivedKey = crypto.pbkdf2Sync(machineId, salt, this.iterations, this.keyLength, 'sha256'); + return this._derivedKey; + } + + encrypt(text) { + if (!text) return null; + + try { + const iv = crypto.randomBytes(this.ivLength); + const salt = crypto.randomBytes(this.saltLength); + const key = this._deriveKey(); + + const cipher = crypto.createCipheriv(this.algorithm, key, iv); + + const encrypted = Buffer.concat([ + cipher.update(text, 'utf8'), + cipher.final() + ]); + + const tag = cipher.getAuthTag(); + + const combined = Buffer.concat([salt, iv, tag, encrypted]); + return combined.toString('base64'); + } catch (error) { + console.error('[CryptoService] Encryption failed:', error.message); + throw new Error('Encryption failed'); + } + } + + decrypt(encryptedData) { + if (!encryptedData) return null; + + try { + const combined = Buffer.from(encryptedData, 'base64'); + + const salt = combined.slice(0, this.saltLength); + const iv = combined.slice(this.saltLength, this.saltLength + this.ivLength); + const tag = combined.slice(this.saltLength + this.ivLength, this.saltLength + this.ivLength + this.tagLength); + const encrypted = combined.slice(this.saltLength + this.ivLength + this.tagLength); + + const key = this._deriveKey(); + + const decipher = crypto.createDecipheriv(this.algorithm, key, iv); + decipher.setAuthTag(tag); + + const decrypted = Buffer.concat([ + decipher.update(encrypted), + decipher.final() + ]); + + return decrypted.toString('utf8'); + } catch (error) { + console.error('[CryptoService] Decryption failed:', error.message); + throw new Error('Decryption failed'); + } + } + + clearCache() { + this._derivedKey = null; + } +} + +module.exports = new CryptoService(); \ No newline at end of file diff --git a/src/common/services/localAIServiceBase.js b/src/common/services/localAIServiceBase.js new file mode 100644 index 0000000..45db41b --- /dev/null +++ b/src/common/services/localAIServiceBase.js @@ -0,0 +1,277 @@ +const { exec } = require('child_process'); +const { promisify } = require('util'); +const { EventEmitter } = require('events'); +const path = require('path'); +const os = require('os'); +const https = require('https'); +const fs = require('fs'); +const crypto = require('crypto'); + +const execAsync = promisify(exec); + +class LocalAIServiceBase extends EventEmitter { + constructor(serviceName) { + super(); + this.serviceName = serviceName; + this.baseUrl = null; + this.installationProgress = new Map(); + } + + getPlatform() { + return process.platform; + } + + async checkCommand(command) { + try { + const platform = this.getPlatform(); + const checkCmd = platform === 'win32' ? 'where' : 'which'; + const { stdout } = await execAsync(`${checkCmd} ${command}`); + return stdout.trim(); + } catch (error) { + return null; + } + } + + async isInstalled() { + throw new Error('isInstalled() must be implemented by subclass'); + } + + async isServiceRunning() { + throw new Error('isServiceRunning() must be implemented by subclass'); + } + + async startService() { + throw new Error('startService() must be implemented by subclass'); + } + + async stopService() { + throw new Error('stopService() must be implemented by subclass'); + } + + async waitForService(checkFn, maxAttempts = 30, delayMs = 1000) { + for (let i = 0; i < maxAttempts; i++) { + if (await checkFn()) { + console.log(`[${this.serviceName}] Service is ready`); + return true; + } + await new Promise(resolve => setTimeout(resolve, delayMs)); + } + throw new Error(`${this.serviceName} service failed to start within timeout`); + } + + getInstallProgress(modelName) { + return this.installationProgress.get(modelName) || 0; + } + + setInstallProgress(modelName, progress) { + this.installationProgress.set(modelName, progress); + this.emit('install-progress', { model: modelName, progress }); + } + + clearInstallProgress(modelName) { + this.installationProgress.delete(modelName); + } + + async autoInstall(onProgress) { + const platform = this.getPlatform(); + console.log(`[${this.serviceName}] Starting auto-installation for ${platform}`); + + try { + switch(platform) { + case 'darwin': + return await this.installMacOS(onProgress); + case 'win32': + return await this.installWindows(onProgress); + case 'linux': + return await this.installLinux(); + default: + throw new Error(`Unsupported platform: ${platform}`); + } + } catch (error) { + console.error(`[${this.serviceName}] Auto-installation failed:`, error); + throw error; + } + } + + async installMacOS() { + throw new Error('installMacOS() must be implemented by subclass'); + } + + async installWindows() { + throw new Error('installWindows() must be implemented by subclass'); + } + + async installLinux() { + throw new Error('installLinux() must be implemented by subclass'); + } + + // parseProgress method removed - using proper REST API now + + async shutdown(force = false) { + console.log(`[${this.serviceName}] Starting ${force ? 'forced' : 'graceful'} shutdown...`); + + const isRunning = await this.isServiceRunning(); + if (!isRunning) { + console.log(`[${this.serviceName}] Service not running, nothing to shutdown`); + return true; + } + + const platform = this.getPlatform(); + + try { + switch(platform) { + case 'darwin': + return await this.shutdownMacOS(force); + case 'win32': + return await this.shutdownWindows(force); + case 'linux': + return await this.shutdownLinux(force); + default: + console.warn(`[${this.serviceName}] Unsupported platform for shutdown: ${platform}`); + return false; + } + } catch (error) { + console.error(`[${this.serviceName}] Error during shutdown:`, error); + return false; + } + } + + async shutdownMacOS(force) { + throw new Error('shutdownMacOS() must be implemented by subclass'); + } + + async shutdownWindows(force) { + throw new Error('shutdownWindows() must be implemented by subclass'); + } + + async shutdownLinux(force) { + throw new Error('shutdownLinux() must be implemented by subclass'); + } + + async downloadFile(url, destination, options = {}) { + const { + onProgress = null, + headers = { 'User-Agent': 'Glass-App' }, + timeout = 300000 // 5 minutes default + } = options; + + return new Promise((resolve, reject) => { + const file = fs.createWriteStream(destination); + let downloadedSize = 0; + let totalSize = 0; + + const request = https.get(url, { headers }, (response) => { + // Handle redirects (301, 302, 307, 308) + if ([301, 302, 307, 308].includes(response.statusCode)) { + file.close(); + fs.unlink(destination, () => {}); + + if (!response.headers.location) { + reject(new Error('Redirect without location header')); + return; + } + + console.log(`[${this.serviceName}] Following redirect from ${url} to ${response.headers.location}`); + this.downloadFile(response.headers.location, destination, options) + .then(resolve) + .catch(reject); + return; + } + + if (response.statusCode !== 200) { + file.close(); + fs.unlink(destination, () => {}); + reject(new Error(`Download failed: ${response.statusCode} ${response.statusMessage}`)); + return; + } + + totalSize = parseInt(response.headers['content-length'], 10) || 0; + + response.on('data', (chunk) => { + downloadedSize += chunk.length; + + if (onProgress && totalSize > 0) { + const progress = Math.round((downloadedSize / totalSize) * 100); + onProgress(progress, downloadedSize, totalSize); + } + }); + + response.pipe(file); + + file.on('finish', () => { + file.close(() => { + this.emit('download-complete', { url, destination, size: downloadedSize }); + resolve({ success: true, size: downloadedSize }); + }); + }); + }); + + request.on('timeout', () => { + request.destroy(); + file.close(); + fs.unlink(destination, () => {}); + reject(new Error('Download timeout')); + }); + + request.on('error', (err) => { + file.close(); + fs.unlink(destination, () => {}); + this.emit('download-error', { url, error: err }); + reject(err); + }); + + request.setTimeout(timeout); + + file.on('error', (err) => { + fs.unlink(destination, () => {}); + reject(err); + }); + }); + } + + async downloadWithRetry(url, destination, options = {}) { + const { maxRetries = 3, retryDelay = 1000, expectedChecksum = null, ...downloadOptions } = options; + + for (let attempt = 1; attempt <= maxRetries; attempt++) { + try { + const result = await this.downloadFile(url, destination, downloadOptions); + + if (expectedChecksum) { + const isValid = await this.verifyChecksum(destination, expectedChecksum); + if (!isValid) { + fs.unlinkSync(destination); + throw new Error('Checksum verification failed'); + } + console.log(`[${this.serviceName}] Checksum verified successfully`); + } + + return result; + } catch (error) { + if (attempt === maxRetries) { + throw error; + } + + console.log(`Download attempt ${attempt} failed, retrying in ${retryDelay}ms...`); + await new Promise(resolve => setTimeout(resolve, retryDelay * attempt)); + } + } + } + + async verifyChecksum(filePath, expectedChecksum) { + return new Promise((resolve, reject) => { + const hash = crypto.createHash('sha256'); + const stream = fs.createReadStream(filePath); + + stream.on('data', (data) => hash.update(data)); + stream.on('end', () => { + const fileChecksum = hash.digest('hex'); + console.log(`[${this.serviceName}] File checksum: ${fileChecksum}`); + console.log(`[${this.serviceName}] Expected checksum: ${expectedChecksum}`); + resolve(fileChecksum === expectedChecksum); + }); + stream.on('error', reject); + }); + } +} + +module.exports = LocalAIServiceBase; \ No newline at end of file diff --git a/src/common/services/localProgressTracker.js b/src/common/services/localProgressTracker.js new file mode 100644 index 0000000..48f5fcb --- /dev/null +++ b/src/common/services/localProgressTracker.js @@ -0,0 +1,133 @@ +export class LocalProgressTracker { + constructor(serviceName) { + this.serviceName = serviceName; + this.activeOperations = new Map(); // operationId -> { controller, onProgress } + this.ipcRenderer = window.require?.('electron')?.ipcRenderer; + + if (!this.ipcRenderer) { + throw new Error(`${serviceName} requires Electron environment`); + } + + this.globalProgressHandler = (event, data) => { + const operation = this.activeOperations.get(data.model || data.modelId); + if (operation && !operation.controller.signal.aborted) { + operation.onProgress(data.progress); + } + }; + + const progressEvents = { + 'ollama': 'ollama:pull-progress', + 'whisper': 'whisper:download-progress' + }; + + const eventName = progressEvents[serviceName.toLowerCase()] || `${serviceName}:progress`; + this.progressEvent = eventName; + this.ipcRenderer.on(eventName, this.globalProgressHandler); + } + + async trackOperation(operationId, operationType, onProgress) { + if (this.activeOperations.has(operationId)) { + throw new Error(`${operationType} ${operationId} is already in progress`); + } + + const controller = new AbortController(); + const operation = { controller, onProgress }; + this.activeOperations.set(operationId, operation); + + try { + const ipcChannels = { + 'ollama': { install: 'ollama:pull-model' }, + 'whisper': { download: 'whisper:download-model' } + }; + + const channel = ipcChannels[this.serviceName.toLowerCase()]?.[operationType] || + `${this.serviceName}:${operationType}`; + + const result = await this.ipcRenderer.invoke(channel, operationId); + + if (!result.success) { + throw new Error(result.error || `${operationType} failed`); + } + + return true; + } catch (error) { + if (!controller.signal.aborted) { + throw error; + } + return false; + } finally { + this.activeOperations.delete(operationId); + } + } + + async installModel(modelName, onProgress) { + return this.trackOperation(modelName, 'install', onProgress); + } + + async downloadModel(modelId, onProgress) { + return this.trackOperation(modelId, 'download', onProgress); + } + + cancelOperation(operationId) { + const operation = this.activeOperations.get(operationId); + if (operation) { + operation.controller.abort(); + this.activeOperations.delete(operationId); + } + } + + cancelAllOperations() { + for (const [operationId, operation] of this.activeOperations) { + operation.controller.abort(); + } + this.activeOperations.clear(); + } + + isOperationActive(operationId) { + return this.activeOperations.has(operationId); + } + + getActiveOperations() { + return Array.from(this.activeOperations.keys()); + } + + destroy() { + this.cancelAllOperations(); + if (this.ipcRenderer) { + this.ipcRenderer.removeListener(this.progressEvent, this.globalProgressHandler); + } + } +} + +let trackers = new Map(); + +export function getLocalProgressTracker(serviceName) { + if (!trackers.has(serviceName)) { + trackers.set(serviceName, new LocalProgressTracker(serviceName)); + } + return trackers.get(serviceName); +} + +export function destroyLocalProgressTracker(serviceName) { + const tracker = trackers.get(serviceName); + if (tracker) { + tracker.destroy(); + trackers.delete(serviceName); + } +} + +export function destroyAllProgressTrackers() { + for (const [name, tracker] of trackers) { + tracker.destroy(); + } + trackers.clear(); +} + +// Legacy compatibility exports +export function getOllamaProgressTracker() { + return getLocalProgressTracker('ollama'); +} + +export function destroyOllamaProgressTracker() { + destroyLocalProgressTracker('ollama'); +} \ No newline at end of file diff --git a/src/common/services/modelStateService.js b/src/common/services/modelStateService.js index 7218ce7..eacbfd5 100644 --- a/src/common/services/modelStateService.js +++ b/src/common/services/modelStateService.js @@ -2,6 +2,7 @@ const Store = require('electron-store'); const fetch = require('node-fetch'); const { ipcMain, webContents } = require('electron'); const { PROVIDERS } = require('../ai/factory'); +const cryptoService = require('./cryptoService'); class ModelStateService { constructor(authService) { @@ -23,7 +24,7 @@ class ModelStateService { const llmProvider = this.getProviderForModel('llm', llmModel) || 'None'; const sttProvider = this.getProviderForModel('stt', sttModel) || 'None'; - console.log(`[ModelStateService] 🌟 Current Selection -> LLM: ${llmModel || 'None'} (Provider: ${llmProvider}), STT: ${sttModel || 'None'} (Provider: ${sttProvider})`); + console.log(`[ModelStateService] Current Selection -> LLM: ${llmModel || 'None'} (Provider: ${llmProvider}), STT: ${sttModel || 'None'} (Provider: ${sttProvider})`); } _autoSelectAvailableModels() { @@ -36,7 +37,9 @@ class ModelStateService { if (currentModelId) { const provider = this.getProviderForModel(type, currentModelId); - if (provider && this.getApiKey(provider)) { + const apiKey = this.getApiKey(provider); + // For Ollama, 'local' is a valid API key + if (provider && (apiKey || (provider === 'ollama' && apiKey === 'local'))) { isCurrentModelValid = true; } } @@ -45,8 +48,15 @@ class ModelStateService { console.log(`[ModelStateService] No valid ${type.toUpperCase()} model selected. Finding an alternative...`); const availableModels = this.getAvailableModels(type); if (availableModels.length > 0) { - this.state.selectedModels[type] = availableModels[0].id; - console.log(`[ModelStateService] Auto-selected ${type.toUpperCase()} model: ${availableModels[0].id}`); + // Prefer API providers over local providers for auto-selection + const apiModel = availableModels.find(model => { + const provider = this.getProviderForModel(type, model.id); + return provider && provider !== 'ollama' && provider !== 'whisper'; + }); + + const selectedModel = apiModel || availableModels[0]; + this.state.selectedModels[type] = selectedModel.id; + console.log(`[ModelStateService] Auto-selected ${type.toUpperCase()} model: ${selectedModel.id} (preferred: ${apiModel ? 'API' : 'local'})`); } else { this.state.selectedModels[type] = null; } @@ -67,11 +77,20 @@ class ModelStateService { }; this.state = this.store.get(`users.${userId}`, defaultState); console.log(`[ModelStateService] State loaded for user: ${userId}`); + for (const p of Object.keys(PROVIDERS)) { - if (!(p in this.state.apiKeys)) { + if (!(p in this.state.apiKeys)) { + this.state.apiKeys[p] = null; + } else if (this.state.apiKeys[p] && p !== 'ollama' && p !== 'whisper') { + try { + this.state.apiKeys[p] = cryptoService.decrypt(this.state.apiKeys[p]); + } catch (error) { + console.error(`[ModelStateService] Failed to decrypt API key for ${p}, resetting`); this.state.apiKeys[p] = null; } } + } + this._autoSelectAvailableModels(); this._saveState(); this._logCurrentSelection(); @@ -80,7 +99,23 @@ class ModelStateService { _saveState() { const userId = this.authService.getCurrentUserId(); - this.store.set(`users.${userId}`, this.state); + const stateToSave = { + ...this.state, + apiKeys: { ...this.state.apiKeys } + }; + + for (const [provider, key] of Object.entries(stateToSave.apiKeys)) { + if (key && provider !== 'ollama' && provider !== 'whisper') { + try { + stateToSave.apiKeys[provider] = cryptoService.encrypt(key); + } catch (error) { + console.error(`[ModelStateService] Failed to encrypt API key for ${provider}`); + stateToSave.apiKeys[provider] = null; + } + } + } + + this.store.set(`users.${userId}`, stateToSave); console.log(`[ModelStateService] State saved for user: ${userId}`); this._logCurrentSelection(); } @@ -94,6 +129,26 @@ class ModelStateService { const body = undefined; switch (provider) { + case 'ollama': + // Ollama doesn't need API key validation + // Just check if the service is running + try { + const response = await fetch('http://localhost:11434/api/tags'); + if (response.ok) { + console.log(`[ModelStateService] Ollama service is accessible.`); + this.setApiKey(provider, 'local'); // Use 'local' as a placeholder + return { success: true }; + } else { + return { success: false, error: 'Ollama service is not running. Please start Ollama first.' }; + } + } catch (error) { + return { success: false, error: 'Cannot connect to Ollama. Please ensure Ollama is installed and running.' }; + } + case 'whisper': + // Whisper is a local service, no API key validation needed + console.log(`[ModelStateService] Whisper is a local service.`); + this.setApiKey(provider, 'local'); // Use 'local' as a placeholder + return { success: true }; case 'openai': validationUrl = 'https://api.openai.com/v1/models'; headers = { 'Authorization': `Bearer ${key}` }; @@ -176,11 +231,19 @@ class ModelStateService { const llmModels = PROVIDERS[provider]?.llmModels; const sttModels = PROVIDERS[provider]?.sttModels; - if (!this.state.selectedModels.llm && llmModels?.length > 0) { - this.state.selectedModels.llm = llmModels[0].id; + // Prioritize newly set API key provider over existing selections + // Only for non-local providers or if no model is currently selected + if (llmModels?.length > 0) { + if (!this.state.selectedModels.llm || provider !== 'ollama') { + this.state.selectedModels.llm = llmModels[0].id; + console.log(`[ModelStateService] Selected LLM model from newly configured provider ${provider}: ${llmModels[0].id}`); + } } - if (!this.state.selectedModels.stt && sttModels?.length > 0) { - this.state.selectedModels.stt = sttModels[0].id; + if (sttModels?.length > 0) { + if (!this.state.selectedModels.stt || provider !== 'whisper') { + this.state.selectedModels.stt = sttModels[0].id; + console.log(`[ModelStateService] Selected STT model from newly configured provider ${provider}: ${sttModels[0].id}`); + } } this._saveState(); this._logCurrentSelection(); @@ -223,6 +286,14 @@ class ModelStateService { return providerId; } } + + // If no provider was found, assume it could be a custom Ollama model + // if Ollama provider is configured (has a key). + if (type === 'llm' && this.state.apiKeys['ollama']) { + console.log(`[ModelStateService] Model '${modelId}' not found in PROVIDERS list, assuming it's a custom Ollama model.`); + return 'ollama'; + } + return null; } @@ -239,10 +310,33 @@ class ModelStateService { if (this.isLoggedInWithFirebase()) return true; // LLM과 STT 모델을 제공하는 Provider 중 하나라도 API 키가 설정되었는지 확인 - const hasLlmKey = Object.entries(this.state.apiKeys).some(([provider, key]) => key && PROVIDERS[provider]?.llmModels.length > 0); - const hasSttKey = Object.entries(this.state.apiKeys).some(([provider, key]) => key && PROVIDERS[provider]?.sttModels.length > 0); + const hasLlmKey = Object.entries(this.state.apiKeys).some(([provider, key]) => { + if (provider === 'ollama') { + // Ollama uses dynamic models, so just check if configured (has 'local' key) + return key === 'local'; + } + if (provider === 'whisper') { + // Whisper doesn't support LLM + return false; + } + return key && PROVIDERS[provider]?.llmModels.length > 0; + }); - return hasLlmKey && hasSttKey; + const hasSttKey = Object.entries(this.state.apiKeys).some(([provider, key]) => { + if (provider === 'whisper') { + // Whisper has static model list and supports STT + return key === 'local' && PROVIDERS[provider]?.sttModels.length > 0; + } + if (provider === 'ollama') { + // Ollama doesn't support STT yet + return false; + } + return key && PROVIDERS[provider]?.sttModels.length > 0; + }); + + const result = hasLlmKey && hasSttKey; + console.log(`[ModelStateService] areProvidersConfigured: LLM=${hasLlmKey}, STT=${hasSttKey}, result=${result}`); + return result; } @@ -265,13 +359,58 @@ class ModelStateService { setSelectedModel(type, modelId) { const provider = this.getProviderForModel(type, modelId); if (provider && this.state.apiKeys[provider]) { + const previousModel = this.state.selectedModels[type]; this.state.selectedModels[type] = modelId; this._saveState(); + + // Auto warm-up for Ollama LLM models when changed + if (type === 'llm' && provider === 'ollama' && modelId !== previousModel) { + this._autoWarmUpOllamaModel(modelId, previousModel); + } + return true; } return false; } + /** + * Auto warm-up Ollama model when LLM selection changes + * @private + * @param {string} newModelId - The newly selected model + * @param {string} previousModelId - The previously selected model + */ + async _autoWarmUpOllamaModel(newModelId, previousModelId) { + try { + console.log(`[ModelStateService] 🔥 LLM model changed: ${previousModelId || 'None'} → ${newModelId}, triggering warm-up`); + + // Get Ollama service if available + const ollamaService = require('./ollamaService'); + if (!ollamaService) { + console.log('[ModelStateService] OllamaService not available for auto warm-up'); + return; + } + + // Delay warm-up slightly to allow UI to update first + setTimeout(async () => { + try { + console.log(`[ModelStateService] Starting background warm-up for: ${newModelId}`); + const success = await ollamaService.warmUpModel(newModelId); + + if (success) { + console.log(`[ModelStateService] ✅ Successfully warmed up model: ${newModelId}`); + } else { + console.log(`[ModelStateService] ⚠️ Failed to warm up model: ${newModelId}`); + } + } catch (error) { + console.log(`[ModelStateService] 🚫 Error during auto warm-up for ${newModelId}:`, error.message); + } + }, 500); // 500ms delay + + } catch (error) { + console.error('[ModelStateService] Error in auto warm-up setup:', error); + } + } + /** * * @param {('llm' | 'stt')} type diff --git a/src/common/services/ollamaService.js b/src/common/services/ollamaService.js new file mode 100644 index 0000000..13186d5 --- /dev/null +++ b/src/common/services/ollamaService.js @@ -0,0 +1,809 @@ +const { spawn } = require('child_process'); +const { promisify } = require('util'); +const fetch = require('node-fetch'); +const path = require('path'); +const fs = require('fs').promises; +const { app } = require('electron'); +const LocalAIServiceBase = require('./localAIServiceBase'); +const { spawnAsync } = require('../utils/spawnHelper'); +const { DOWNLOAD_CHECKSUMS } = require('../config/checksums'); + +class OllamaService extends LocalAIServiceBase { + constructor() { + super('OllamaService'); + this.baseUrl = 'http://localhost:11434'; + this.warmingModels = new Map(); + this.warmedModels = new Set(); + this.lastWarmUpAttempt = new Map(); + + // Request management system + this.activeRequests = new Map(); + this.requestTimeouts = new Map(); + this.healthStatus = { + lastHealthCheck: 0, + consecutive_failures: 0, + is_circuit_open: false + }; + + // Configuration + this.requestTimeout = 8000; // 8s for health checks + this.warmupTimeout = 15000; // 15s for model warmup + this.healthCheckInterval = 60000; // 1min between health checks + this.circuitBreakerThreshold = 3; + this.circuitBreakerCooldown = 30000; // 30s + + // Supported models are determined dynamically from installed models + this.supportedModels = {}; + + // Start health monitoring + this._startHealthMonitoring(); + } + + getOllamaCliPath() { + if (this.getPlatform() === 'darwin') { + return '/Applications/Ollama.app/Contents/Resources/ollama'; + } + return 'ollama'; + } + + /** + * Professional request management with AbortController-based cancellation + */ + async _makeRequest(url, options = {}, operationType = 'default') { + const requestId = `${operationType}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; + + // Circuit breaker check + if (this._isCircuitOpen()) { + throw new Error('Service temporarily unavailable (circuit breaker open)'); + } + + // Request deduplication for health checks + if (operationType === 'health' && this.activeRequests.has('health')) { + console.log('[OllamaService] Health check already in progress, returning existing promise'); + return this.activeRequests.get('health'); + } + + const controller = new AbortController(); + const timeout = options.timeout || this.requestTimeout; + + // Set up timeout mechanism + const timeoutId = setTimeout(() => { + controller.abort(); + this.activeRequests.delete(requestId); + this._recordFailure(); + }, timeout); + + this.requestTimeouts.set(requestId, timeoutId); + + const requestPromise = this._executeRequest(url, { + ...options, + signal: controller.signal + }, requestId); + + // Store active request for deduplication and cleanup + this.activeRequests.set(operationType === 'health' ? 'health' : requestId, requestPromise); + + try { + const result = await requestPromise; + this._recordSuccess(); + return result; + } catch (error) { + this._recordFailure(); + if (error.name === 'AbortError') { + throw new Error(`Request timeout after ${timeout}ms`); + } + throw error; + } finally { + clearTimeout(timeoutId); + this.requestTimeouts.delete(requestId); + this.activeRequests.delete(operationType === 'health' ? 'health' : requestId); + } + } + + async _executeRequest(url, options, requestId) { + try { + console.log(`[OllamaService] Executing request ${requestId} to ${url}`); + const response = await fetch(url, options); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + return response; + } catch (error) { + console.error(`[OllamaService] Request ${requestId} failed:`, error.message); + throw error; + } + } + + _isCircuitOpen() { + if (!this.healthStatus.is_circuit_open) return false; + + // Check if cooldown period has passed + const now = Date.now(); + if (now - this.healthStatus.lastHealthCheck > this.circuitBreakerCooldown) { + console.log('[OllamaService] Circuit breaker cooldown expired, attempting recovery'); + this.healthStatus.is_circuit_open = false; + this.healthStatus.consecutive_failures = 0; + return false; + } + + return true; + } + + _recordSuccess() { + this.healthStatus.consecutive_failures = 0; + this.healthStatus.is_circuit_open = false; + this.healthStatus.lastHealthCheck = Date.now(); + } + + _recordFailure() { + this.healthStatus.consecutive_failures++; + this.healthStatus.lastHealthCheck = Date.now(); + + if (this.healthStatus.consecutive_failures >= this.circuitBreakerThreshold) { + console.warn(`[OllamaService] Circuit breaker opened after ${this.healthStatus.consecutive_failures} failures`); + this.healthStatus.is_circuit_open = true; + } + } + + _startHealthMonitoring() { + // Passive health monitoring - only when requests are made + console.log('[OllamaService] Health monitoring system initialized'); + } + + /** + * Cleanup all active requests and resources + */ + _cleanup() { + console.log(`[OllamaService] Cleaning up ${this.activeRequests.size} active requests`); + + // Cancel all active requests + for (const [requestId, promise] of this.activeRequests) { + if (this.requestTimeouts.has(requestId)) { + clearTimeout(this.requestTimeouts.get(requestId)); + this.requestTimeouts.delete(requestId); + } + } + + this.activeRequests.clear(); + this.requestTimeouts.clear(); + } + + async isInstalled() { + try { + const platform = this.getPlatform(); + + if (platform === 'darwin') { + try { + await fs.access('/Applications/Ollama.app'); + return true; + } catch { + const ollamaPath = await this.checkCommand(this.getOllamaCliPath()); + return !!ollamaPath; + } + } else { + const ollamaPath = await this.checkCommand(this.getOllamaCliPath()); + return !!ollamaPath; + } + } catch (error) { + console.log('[OllamaService] Ollama not found:', error.message); + return false; + } + } + + async isServiceRunning() { + try { + const response = await this._makeRequest(`${this.baseUrl}/api/tags`, { + method: 'GET', + timeout: this.requestTimeout + }, 'health'); + + return response.ok; + } catch (error) { + console.log(`[OllamaService] Service health check failed: ${error.message}`); + return false; + } + } + + async startService() { + const platform = this.getPlatform(); + + try { + if (platform === 'darwin') { + try { + await spawnAsync('open', ['-a', 'Ollama']); + await this.waitForService(() => this.isServiceRunning()); + return true; + } catch { + spawn(this.getOllamaCliPath(), ['serve'], { + detached: true, + stdio: 'ignore' + }).unref(); + await this.waitForService(() => this.isServiceRunning()); + return true; + } + } else { + spawn(this.getOllamaCliPath(), ['serve'], { + detached: true, + stdio: 'ignore', + shell: platform === 'win32' + }).unref(); + await this.waitForService(() => this.isServiceRunning()); + return true; + } + } catch (error) { + console.error('[OllamaService] Failed to start service:', error); + throw error; + } + } + + async stopService() { + return await this.shutdown(); + } + + async getInstalledModels() { + try { + const response = await this._makeRequest(`${this.baseUrl}/api/tags`, { + method: 'GET', + timeout: this.requestTimeout + }, 'models'); + + const data = await response.json(); + return data.models || []; + } catch (error) { + console.error('[OllamaService] Failed to get installed models:', error.message); + return []; + } + } + + async getInstalledModelsList() { + try { + const { stdout } = await spawnAsync(this.getOllamaCliPath(), ['list']); + const lines = stdout.split('\n').filter(line => line.trim()); + + // Skip header line (NAME, ID, SIZE, MODIFIED) + const modelLines = lines.slice(1); + + const models = []; + for (const line of modelLines) { + if (!line.trim()) continue; + + // Parse line: "model:tag model_id size modified_time" + const parts = line.split(/\s+/); + if (parts.length >= 3) { + models.push({ + name: parts[0], + id: parts[1], + size: parts[2] + (parts[3] === 'GB' || parts[3] === 'MB' ? ' ' + parts[3] : ''), + status: 'installed' + }); + } + } + + return models; + } catch (error) { + console.log('[OllamaService] Failed to get installed models via CLI, falling back to API'); + // Fallback to API if CLI fails + const apiModels = await this.getInstalledModels(); + return apiModels.map(model => ({ + name: model.name, + id: model.digest || 'unknown', + size: model.size || 'Unknown', + status: 'installed' + })); + } + } + + async getModelSuggestions() { + try { + // Get actually installed models + const installedModels = await this.getInstalledModelsList(); + + // Get user input history from storage (we'll implement this in the frontend) + // For now, just return installed models + return installedModels; + } catch (error) { + console.error('[OllamaService] Failed to get model suggestions:', error); + return []; + } + } + + async isModelInstalled(modelName) { + const models = await this.getInstalledModels(); + return models.some(model => model.name === modelName); + } + + async pullModel(modelName) { + if (!modelName?.trim()) { + throw new Error(`Invalid model name: ${modelName}`); + } + + console.log(`[OllamaService] Starting to pull model: ${modelName} via API`); + + try { + const response = await fetch(`${this.baseUrl}/api/pull`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + model: modelName, + stream: true + }) + }); + + if (!response.ok) { + throw new Error(`Pull API failed: ${response.status} ${response.statusText}`); + } + + // Handle Node.js streaming response + return new Promise((resolve, reject) => { + let buffer = ''; + + response.body.on('data', (chunk) => { + buffer += chunk.toString(); + const lines = buffer.split('\n'); + + // Keep incomplete line in buffer + buffer = lines.pop() || ''; + + // Process complete lines + for (const line of lines) { + if (!line.trim()) continue; + + try { + const data = JSON.parse(line); + const progress = this._parseOllamaPullProgress(data, modelName); + + if (progress !== null) { + this.setInstallProgress(modelName, progress); + this.emit('pull-progress', { + model: modelName, + progress, + status: data.status || 'downloading' + }); + console.log(`[OllamaService] API Progress: ${progress}% for ${modelName} (${data.status || 'downloading'})`); + } + + // Handle completion + if (data.status === 'success') { + console.log(`[OllamaService] Successfully pulled model: ${modelName}`); + this.emit('pull-complete', { model: modelName }); + this.clearInstallProgress(modelName); + resolve(); + return; + } + } catch (parseError) { + console.warn('[OllamaService] Failed to parse response line:', line); + } + } + }); + + response.body.on('end', () => { + // Process any remaining data in buffer + if (buffer.trim()) { + try { + const data = JSON.parse(buffer); + if (data.status === 'success') { + console.log(`[OllamaService] Successfully pulled model: ${modelName}`); + this.emit('pull-complete', { model: modelName }); + } + } catch (parseError) { + console.warn('[OllamaService] Failed to parse final buffer:', buffer); + } + } + this.clearInstallProgress(modelName); + resolve(); + }); + + response.body.on('error', (error) => { + console.error(`[OllamaService] Stream error for ${modelName}:`, error); + this.clearInstallProgress(modelName); + reject(error); + }); + }); + } catch (error) { + this.clearInstallProgress(modelName); + console.error(`[OllamaService] Pull model failed:`, error); + throw error; + } + } + + _parseOllamaPullProgress(data, modelName) { + // Handle Ollama API response format + if (data.status === 'success') { + return 100; + } + + // Handle downloading progress + if (data.total && data.completed !== undefined) { + const progress = Math.round((data.completed / data.total) * 100); + return Math.min(progress, 99); // Don't show 100% until success + } + + // Handle status-based progress + const statusProgress = { + 'pulling manifest': 5, + 'downloading': 10, + 'verifying sha256 digest': 90, + 'writing manifest': 95, + 'removing any unused layers': 98 + }; + + if (data.status && statusProgress[data.status] !== undefined) { + return statusProgress[data.status]; + } + + return null; + } + + + + async installMacOS(onProgress) { + console.log('[OllamaService] Installing Ollama on macOS using DMG...'); + + try { + const dmgUrl = 'https://ollama.com/download/Ollama.dmg'; + const tempDir = app.getPath('temp'); + const dmgPath = path.join(tempDir, 'Ollama.dmg'); + const mountPoint = path.join(tempDir, 'OllamaMount'); + + console.log('[OllamaService] Step 1: Downloading Ollama DMG...'); + onProgress?.({ stage: 'downloading', message: 'Downloading Ollama installer...', progress: 0 }); + const checksumInfo = DOWNLOAD_CHECKSUMS.ollama.dmg; + await this.downloadWithRetry(dmgUrl, dmgPath, { + expectedChecksum: checksumInfo?.sha256, + onProgress: (progress) => { + onProgress?.({ stage: 'downloading', message: `Downloading... ${progress}%`, progress }); + } + }); + + console.log('[OllamaService] Step 2: Mounting DMG...'); + onProgress?.({ stage: 'mounting', message: 'Mounting disk image...', progress: 0 }); + await fs.mkdir(mountPoint, { recursive: true }); + await spawnAsync('hdiutil', ['attach', dmgPath, '-mountpoint', mountPoint]); + onProgress?.({ stage: 'mounting', message: 'Disk image mounted.', progress: 100 }); + + console.log('[OllamaService] Step 3: Installing Ollama.app...'); + onProgress?.({ stage: 'installing', message: 'Installing Ollama application...', progress: 0 }); + await spawnAsync('cp', ['-R', `${mountPoint}/Ollama.app`, '/Applications/']); + onProgress?.({ stage: 'installing', message: 'Application installed.', progress: 100 }); + + console.log('[OllamaService] Step 4: Setting up CLI path...'); + onProgress?.({ stage: 'linking', message: 'Creating command-line shortcut...', progress: 0 }); + try { + const script = `do shell script "mkdir -p /usr/local/bin && ln -sf '${this.getOllamaCliPath()}' '/usr/local/bin/ollama'" with administrator privileges`; + await spawnAsync('osascript', ['-e', script]); + onProgress?.({ stage: 'linking', message: 'Shortcut created.', progress: 100 }); + } catch (linkError) { + console.error('[OllamaService] CLI symlink creation failed:', linkError.message); + onProgress?.({ stage: 'linking', message: 'Shortcut creation failed (permissions?).', progress: 100 }); + // Not throwing an error, as the app might still work + } + + console.log('[OllamaService] Step 5: Cleanup...'); + onProgress?.({ stage: 'cleanup', message: 'Cleaning up installation files...', progress: 0 }); + await spawnAsync('hdiutil', ['detach', mountPoint]); + await fs.unlink(dmgPath).catch(() => {}); + await fs.rmdir(mountPoint).catch(() => {}); + onProgress?.({ stage: 'cleanup', message: 'Cleanup complete.', progress: 100 }); + + console.log('[OllamaService] Ollama installed successfully on macOS'); + + await new Promise(resolve => setTimeout(resolve, 2000)); + + return true; + } catch (error) { + console.error('[OllamaService] macOS installation failed:', error); + throw new Error(`Failed to install Ollama on macOS: ${error.message}`); + } + } + + async installWindows(onProgress) { + console.log('[OllamaService] Installing Ollama on Windows...'); + + try { + const exeUrl = 'https://ollama.com/download/OllamaSetup.exe'; + const tempDir = app.getPath('temp'); + const exePath = path.join(tempDir, 'OllamaSetup.exe'); + + console.log('[OllamaService] Step 1: Downloading Ollama installer...'); + onProgress?.({ stage: 'downloading', message: 'Downloading Ollama installer...', progress: 0 }); + const checksumInfo = DOWNLOAD_CHECKSUMS.ollama.exe; + await this.downloadWithRetry(exeUrl, exePath, { + expectedChecksum: checksumInfo?.sha256, + onProgress: (progress) => { + onProgress?.({ stage: 'downloading', message: `Downloading... ${progress}%`, progress }); + } + }); + + console.log('[OllamaService] Step 2: Running silent installation...'); + onProgress?.({ stage: 'installing', message: 'Installing Ollama...', progress: 0 }); + await spawnAsync(exePath, ['/VERYSILENT', '/NORESTART']); + onProgress?.({ stage: 'installing', message: 'Installation complete.', progress: 100 }); + + console.log('[OllamaService] Step 3: Cleanup...'); + onProgress?.({ stage: 'cleanup', message: 'Cleaning up installation files...', progress: 0 }); + await fs.unlink(exePath).catch(() => {}); + onProgress?.({ stage: 'cleanup', message: 'Cleanup complete.', progress: 100 }); + + console.log('[OllamaService] Ollama installed successfully on Windows'); + + await new Promise(resolve => setTimeout(resolve, 3000)); + + return true; + } catch (error) { + console.error('[OllamaService] Windows installation failed:', error); + throw new Error(`Failed to install Ollama on Windows: ${error.message}`); + } + } + + async installLinux() { + console.log('[OllamaService] Installing Ollama on Linux...'); + console.log('[OllamaService] Automatic installation on Linux is not supported for security reasons.'); + console.log('[OllamaService] Please install Ollama manually:'); + console.log('[OllamaService] 1. Visit https://ollama.com/download/linux'); + console.log('[OllamaService] 2. Follow the official installation instructions'); + console.log('[OllamaService] 3. Or use your package manager if available'); + throw new Error('Manual installation required on Linux. Please visit https://ollama.com/download/linux'); + } + + + + async warmUpModel(modelName, forceRefresh = false) { + if (!modelName?.trim()) { + console.warn(`[OllamaService] Invalid model name for warm-up`); + return false; + } + + // Check if already warmed (and not forcing refresh) + if (!forceRefresh && this.warmedModels.has(modelName)) { + console.log(`[OllamaService] Model ${modelName} already warmed up, skipping`); + return true; + } + + // Check if currently warming - return existing Promise + if (this.warmingModels.has(modelName)) { + console.log(`[OllamaService] Model ${modelName} is already warming up, joining existing operation`); + return await this.warmingModels.get(modelName); + } + + // Check rate limiting (prevent too frequent attempts) + const lastAttempt = this.lastWarmUpAttempt.get(modelName); + const now = Date.now(); + if (lastAttempt && (now - lastAttempt) < 5000) { // 5 second cooldown + console.log(`[OllamaService] Rate limiting warm-up for ${modelName}, try again in ${5 - Math.floor((now - lastAttempt) / 1000)}s`); + return false; + } + + // Create and store the warming Promise + const warmingPromise = this._performWarmUp(modelName); + this.warmingModels.set(modelName, warmingPromise); + this.lastWarmUpAttempt.set(modelName, now); + + try { + const result = await warmingPromise; + + if (result) { + this.warmedModels.add(modelName); + console.log(`[OllamaService] Model ${modelName} successfully warmed up`); + } + + return result; + } finally { + // Always clean up the warming Promise + this.warmingModels.delete(modelName); + } + } + + async _performWarmUp(modelName) { + console.log(`[OllamaService] Starting warm-up for model: ${modelName}`); + + try { + const response = await this._makeRequest(`${this.baseUrl}/api/chat`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + model: modelName, + messages: [ + { role: 'user', content: 'Hi' } + ], + stream: false, + options: { + num_predict: 1, // Minimal response + temperature: 0 + } + }), + timeout: this.warmupTimeout + }, `warmup_${modelName}`); + + return true; + } catch (error) { + console.error(`[OllamaService] Failed to warm up model ${modelName}:`, error.message); + return false; + } + } + + async autoWarmUpSelectedModel() { + try { + // Get selected model from ModelStateService + const modelStateService = global.modelStateService; + if (!modelStateService) { + console.log('[OllamaService] ModelStateService not available for auto warm-up'); + return false; + } + + const selectedModels = modelStateService.getSelectedModels(); + const llmModelId = selectedModels.llm; + + // Check if it's an Ollama model + const provider = modelStateService.getProviderForModel('llm', llmModelId); + if (provider !== 'ollama') { + console.log('[OllamaService] Selected LLM is not Ollama, skipping warm-up'); + return false; + } + + // Check if Ollama service is running + const isRunning = await this.isServiceRunning(); + if (!isRunning) { + console.log('[OllamaService] Ollama service not running, clearing warm-up cache'); + this._clearWarmUpCache(); + return false; + } + + // Check if model is installed + const isInstalled = await this.isModelInstalled(llmModelId); + if (!isInstalled) { + console.log(`[OllamaService] Model ${llmModelId} not installed, skipping warm-up`); + return false; + } + + console.log(`[OllamaService] Auto-warming up selected model: ${llmModelId}`); + return await this.warmUpModel(llmModelId); + + } catch (error) { + console.error('[OllamaService] Auto warm-up failed:', error); + return false; + } + } + + _clearWarmUpCache() { + this.warmedModels.clear(); + this.warmingModels.clear(); + this.lastWarmUpAttempt.clear(); + console.log('[OllamaService] Warm-up cache cleared'); + } + + getWarmUpStatus() { + return { + warmedModels: Array.from(this.warmedModels), + warmingModels: Array.from(this.warmingModels.keys()), + lastAttempts: Object.fromEntries(this.lastWarmUpAttempt) + }; + } + + async shutdown(force = false) { + console.log(`[OllamaService] Shutdown initiated (force: ${force})`); + + if (!force && this.warmingModels.size > 0) { + const warmingList = Array.from(this.warmingModels.keys()); + console.log(`[OllamaService] Waiting for ${warmingList.length} models to finish warming: ${warmingList.join(', ')}`); + + const warmingPromises = Array.from(this.warmingModels.values()); + try { + // Use Promise.allSettled instead of race with setTimeout + const results = await Promise.allSettled(warmingPromises); + const completed = results.filter(r => r.status === 'fulfilled').length; + console.log(`[OllamaService] ${completed}/${results.length} warming operations completed`); + } catch (error) { + console.log('[OllamaService] Error waiting for warm-up completion, proceeding with shutdown'); + } + } + + // Clean up all resources + this._cleanup(); + this._clearWarmUpCache(); + + return super.shutdown(force); + } + + async shutdownMacOS(force) { + try { + // Try to quit Ollama.app gracefully + await spawnAsync('osascript', ['-e', 'tell application "Ollama" to quit']); + console.log('[OllamaService] Ollama.app quit successfully'); + + // Wait a moment for graceful shutdown + await new Promise(resolve => setTimeout(resolve, 2000)); + + // Check if still running + const stillRunning = await this.isServiceRunning(); + if (stillRunning) { + console.log('[OllamaService] Ollama still running, forcing shutdown'); + // Force kill if necessary + await spawnAsync('pkill', ['-f', this.getOllamaCliPath()]); + } + + return true; + } catch (error) { + console.log('[OllamaService] Graceful quit failed, trying force kill'); + try { + await spawnAsync('pkill', ['-f', this.getOllamaCliPath()]); + return true; + } catch (killError) { + console.error('[OllamaService] Failed to force kill Ollama:', killError); + return false; + } + } + } + + async shutdownWindows(force) { + try { + // Try to stop the service gracefully + await spawnAsync('taskkill', ['/IM', 'ollama.exe', '/T']); + console.log('[OllamaService] Ollama process terminated on Windows'); + return true; + } catch (error) { + console.log('[OllamaService] Standard termination failed, trying force kill'); + try { + await spawnAsync('taskkill', ['/IM', 'ollama.exe', '/F', '/T']); + return true; + } catch (killError) { + console.error('[OllamaService] Failed to force kill Ollama on Windows:', killError); + return false; + } + } + } + + async shutdownLinux(force) { + try { + await spawnAsync('pkill', ['-f', this.getOllamaCliPath()]); + console.log('[OllamaService] Ollama process terminated on Linux'); + return true; + } catch (error) { + if (force) { + await spawnAsync('pkill', ['-9', '-f', this.getOllamaCliPath()]).catch(() => {}); + } + console.error('[OllamaService] Failed to shutdown Ollama on Linux:', error); + return false; + } + } + + async getAllModelsWithStatus() { + // Get all installed models directly from Ollama + const installedModels = await this.getInstalledModels(); + + const models = []; + for (const model of installedModels) { + models.push({ + name: model.name, + displayName: model.name, // Use model name as display name + size: model.size || 'Unknown', + description: `Ollama model: ${model.name}`, + installed: true, + installing: this.installationProgress.has(model.name), + progress: this.getInstallProgress(model.name) + }); + } + + // Also add any models currently being installed + for (const [modelName, progress] of this.installationProgress) { + if (!models.find(m => m.name === modelName)) { + models.push({ + name: modelName, + displayName: modelName, + size: 'Unknown', + description: `Ollama model: ${modelName}`, + installed: false, + installing: true, + progress: progress + }); + } + } + + return models; + } +} + +// Export singleton instance +const ollamaService = new OllamaService(); +module.exports = ollamaService; \ No newline at end of file diff --git a/src/common/services/whisperService.js b/src/common/services/whisperService.js new file mode 100644 index 0000000..1bbfb23 --- /dev/null +++ b/src/common/services/whisperService.js @@ -0,0 +1,352 @@ +const { spawn } = require('child_process'); +const path = require('path'); +const fs = require('fs'); +const os = require('os'); +const LocalAIServiceBase = require('./localAIServiceBase'); +const { spawnAsync } = require('../utils/spawnHelper'); +const { DOWNLOAD_CHECKSUMS } = require('../config/checksums'); + +const fsPromises = fs.promises; + +class WhisperService extends LocalAIServiceBase { + constructor() { + super('WhisperService'); + this.isInitialized = false; + this.whisperPath = null; + this.modelsDir = null; + this.tempDir = null; + this.availableModels = { + 'whisper-tiny': { + name: 'Tiny', + size: '39M', + url: 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.bin' + }, + 'whisper-base': { + name: 'Base', + size: '74M', + url: 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.bin' + }, + 'whisper-small': { + name: 'Small', + size: '244M', + url: 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin' + }, + 'whisper-medium': { + name: 'Medium', + size: '769M', + url: 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-medium.bin' + } + }; + } + + async initialize() { + if (this.isInitialized) return; + + try { + const homeDir = os.homedir(); + const whisperDir = path.join(homeDir, '.glass', 'whisper'); + + this.modelsDir = path.join(whisperDir, 'models'); + this.tempDir = path.join(whisperDir, 'temp'); + this.whisperPath = path.join(whisperDir, 'bin', 'whisper'); + + await this.ensureDirectories(); + await this.ensureWhisperBinary(); + + this.isInitialized = true; + console.log('[WhisperService] Initialized successfully'); + } catch (error) { + console.error('[WhisperService] Initialization failed:', error); + throw error; + } + } + + async ensureDirectories() { + await fsPromises.mkdir(this.modelsDir, { recursive: true }); + await fsPromises.mkdir(this.tempDir, { recursive: true }); + await fsPromises.mkdir(path.dirname(this.whisperPath), { recursive: true }); + } + + async ensureWhisperBinary() { + const whisperCliPath = await this.checkCommand('whisper-cli'); + if (whisperCliPath) { + this.whisperPath = whisperCliPath; + console.log(`[WhisperService] Found whisper-cli at: ${this.whisperPath}`); + return; + } + + const whisperPath = await this.checkCommand('whisper'); + if (whisperPath) { + this.whisperPath = whisperPath; + console.log(`[WhisperService] Found whisper at: ${this.whisperPath}`); + return; + } + + try { + await fsPromises.access(this.whisperPath, fs.constants.X_OK); + console.log('[WhisperService] Custom whisper binary found'); + return; + } catch (error) { + // Continue to installation + } + + const platform = this.getPlatform(); + if (platform === 'darwin') { + console.log('[WhisperService] Whisper not found, trying Homebrew installation...'); + try { + await this.installViaHomebrew(); + return; + } catch (error) { + console.log('[WhisperService] Homebrew installation failed:', error.message); + } + } + + await this.autoInstall(); + } + + async installViaHomebrew() { + const brewPath = await this.checkCommand('brew'); + if (!brewPath) { + throw new Error('Homebrew not found. Please install Homebrew first.'); + } + + console.log('[WhisperService] Installing whisper-cpp via Homebrew...'); + await spawnAsync('brew', ['install', 'whisper-cpp']); + + const whisperCliPath = await this.checkCommand('whisper-cli'); + if (whisperCliPath) { + this.whisperPath = whisperCliPath; + console.log(`[WhisperService] Whisper-cli installed via Homebrew at: ${this.whisperPath}`); + } else { + const whisperPath = await this.checkCommand('whisper'); + if (whisperPath) { + this.whisperPath = whisperPath; + console.log(`[WhisperService] Whisper installed via Homebrew at: ${this.whisperPath}`); + } + } + } + + + async ensureModelAvailable(modelId) { + if (!this.isInitialized) { + console.log('[WhisperService] Service not initialized, initializing now...'); + await this.initialize(); + } + + const modelInfo = this.availableModels[modelId]; + if (!modelInfo) { + throw new Error(`Unknown model: ${modelId}. Available models: ${Object.keys(this.availableModels).join(', ')}`); + } + + const modelPath = await this.getModelPath(modelId); + try { + await fsPromises.access(modelPath, fs.constants.R_OK); + console.log(`[WhisperService] Model ${modelId} already available at: ${modelPath}`); + } catch (error) { + console.log(`[WhisperService] Model ${modelId} not found, downloading...`); + await this.downloadModel(modelId); + } + } + + async downloadModel(modelId) { + const modelInfo = this.availableModels[modelId]; + const modelPath = await this.getModelPath(modelId); + const checksumInfo = DOWNLOAD_CHECKSUMS.whisper.models[modelId]; + + this.emit('downloadProgress', { modelId, progress: 0 }); + + await this.downloadWithRetry(modelInfo.url, modelPath, { + expectedChecksum: checksumInfo?.sha256, + onProgress: (progress) => { + this.emit('downloadProgress', { modelId, progress }); + } + }); + + console.log(`[WhisperService] Model ${modelId} downloaded successfully`); + } + + + async getModelPath(modelId) { + if (!this.isInitialized || !this.modelsDir) { + throw new Error('WhisperService is not initialized. Call initialize() first.'); + } + return path.join(this.modelsDir, `${modelId}.bin`); + } + + async getWhisperPath() { + return this.whisperPath; + } + + async saveAudioToTemp(audioBuffer, sessionId = '') { + const timestamp = Date.now(); + const random = Math.random().toString(36).substr(2, 6); + const sessionPrefix = sessionId ? `${sessionId}_` : ''; + const tempFile = path.join(this.tempDir, `audio_${sessionPrefix}${timestamp}_${random}.wav`); + + const wavHeader = this.createWavHeader(audioBuffer.length); + const wavBuffer = Buffer.concat([wavHeader, audioBuffer]); + + await fsPromises.writeFile(tempFile, wavBuffer); + return tempFile; + } + + createWavHeader(dataSize) { + const header = Buffer.alloc(44); + const sampleRate = 24000; + const numChannels = 1; + const bitsPerSample = 16; + + header.write('RIFF', 0); + header.writeUInt32LE(36 + dataSize, 4); + header.write('WAVE', 8); + header.write('fmt ', 12); + header.writeUInt32LE(16, 16); + header.writeUInt16LE(1, 20); + header.writeUInt16LE(numChannels, 22); + header.writeUInt32LE(sampleRate, 24); + header.writeUInt32LE(sampleRate * numChannels * bitsPerSample / 8, 28); + header.writeUInt16LE(numChannels * bitsPerSample / 8, 32); + header.writeUInt16LE(bitsPerSample, 34); + header.write('data', 36); + header.writeUInt32LE(dataSize, 40); + + return header; + } + + async cleanupTempFile(filePath) { + if (!filePath || typeof filePath !== 'string') { + console.warn('[WhisperService] Invalid file path for cleanup:', filePath); + return; + } + + const filesToCleanup = [ + filePath, + filePath.replace('.wav', '.txt'), + filePath.replace('.wav', '.json') + ]; + + for (const file of filesToCleanup) { + try { + // Check if file exists before attempting to delete + await fsPromises.access(file, fs.constants.F_OK); + await fsPromises.unlink(file); + console.log(`[WhisperService] Cleaned up: ${file}`); + } catch (error) { + // File doesn't exist or already deleted - this is normal + if (error.code !== 'ENOENT') { + console.warn(`[WhisperService] Failed to cleanup ${file}:`, error.message); + } + } + } + } + + async getInstalledModels() { + if (!this.isInitialized) { + console.log('[WhisperService] Service not initialized for getInstalledModels, initializing now...'); + await this.initialize(); + } + + const models = []; + for (const [modelId, modelInfo] of Object.entries(this.availableModels)) { + try { + const modelPath = await this.getModelPath(modelId); + await fsPromises.access(modelPath, fs.constants.R_OK); + models.push({ + id: modelId, + name: modelInfo.name, + size: modelInfo.size, + installed: true + }); + } catch (error) { + models.push({ + id: modelId, + name: modelInfo.name, + size: modelInfo.size, + installed: false + }); + } + } + return models; + } + + async isServiceRunning() { + return this.isInitialized; + } + + async startService() { + if (!this.isInitialized) { + await this.initialize(); + } + return true; + } + + async stopService() { + return true; + } + + async isInstalled() { + try { + const whisperPath = await this.checkCommand('whisper-cli') || await this.checkCommand('whisper'); + return !!whisperPath; + } catch (error) { + return false; + } + } + + async installMacOS() { + throw new Error('Binary installation not available for macOS. Please install Homebrew and run: brew install whisper-cpp'); + } + + async installWindows() { + console.log('[WhisperService] Installing Whisper on Windows...'); + const version = 'v1.7.6'; + const binaryUrl = `https://github.com/ggerganov/whisper.cpp/releases/download/${version}/whisper-cpp-${version}-win-x64.zip`; + const tempFile = path.join(this.tempDir, 'whisper-binary.zip'); + + try { + await this.downloadWithRetry(binaryUrl, tempFile); + const extractDir = path.dirname(this.whisperPath); + await spawnAsync('powershell', ['-command', `Expand-Archive -Path '${tempFile}' -DestinationPath '${extractDir}' -Force`]); + await fsPromises.unlink(tempFile); + console.log('[WhisperService] Whisper installed successfully on Windows'); + return true; + } catch (error) { + console.error('[WhisperService] Windows installation failed:', error); + throw new Error(`Failed to install Whisper on Windows: ${error.message}`); + } + } + + async installLinux() { + console.log('[WhisperService] Installing Whisper on Linux...'); + const version = 'v1.7.6'; + const binaryUrl = `https://github.com/ggerganov/whisper.cpp/releases/download/${version}/whisper-cpp-${version}-linux-x64.tar.gz`; + const tempFile = path.join(this.tempDir, 'whisper-binary.tar.gz'); + + try { + await this.downloadWithRetry(binaryUrl, tempFile); + const extractDir = path.dirname(this.whisperPath); + await spawnAsync('tar', ['-xzf', tempFile, '-C', extractDir, '--strip-components=1']); + await spawnAsync('chmod', ['+x', this.whisperPath]); + await fsPromises.unlink(tempFile); + console.log('[WhisperService] Whisper installed successfully on Linux'); + return true; + } catch (error) { + console.error('[WhisperService] Linux installation failed:', error); + throw new Error(`Failed to install Whisper on Linux: ${error.message}`); + } + } + + async shutdownMacOS(force) { + return true; + } + + async shutdownWindows(force) { + return true; + } + + async shutdownLinux(force) { + return true; + } +} + +module.exports = { WhisperService }; \ No newline at end of file diff --git a/src/common/utils/spawnHelper.js b/src/common/utils/spawnHelper.js new file mode 100644 index 0000000..5b80eb2 --- /dev/null +++ b/src/common/utils/spawnHelper.js @@ -0,0 +1,39 @@ +const { spawn } = require('child_process'); + +function spawnAsync(command, args = [], options = {}) { + return new Promise((resolve, reject) => { + const child = spawn(command, args, options); + let stdout = ''; + let stderr = ''; + + if (child.stdout) { + child.stdout.on('data', (data) => { + stdout += data.toString(); + }); + } + + if (child.stderr) { + child.stderr.on('data', (data) => { + stderr += data.toString(); + }); + } + + child.on('error', (error) => { + reject(error); + }); + + child.on('close', (code) => { + if (code === 0) { + resolve({ stdout, stderr }); + } else { + const error = new Error(`Command failed with code ${code}: ${stderr || stdout}`); + error.code = code; + error.stdout = stdout; + error.stderr = stderr; + reject(error); + } + }); + }); +} + +module.exports = { spawnAsync }; \ No newline at end of file diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 470ca94..33f632d 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -6,7 +6,17 @@ const fs = require('node:fs'); const os = require('os'); const util = require('util'); const execFile = util.promisify(require('child_process').execFile); -const sharp = require('sharp'); + +// Try to load sharp, but don't fail if it's not available +let sharp; +try { + sharp = require('sharp'); + console.log('[WindowManager] Sharp module loaded successfully'); +} catch (error) { + console.warn('[WindowManager] Sharp module not available:', error.message); + console.warn('[WindowManager] Screenshot functionality will work with reduced image processing capabilities'); + sharp = null; +} const authService = require('../common/services/authService'); const systemSettingsRepository = require('../common/repositories/systemSettings'); const userRepository = require('../common/repositories/user'); @@ -1522,25 +1532,45 @@ async function captureScreenshot(options = {}) { const imageBuffer = await fs.promises.readFile(tempPath); await fs.promises.unlink(tempPath); - const resizedBuffer = await sharp(imageBuffer) - // .resize({ height: 1080 }) - .resize({ height: 384 }) - .jpeg({ quality: 80 }) - .toBuffer(); + if (sharp) { + try { + // Try using sharp for optimal image processing + const resizedBuffer = await sharp(imageBuffer) + // .resize({ height: 1080 }) + .resize({ height: 384 }) + .jpeg({ quality: 80 }) + .toBuffer(); - const base64 = resizedBuffer.toString('base64'); - const metadata = await sharp(resizedBuffer).metadata(); + const base64 = resizedBuffer.toString('base64'); + const metadata = await sharp(resizedBuffer).metadata(); + lastScreenshot = { + base64, + width: metadata.width, + height: metadata.height, + timestamp: Date.now(), + }; + + return { success: true, base64, width: metadata.width, height: metadata.height }; + } catch (sharpError) { + console.warn('Sharp module failed, falling back to basic image processing:', sharpError.message); + } + } + + // Fallback: Return the original image without resizing + console.log('[WindowManager] Using fallback image processing (no resize/compression)'); + const base64 = imageBuffer.toString('base64'); + lastScreenshot = { base64, - width: metadata.width, - height: metadata.height, + width: null, // We don't have metadata without sharp + height: null, timestamp: Date.now(), }; - return { success: true, base64, width: metadata.width, height: metadata.height }; + return { success: true, base64, width: null, height: null }; } catch (error) { - console.error('Failed to capture and resize screenshot:', error); + console.error('Failed to capture screenshot:', error); return { success: false, error: error.message }; } } diff --git a/src/features/listen/stt/sttService.js b/src/features/listen/stt/sttService.js index 187f76e..39f7aa8 100644 --- a/src/features/listen/stt/sttService.js +++ b/src/features/listen/stt/sttService.js @@ -133,7 +133,50 @@ class SttService { return; } - if (this.modelInfo.provider === 'gemini') { + if (this.modelInfo.provider === 'whisper') { + // Whisper STT emits 'transcription' events with different structure + if (message.text && message.text.trim()) { + const finalText = message.text.trim(); + + // Filter out Whisper noise transcriptions + const noisePatterns = [ + '[BLANK_AUDIO]', + '[INAUDIBLE]', + '[MUSIC]', + '[SOUND]', + '[NOISE]', + '(BLANK_AUDIO)', + '(INAUDIBLE)', + '(MUSIC)', + '(SOUND)', + '(NOISE)' + ]; + + + + const normalizedText = finalText.toLowerCase().trim(); + + const isNoise = noisePatterns.some(pattern => + finalText.includes(pattern) || finalText === pattern + ); + + + if (!isNoise && finalText.length > 2) { + this.debounceMyCompletion(finalText); + + this.sendToRenderer('stt-update', { + speaker: 'Me', + text: finalText, + isPartial: false, + isFinal: true, + timestamp: Date.now(), + }); + } else { + console.log(`[Whisper-Me] Filtered noise: "${finalText}"`); + } + } + return; + } else if (this.modelInfo.provider === 'gemini') { if (!message.serverContent?.modelTurn) { console.log('[Gemini STT - Me]', JSON.stringify(message, null, 2)); } @@ -203,7 +246,50 @@ class SttService { return; } - if (this.modelInfo.provider === 'gemini') { + if (this.modelInfo.provider === 'whisper') { + // Whisper STT emits 'transcription' events with different structure + if (message.text && message.text.trim()) { + const finalText = message.text.trim(); + + // Filter out Whisper noise transcriptions + const noisePatterns = [ + '[BLANK_AUDIO]', + '[INAUDIBLE]', + '[MUSIC]', + '[SOUND]', + '[NOISE]', + '(BLANK_AUDIO)', + '(INAUDIBLE)', + '(MUSIC)', + '(SOUND)', + '(NOISE)' + ]; + + + const normalizedText = finalText.toLowerCase().trim(); + + const isNoise = noisePatterns.some(pattern => + finalText.includes(pattern) || finalText === pattern + ); + + + // Only process if it's not noise, not a false positive, and has meaningful content + if (!isNoise && finalText.length > 2) { + this.debounceTheirCompletion(finalText); + + this.sendToRenderer('stt-update', { + speaker: 'Them', + text: finalText, + isPartial: false, + isFinal: true, + timestamp: Date.now(), + }); + } else { + console.log(`[Whisper-Them] Filtered noise: "${finalText}"`); + } + } + return; + } else if (this.modelInfo.provider === 'gemini') { if (!message.serverContent?.modelTurn) { console.log('[Gemini STT - Them]', JSON.stringify(message, null, 2)); } @@ -294,9 +380,13 @@ class SttService { portkeyVirtualKey: this.modelInfo.provider === 'openai-glass' ? this.modelInfo.apiKey : undefined, }; + // Add sessionType for Whisper to distinguish between My and Their sessions + const myOptions = { ...sttOptions, callbacks: mySttConfig.callbacks, sessionType: 'my' }; + const theirOptions = { ...sttOptions, callbacks: theirSttConfig.callbacks, sessionType: 'their' }; + [this.mySttSession, this.theirSttSession] = await Promise.all([ - createSTT(this.modelInfo.provider, { ...sttOptions, callbacks: mySttConfig.callbacks }), - createSTT(this.modelInfo.provider, { ...sttOptions, callbacks: theirSttConfig.callbacks }), + createSTT(this.modelInfo.provider, myOptions), + createSTT(this.modelInfo.provider, theirOptions), ]); console.log('✅ Both STT sessions initialized successfully.'); diff --git a/src/features/settings/SettingsView.js b/src/features/settings/SettingsView.js index bd99937..7bb42f0 100644 --- a/src/features/settings/SettingsView.js +++ b/src/features/settings/SettingsView.js @@ -1,4 +1,5 @@ import { html, css, LitElement } from '../../assets/lit-core-2.7.4.min.js'; +import { getOllamaProgressTracker } from '../../common/services/localProgressTracker.js'; export class SettingsView extends LitElement { static styles = css` @@ -408,9 +409,54 @@ export class SettingsView extends LitElement { overflow-y: auto; background: rgba(0,0,0,0.3); border-radius: 4px; padding: 4px; margin-top: 4px; } - .model-item { padding: 5px 8px; font-size: 11px; border-radius: 3px; cursor: pointer; transition: background-color 0.15s; } + .model-item { + padding: 5px 8px; + font-size: 11px; + border-radius: 3px; + cursor: pointer; + transition: background-color 0.15s; + display: flex; + justify-content: space-between; + align-items: center; + } .model-item:hover { background-color: rgba(255,255,255,0.1); } .model-item.selected { background-color: rgba(0, 122, 255, 0.4); font-weight: 500; } + .model-status { + font-size: 9px; + color: rgba(255,255,255,0.6); + margin-left: 8px; + } + .model-status.installed { color: rgba(0, 255, 0, 0.8); } + .model-status.not-installed { color: rgba(255, 200, 0, 0.8); } + .install-progress { + flex: 1; + height: 4px; + background: rgba(255,255,255,0.1); + border-radius: 2px; + margin-left: 8px; + overflow: hidden; + } + .install-progress-bar { + height: 100%; + background: rgba(0, 122, 255, 0.8); + transition: width 0.3s ease; + } + + /* Dropdown styles */ + select.model-dropdown { + background: rgba(0,0,0,0.2); + color: white; + cursor: pointer; + } + + select.model-dropdown option { + background: #1a1a1a; + color: white; + } + + select.model-dropdown option:disabled { + color: rgba(255,255,255,0.4); + } /* ────────────────[ GLASS BYPASS ]─────────────── */ :host-context(body.has-glass) { @@ -458,6 +504,12 @@ export class SettingsView extends LitElement { showPresets: { type: Boolean, state: true }, autoUpdateEnabled: { type: Boolean, state: true }, autoUpdateLoading: { type: Boolean, state: true }, + // Ollama related properties + ollamaStatus: { type: Object, state: true }, + ollamaModels: { type: Array, state: true }, + installingModels: { type: Object, state: true }, + // Whisper related properties + whisperModels: { type: Array, state: true }, }; //////// after_modelStateService //////// @@ -466,7 +518,7 @@ export class SettingsView extends LitElement { //////// after_modelStateService //////// this.shortcuts = {}; this.firebaseUser = null; - this.apiKeys = { openai: '', gemini: '', anthropic: '' }; + this.apiKeys = { openai: '', gemini: '', anthropic: '', whisper: '' }; this.providerConfig = {}; this.isLoading = true; this.isContentProtectionOn = true; @@ -480,6 +532,14 @@ export class SettingsView extends LitElement { this.presets = []; this.selectedPreset = null; this.showPresets = false; + // Ollama related + this.ollamaStatus = { installed: false, running: false }; + this.ollamaModels = []; + this.installingModels = {}; // { modelName: progress } + this.progressTracker = getOllamaProgressTracker(); + // Whisper related + this.whisperModels = []; + this.whisperProgressTracker = null; // Will be initialized when needed this.handleUsePicklesKey = this.handleUsePicklesKey.bind(this) this.autoUpdateEnabled = true; this.autoUpdateLoading = true; @@ -529,7 +589,7 @@ export class SettingsView extends LitElement { this.isLoading = true; const { ipcRenderer } = window.require('electron'); try { - const [userState, config, storedKeys, availableLlm, availableStt, selectedModels, presets, contentProtection, shortcuts] = await Promise.all([ + const [userState, config, storedKeys, availableLlm, availableStt, selectedModels, presets, contentProtection, shortcuts, ollamaStatus, whisperModelsResult] = await Promise.all([ ipcRenderer.invoke('get-current-user'), ipcRenderer.invoke('model:get-provider-config'), // Provider 설정 로드 ipcRenderer.invoke('model:get-all-keys'), @@ -538,7 +598,9 @@ export class SettingsView extends LitElement { ipcRenderer.invoke('model:get-selected-models'), ipcRenderer.invoke('settings:getPresets'), ipcRenderer.invoke('get-content-protection-status'), - ipcRenderer.invoke('get-current-shortcuts') + ipcRenderer.invoke('get-current-shortcuts'), + ipcRenderer.invoke('ollama:get-status'), + ipcRenderer.invoke('whisper:get-installed-models') ]); if (userState && userState.isLoggedIn) this.firebaseUser = userState; @@ -555,6 +617,23 @@ export class SettingsView extends LitElement { const firstUserPreset = this.presets.find(p => p.is_default === 0); if (firstUserPreset) this.selectedPreset = firstUserPreset; } + // Ollama status + if (ollamaStatus?.success) { + this.ollamaStatus = { installed: ollamaStatus.installed, running: ollamaStatus.running }; + this.ollamaModels = ollamaStatus.models || []; + } + // Whisper status + if (whisperModelsResult?.success) { + const installedWhisperModels = whisperModelsResult.models; + if (this.providerConfig.whisper) { + this.providerConfig.whisper.sttModels.forEach(m => { + const installedInfo = installedWhisperModels.find(i => i.id === m.id); + if (installedInfo) { + m.installed = installedInfo.installed; + } + }); + } + } } catch (error) { console.error('Error loading initial settings data:', error); } finally { @@ -566,8 +645,52 @@ export class SettingsView extends LitElement { const input = this.shadowRoot.querySelector(`#key-input-${provider}`); if (!input) return; const key = input.value; + + // For Ollama, we need to ensure it's ready first + if (provider === 'ollama') { + this.saving = true; + const { ipcRenderer } = window.require('electron'); + + // First ensure Ollama is installed and running + const ensureResult = await ipcRenderer.invoke('ollama:ensure-ready'); + if (!ensureResult.success) { + alert(`Failed to setup Ollama: ${ensureResult.error}`); + this.saving = false; + return; + } + + // Now validate (which will check if service is running) + const result = await ipcRenderer.invoke('model:validate-key', { provider, key: 'local' }); + + if (result.success) { + this.apiKeys = { ...this.apiKeys, [provider]: 'local' }; + await this.refreshModelData(); + await this.refreshOllamaStatus(); + } else { + alert(`Failed to connect to Ollama: ${result.error}`); + } + this.saving = false; + return; + } + + // For Whisper, just enable it + if (provider === 'whisper') { + this.saving = true; + const { ipcRenderer } = window.require('electron'); + const result = await ipcRenderer.invoke('model:validate-key', { provider, key: 'local' }); + + if (result.success) { + this.apiKeys = { ...this.apiKeys, [provider]: 'local' }; + await this.refreshModelData(); + } else { + alert(`Failed to enable Whisper: ${result.error}`); + } + this.saving = false; + return; + } + + // For other providers, use the normal flow this.saving = true; - const { ipcRenderer } = window.require('electron'); const result = await ipcRenderer.invoke('model:validate-key', { provider, key }); @@ -592,15 +715,17 @@ export class SettingsView extends LitElement { async refreshModelData() { const { ipcRenderer } = window.require('electron'); - const [availableLlm, availableStt, selected] = await Promise.all([ + const [availableLlm, availableStt, selected, storedKeys] = await Promise.all([ ipcRenderer.invoke('model:get-available-models', { type: 'llm' }), ipcRenderer.invoke('model:get-available-models', { type: 'stt' }), - ipcRenderer.invoke('model:get-selected-models') + ipcRenderer.invoke('model:get-selected-models'), + ipcRenderer.invoke('model:get-all-keys') ]); this.availableLlmModels = availableLlm; this.availableSttModels = availableStt; this.selectedLlm = selected.llm; this.selectedStt = selected.stt; + this.apiKeys = storedKeys; this.requestUpdate(); } @@ -622,6 +747,28 @@ export class SettingsView extends LitElement { } async selectModel(type, modelId) { + // Check if this is an Ollama model that needs to be installed + const provider = this.getProviderForModel(type, modelId); + if (provider === 'ollama') { + const ollamaModel = this.ollamaModels.find(m => m.name === modelId); + if (ollamaModel && !ollamaModel.installed && !ollamaModel.installing) { + // Need to install the model first + await this.installOllamaModel(modelId); + return; + } + } + + // Check if this is a Whisper model that needs to be downloaded + if (provider === 'whisper' && type === 'stt') { + const isInstalling = this.installingModels[modelId] !== undefined; + const whisperModelInfo = this.providerConfig.whisper.sttModels.find(m => m.id === modelId); + + if (whisperModelInfo && !whisperModelInfo.installed && !isInstalling) { + await this.downloadWhisperModel(modelId); + return; + } + } + this.saving = true; const { ipcRenderer } = window.require('electron'); await ipcRenderer.invoke('model:set-selected-model', { type, modelId }); @@ -632,6 +779,102 @@ export class SettingsView extends LitElement { this.saving = false; this.requestUpdate(); } + + async refreshOllamaStatus() { + const { ipcRenderer } = window.require('electron'); + const ollamaStatus = await ipcRenderer.invoke('ollama:get-status'); + if (ollamaStatus?.success) { + this.ollamaStatus = { installed: ollamaStatus.installed, running: ollamaStatus.running }; + this.ollamaModels = ollamaStatus.models || []; + } + } + + async installOllamaModel(modelName) { + // Mark as installing + this.installingModels = { ...this.installingModels, [modelName]: 0 }; + this.requestUpdate(); + + try { + // Use the clean progress tracker - no manual event management needed + const success = await this.progressTracker.installModel(modelName, (progress) => { + this.installingModels = { ...this.installingModels, [modelName]: progress }; + this.requestUpdate(); + }); + + if (success) { + // Refresh status after installation + await this.refreshOllamaStatus(); + await this.refreshModelData(); + // Auto-select the model after installation + await this.selectModel('llm', modelName); + } else { + alert(`Installation of ${modelName} was cancelled`); + } + } catch (error) { + console.error(`[SettingsView] Error installing model ${modelName}:`, error); + alert(`Error installing ${modelName}: ${error.message}`); + } finally { + // Automatic cleanup - no manual event listener management + delete this.installingModels[modelName]; + this.requestUpdate(); + } + } + + async downloadWhisperModel(modelId) { + // Mark as installing + this.installingModels = { ...this.installingModels, [modelId]: 0 }; + this.requestUpdate(); + + try { + const { ipcRenderer } = window.require('electron'); + + // Set up progress listener + const progressHandler = (event, { modelId: id, progress }) => { + if (id === modelId) { + this.installingModels = { ...this.installingModels, [modelId]: progress }; + this.requestUpdate(); + } + }; + + ipcRenderer.on('whisper:download-progress', progressHandler); + + // Start download + const result = await ipcRenderer.invoke('whisper:download-model', modelId); + + if (result.success) { + // Auto-select the model after download + await this.selectModel('stt', modelId); + } else { + alert(`Failed to download Whisper model: ${result.error}`); + } + + // Cleanup + ipcRenderer.removeListener('whisper:download-progress', progressHandler); + } catch (error) { + console.error(`[SettingsView] Error downloading Whisper model ${modelId}:`, error); + alert(`Error downloading ${modelId}: ${error.message}`); + } finally { + delete this.installingModels[modelId]; + this.requestUpdate(); + } + } + + getProviderForModel(type, modelId) { + for (const [providerId, config] of Object.entries(this.providerConfig)) { + const models = type === 'llm' ? config.llmModels : config.sttModels; + if (models?.some(m => m.id === modelId)) { + return providerId; + } + } + return null; + } + + async handleWhisperModelSelect(modelId) { + if (!modelId) return; + + // Select the model (will trigger download if needed) + await this.selectModel('stt', modelId); + } handleUsePicklesKey(e) { e.preventDefault() @@ -665,6 +908,14 @@ export class SettingsView extends LitElement { this.cleanupEventListeners(); this.cleanupIpcListeners(); this.cleanupWindowResize(); + + // Cancel any ongoing Ollama installations when component is destroyed + const installingModels = Object.keys(this.installingModels); + if (installingModels.length > 0) { + installingModels.forEach(modelName => { + this.progressTracker.cancelInstallation(modelName); + }); + } } setupEventListeners() { @@ -920,6 +1171,36 @@ export class SettingsView extends LitElement { } } + async handleOllamaShutdown() { + console.log('[SettingsView] Shutting down Ollama service...'); + + if (!window.require) return; + + const { ipcRenderer } = window.require('electron'); + + try { + // Show loading state + this.ollamaStatus = { ...this.ollamaStatus, running: false }; + this.requestUpdate(); + + const result = await ipcRenderer.invoke('ollama:shutdown', false); // Graceful shutdown + + if (result.success) { + console.log('[SettingsView] Ollama shut down successfully'); + // Refresh status to reflect the change + await this.refreshOllamaStatus(); + } else { + console.error('[SettingsView] Failed to shutdown Ollama:', result.error); + // Restore previous state on error + await this.refreshOllamaStatus(); + } + } catch (error) { + console.error('[SettingsView] Error during Ollama shutdown:', error); + // Restore previous state on error + await this.refreshOllamaStatus(); + } + } + //////// before_modelStateService //////// // render() { @@ -1072,20 +1353,124 @@ export class SettingsView extends LitElement {
${Object.entries(this.providerConfig) .filter(([id, config]) => !id.includes('-glass')) - .map(([id, config]) => html` + .map(([id, config]) => { + if (id === 'ollama') { + // Special UI for Ollama + return html` +
+ + ${this.ollamaStatus.installed && this.ollamaStatus.running ? html` +
+ ✓ Ollama is running +
+ + ` : this.ollamaStatus.installed ? html` +
+ ⚠ Ollama installed but not running +
+ + ` : html` +
+ ✗ Ollama not installed +
+ + `} +
+ `; + } + + if (id === 'whisper') { + // Special UI for Whisper with model selection + const whisperModels = config.sttModels || []; + const selectedWhisperModel = this.selectedStt && this.getProviderForModel('stt', this.selectedStt) === 'whisper' + ? this.selectedStt + : null; + + return html` +
+ + ${this.apiKeys[id] === 'local' ? html` +
+ ✓ Whisper is enabled +
+ + + + + + ${Object.entries(this.installingModels).map(([modelId, progress]) => { + if (modelId.startsWith('whisper-') && progress !== undefined) { + return html` +
+
+ Downloading ${modelId}... +
+
+
+
+
+ `; + } + return null; + })} + + + ` : html` + + `} +
+ `; + } + + // Regular providers + return html`
- `)} + `; + })}
`; @@ -1104,11 +1489,30 @@ export class SettingsView extends LitElement { ${this.isLlmListVisible ? html`
- ${this.availableLlmModels.map(model => html` -
this.selectModel('llm', model.id)}> - ${model.name} + ${this.availableLlmModels.map(model => { + const isOllama = this.getProviderForModel('llm', model.id) === 'ollama'; + const ollamaModel = isOllama ? this.ollamaModels.find(m => m.name === model.id) : null; + const isInstalling = this.installingModels[model.id] !== undefined; + const installProgress = this.installingModels[model.id] || 0; + + return html` +
this.selectModel('llm', model.id)}> + ${model.name} + ${isOllama ? html` + ${isInstalling ? html` +
+
- `)} + ` : ollamaModel?.installed ? html` + ✓ Installed + ` : html` + Click to install + `} + ` : ''} +
+ `; + })}
` : ''}
@@ -1119,11 +1523,23 @@ export class SettingsView extends LitElement { ${this.isSttListVisible ? html`
- ${this.availableSttModels.map(model => html` -
this.selectModel('stt', model.id)}> - ${model.name} -
- `)} + ${this.availableSttModels.map(model => { + const isWhisper = this.getProviderForModel('stt', model.id) === 'whisper'; + const isInstalling = this.installingModels[model.id] !== undefined; + const installProgress = this.installingModels[model.id] || 0; + + return html` +
this.selectModel('stt', model.id)}> + ${model.name} + ${isWhisper && isInstalling ? html` +
+
+
+ ` : ''} +
+ `; + })}
` : ''}
diff --git a/src/index.js b/src/index.js index 3bf273d..22a06f5 100644 --- a/src/index.js +++ b/src/index.js @@ -28,8 +28,10 @@ const sessionRepository = require('./common/repositories/session'); const ModelStateService = require('./common/services/modelStateService'); const sqliteClient = require('./common/services/sqliteClient'); +// Global variables const eventBridge = new EventEmitter(); let WEB_PORT = 3000; +let isShuttingDown = false; // Flag to prevent infinite shutdown loop const listenService = new ListenService(); // Make listenService globally accessible so other modules (e.g., windowManager, askService) can reuse the same instance @@ -40,6 +42,10 @@ const modelStateService = new ModelStateService(authService); global.modelStateService = modelStateService; //////// after_modelStateService //////// +// Import and initialize OllamaService +const ollamaService = require('./common/services/ollamaService'); +const ollamaModelRepository = require('./common/repositories/ollamaModel'); + // Native deep link handling - cross-platform compatible let pendingDeepLinkUrl = null; @@ -200,6 +206,21 @@ app.whenReady().then(async () => { askService.initialize(); settingsService.initialize(); setupGeneralIpcHandlers(); + setupOllamaIpcHandlers(); + setupWhisperIpcHandlers(); + + // Initialize Ollama models in database + await ollamaModelRepository.initializeDefaultModels(); + + // Auto warm-up selected Ollama model in background (non-blocking) + setTimeout(async () => { + try { + console.log('[index.js] Starting background Ollama model warm-up...'); + await ollamaService.autoWarmUpSelectedModel(); + } catch (error) { + console.log('[index.js] Background warm-up failed (non-critical):', error.message); + } + }, 2000); // Wait 2 seconds after app start // Start web server and create windows ONLY after all initializations are successful WEB_PORT = await startWebStack(); @@ -234,11 +255,71 @@ app.on('window-all-closed', () => { } }); -app.on('before-quit', async () => { - console.log('[Shutdown] App is about to quit.'); - listenService.stopMacOSAudioCapture(); - // await sessionRepository.endAllActiveSessions(); // MOVED TO authService - databaseInitializer.close(); +app.on('before-quit', async (event) => { + // Prevent infinite loop by checking if shutdown is already in progress + if (isShuttingDown) { + console.log('[Shutdown] 🔄 Shutdown already in progress, allowing quit...'); + return; + } + + console.log('[Shutdown] App is about to quit. Starting graceful shutdown...'); + + // Set shutdown flag to prevent infinite loop + isShuttingDown = true; + + // Prevent immediate quit to allow graceful shutdown + event.preventDefault(); + + try { + // 1. Stop audio capture first (immediate) + listenService.stopMacOSAudioCapture(); + console.log('[Shutdown] Audio capture stopped'); + + // 2. End all active sessions (database operations) - with error handling + try { + await sessionRepository.endAllActiveSessions(); + console.log('[Shutdown] Active sessions ended'); + } catch (dbError) { + console.warn('[Shutdown] Could not end active sessions (database may be closed):', dbError.message); + } + + // 3. Shutdown Ollama service (potentially time-consuming) + console.log('[Shutdown] shutting down Ollama service...'); + const ollamaShutdownSuccess = await Promise.race([ + ollamaService.shutdown(false), // Graceful shutdown + new Promise(resolve => setTimeout(() => resolve(false), 8000)) // 8s timeout + ]); + + if (ollamaShutdownSuccess) { + console.log('[Shutdown] Ollama service shut down gracefully'); + } else { + console.log('[Shutdown] Ollama shutdown timeout, forcing...'); + // Force shutdown if graceful failed + try { + await ollamaService.shutdown(true); + } catch (forceShutdownError) { + console.warn('[Shutdown] Force shutdown also failed:', forceShutdownError.message); + } + } + + // 4. Close database connections (final cleanup) + try { + databaseInitializer.close(); + console.log('[Shutdown] Database connections closed'); + } catch (closeError) { + console.warn('[Shutdown] Error closing database:', closeError.message); + } + + console.log('[Shutdown] Graceful shutdown completed successfully'); + + } catch (error) { + console.error('[Shutdown] Error during graceful shutdown:', error); + // Continue with shutdown even if there were errors + } finally { + // Actually quit the app now + console.log('[Shutdown] Exiting application...'); + app.exit(0); // Use app.exit() instead of app.quit() to force quit + } }); app.on('activate', () => { @@ -247,6 +328,70 @@ app.on('activate', () => { } }); +function setupWhisperIpcHandlers() { + const { WhisperService } = require('./common/services/whisperService'); + const whisperService = new WhisperService(); + + // Forward download progress events to renderer + whisperService.on('downloadProgress', (data) => { + const windows = BrowserWindow.getAllWindows(); + windows.forEach(window => { + window.webContents.send('whisper:download-progress', data); + }); + }); + + // IPC handlers for Whisper operations + ipcMain.handle('whisper:download-model', async (event, modelId) => { + try { + console.log(`[Whisper IPC] Starting download for model: ${modelId}`); + + // Ensure WhisperService is initialized first + if (!whisperService.isInitialized) { + console.log('[Whisper IPC] Initializing WhisperService...'); + await whisperService.initialize(); + } + + // Set up progress listener + const progressHandler = (data) => { + if (data.modelId === modelId) { + event.sender.send('whisper:download-progress', data); + } + }; + + whisperService.on('downloadProgress', progressHandler); + + try { + await whisperService.ensureModelAvailable(modelId); + console.log(`[Whisper IPC] Model ${modelId} download completed successfully`); + } finally { + // Cleanup listener + whisperService.removeListener('downloadProgress', progressHandler); + } + + return { success: true }; + } catch (error) { + console.error(`[Whisper IPC] Failed to download model ${modelId}:`, error); + return { success: false, error: error.message }; + } + }); + + ipcMain.handle('whisper:get-installed-models', async () => { + try { + // Ensure WhisperService is initialized first + if (!whisperService.isInitialized) { + console.log('[Whisper IPC] Initializing WhisperService for model list...'); + await whisperService.initialize(); + } + + const models = await whisperService.getInstalledModels(); + return { success: true, models }; + } catch (error) { + console.error('[Whisper IPC] Failed to get installed models:', error); + return { success: false, error: error.message }; + } + }); +} + function setupGeneralIpcHandlers() { const userRepository = require('./common/repositories/user'); const presetRepository = require('./common/repositories/preset'); @@ -299,6 +444,201 @@ function setupGeneralIpcHandlers() { setupWebDataHandlers(); } +function setupOllamaIpcHandlers() { + // Ollama status and installation + ipcMain.handle('ollama:get-status', async () => { + try { + const installed = await ollamaService.isInstalled(); + const running = installed ? await ollamaService.isServiceRunning() : false; + const models = await ollamaService.getAllModelsWithStatus(); + + return { + installed, + running, + models, + success: true + }; + } catch (error) { + console.error('[Ollama IPC] Failed to get status:', error); + return { success: false, error: error.message }; + } + }); + + ipcMain.handle('ollama:install', async (event) => { + try { + const onProgress = (data) => { + event.sender.send('ollama:install-progress', data); + }; + + await ollamaService.autoInstall(onProgress); + + if (!await ollamaService.isServiceRunning()) { + onProgress({ stage: 'starting', message: 'Starting Ollama service...', progress: 0 }); + await ollamaService.startService(); + onProgress({ stage: 'starting', message: 'Ollama service started.', progress: 100 }); + } + event.sender.send('ollama:install-complete', { success: true }); + return { success: true }; + } catch (error) { + console.error('[Ollama IPC] Failed to install:', error); + event.sender.send('ollama:install-complete', { success: false, error: error.message }); + return { success: false, error: error.message }; + } + }); + + ipcMain.handle('ollama:start-service', async (event) => { + try { + if (!await ollamaService.isServiceRunning()) { + console.log('[Ollama IPC] Starting Ollama service...'); + await ollamaService.startService(); + } + event.sender.send('ollama:install-complete', { success: true }); + return { success: true }; + } catch (error) { + console.error('[Ollama IPC] Failed to start service:', error); + event.sender.send('ollama:install-complete', { success: false, error: error.message }); + return { success: false, error: error.message }; + } + }); + + // Ensure Ollama is ready (starts service if installed but not running) + ipcMain.handle('ollama:ensure-ready', async () => { + try { + if (await ollamaService.isInstalled() && !await ollamaService.isServiceRunning()) { + console.log('[Ollama IPC] Ollama installed but not running, starting service...'); + await ollamaService.startService(); + } + return { success: true }; + } catch (error) { + console.error('[Ollama IPC] Failed to ensure ready:', error); + return { success: false, error: error.message }; + } + }); + + // Get all models with their status + ipcMain.handle('ollama:get-models', async () => { + try { + const models = await ollamaService.getAllModelsWithStatus(); + return { success: true, models }; + } catch (error) { + console.error('[Ollama IPC] Failed to get models:', error); + return { success: false, error: error.message }; + } + }); + + // Get model suggestions for autocomplete + ipcMain.handle('ollama:get-model-suggestions', async () => { + try { + const suggestions = await ollamaService.getModelSuggestions(); + return { success: true, suggestions }; + } catch (error) { + console.error('[Ollama IPC] Failed to get model suggestions:', error); + return { success: false, error: error.message }; + } + }); + + // Pull/install a specific model + ipcMain.handle('ollama:pull-model', async (event, modelName) => { + try { + console.log(`[Ollama IPC] Starting model pull: ${modelName}`); + + // Update DB status to installing + await ollamaModelRepository.updateInstallStatus(modelName, false, true); + + // Set up progress listener for real-time updates + const progressHandler = (data) => { + if (data.model === modelName) { + event.sender.send('ollama:pull-progress', data); + } + }; + + const completeHandler = (data) => { + if (data.model === modelName) { + console.log(`[Ollama IPC] Model ${modelName} pull completed`); + // Clean up listeners + ollamaService.removeListener('pull-progress', progressHandler); + ollamaService.removeListener('pull-complete', completeHandler); + } + }; + + ollamaService.on('pull-progress', progressHandler); + ollamaService.on('pull-complete', completeHandler); + + // Pull the model using REST API + await ollamaService.pullModel(modelName); + + // Update DB status to installed + await ollamaModelRepository.updateInstallStatus(modelName, true, false); + + console.log(`[Ollama IPC] Model ${modelName} pull successful`); + return { success: true }; + } catch (error) { + console.error('[Ollama IPC] Failed to pull model:', error); + // Reset status on error + await ollamaModelRepository.updateInstallStatus(modelName, false, false); + return { success: false, error: error.message }; + } + }); + + // Check if a specific model is installed + ipcMain.handle('ollama:is-model-installed', async (event, modelName) => { + try { + const installed = await ollamaService.isModelInstalled(modelName); + return { success: true, installed }; + } catch (error) { + console.error('[Ollama IPC] Failed to check model installation:', error); + return { success: false, error: error.message }; + } + }); + + // Warm up a specific model + ipcMain.handle('ollama:warm-up-model', async (event, modelName) => { + try { + const success = await ollamaService.warmUpModel(modelName); + return { success }; + } catch (error) { + console.error('[Ollama IPC] Failed to warm up model:', error); + return { success: false, error: error.message }; + } + }); + + // Auto warm-up currently selected model + ipcMain.handle('ollama:auto-warm-up', async () => { + try { + const success = await ollamaService.autoWarmUpSelectedModel(); + return { success }; + } catch (error) { + console.error('[Ollama IPC] Failed to auto warm-up:', error); + return { success: false, error: error.message }; + } + }); + + // Get warm-up status for debugging + ipcMain.handle('ollama:get-warm-up-status', async () => { + try { + const status = ollamaService.getWarmUpStatus(); + return { success: true, status }; + } catch (error) { + console.error('[Ollama IPC] Failed to get warm-up status:', error); + return { success: false, error: error.message }; + } + }); + + // Shutdown Ollama service manually + ipcMain.handle('ollama:shutdown', async (event, force = false) => { + try { + console.log(`[Ollama IPC] Manual shutdown requested (force: ${force})`); + const success = await ollamaService.shutdown(force); + return { success }; + } catch (error) { + console.error('[Ollama IPC] Failed to shutdown Ollama:', error); + return { success: false, error: error.message }; + } + }); + + console.log('[Ollama IPC] Handlers registered'); +} + function setupWebDataHandlers() { const sessionRepository = require('./common/repositories/session'); const sttRepository = require('./features/listen/stt/repositories');