From cf129714be96119c0ea6070c728d76f27fff15f8 Mon Sep 17 00:00:00 2001 From: JakeBreath Date: Sun, 20 Sep 2026 17:07:22 -0500 Subject: [PATCH] Add an Electron desktop shell for the SPA desktop/ serves the normal frontend build over a privileged app://j621 scheme, so localStorage, OPFS, Web Workers, WebCodecs and history routing behave exactly like Chrome. Development points at the Vite dev server; `npm run smoke` runs headless Electron and checks the bundled app. External links open in the system browser, and download navigations (?download=1 or media URLs) are rerouted through webContents.downloadURL, since preventing them cancels the download. The setup screen names the shell's origin when the connection test fails, and the deploy docs list app://j621 for CORS_ALLOWED_ORIGINS. --- deploy/.env.example | 3 + deploy/README.md | 4 + desktop/.gitignore | 4 + desktop/README.md | 66 + desktop/build/icon.ico | Bin 0 -> 370070 bytes desktop/build/icon.png | Bin 0 -> 19835 bytes desktop/electron-builder.yml | 42 + desktop/package-lock.json | 3617 +++++++++++++++++++++ desktop/package.json | 27 + desktop/src/main.ts | 395 +++ desktop/src/preload.ts | 27 + desktop/tsconfig.json | 19 + frontend/src/features/setup/SetupPage.tsx | 8 +- frontend/src/globals.d.ts | 16 + 14 files changed, 4227 insertions(+), 1 deletion(-) create mode 100644 desktop/.gitignore create mode 100644 desktop/README.md create mode 100644 desktop/build/icon.ico create mode 100644 desktop/build/icon.png create mode 100644 desktop/electron-builder.yml create mode 100644 desktop/package-lock.json create mode 100644 desktop/package.json create mode 100644 desktop/src/main.ts create mode 100644 desktop/src/preload.ts create mode 100644 desktop/tsconfig.json diff --git a/deploy/.env.example b/deploy/.env.example index 4fc7f04..95958b7 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -31,6 +31,9 @@ ALLOWED_HOSTS=j621.rainbow-herring.ts.net,localhost,127.0.0.1 # Cross-origin access (needed for the separate frontend + backend deploys) # --------------------------------------------------------------------------- # The origin the SPA is served from, e.g. https://j621-frontend..ts.net +# The desktop app (desktop/) is served from app://j621, so add that origin too +# when it should reach this backend: +# CORS_ALLOWED_ORIGINS=https://j621-frontend..ts.net,app://j621 # CORS_ALLOWED_ORIGINS= # CSRF_TRUSTED_ORIGINS= diff --git a/deploy/README.md b/deploy/README.md index 927c925..86becdf 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -92,6 +92,10 @@ The SPA asks where the backend is (`/setup`) in production builds: backend's funnel URL, e.g. `https://j621-backend..ts.net:8443`, and give the backend `CORS_ALLOWED_ORIGINS=https://..ts.net` (plus `CSRF_TRUSTED_ORIGINS` for the admin). +- **Desktop app** — the Electron shell (`desktop/`) is served from the + `app://j621` origin, so it needs that entry too: + `CORS_ALLOWED_ORIGINS=...,app://j621`. The shell's setup screen prints the + exact origin when the connection test fails. - Without a backend at all, choose **"Continue without a backend"** to run in local mode (e621 browsing only). diff --git a/desktop/.gitignore b/desktop/.gitignore new file mode 100644 index 0000000..d50979b --- /dev/null +++ b/desktop/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +dist/ +release/ +*.tsbuildinfo diff --git a/desktop/README.md b/desktop/README.md new file mode 100644 index 0000000..0889411 --- /dev/null +++ b/desktop/README.md @@ -0,0 +1,66 @@ +# J621 desktop (Electron) + +An Electron shell around the web build. The main process serves the SPA from +the privileged `app://j621` scheme — a real origin, so `localStorage`, OPFS, +Web Workers and WebCodecs all behave exactly like they do in Chrome — and the +SPA keeps its normal first-run flow: on launch it asks where the backend is +(or runs in local mode with no backend at all). + +The renderer code is not forked: the shell loads `frontend/dist` as built by +`npm run build` in `frontend/`. + +## Layout + +``` +src/main.ts window, app:// protocol handler, menu, external links +src/preload.ts window.j621Desktop bridge +electron-builder.yml deb + pacman + nsis packaging +``` + +## Development + +```bash +# terminal 1: the SPA with its /api proxy (needs the backend for library pages) +cd frontend && npm run dev + +# terminal 2 +cd desktop && npm run dev +``` + +`npm run dev` builds the main process and points the window at +`http://localhost:5173` (`J621_DEV_SERVER`). Without the dev server, +`npm start` builds both halves and serves the bundled SPA over `app://j621`. + +## Builds + +```bash +npm run dist:linux # release/*.deb + release/*.pkg.tar.zst +npm run dist:win # release/J621-Setup-*.exe (cross-built with wine; untested) +npm run dist:all +``` + +The Arch package can be installed and removed with pacman: + +```bash +sudo pacman -U release/j621-*.pkg.tar.zst +``` + +## Smoke test + +`npm run smoke` builds everything, runs Electron headless through `xvfb-run` +and checks that the bundled SPA loads over `app://j621`: the SPA fallback, an +asset fetch, `localStorage`, OPFS, WebCodecs and the preload bridge. It exits +non-zero on failure. + +## Backend CORS + +A desktop app is cross-origin to the backend, exactly like the frontend-only +Docker deployment. Add the shell's origin to the backend: + +``` +CORS_ALLOWED_ORIGINS=app://j621 +``` + +The setup screen shows this hint (with the actual origin) when the connection +test fails. Without a backend, choose "Continue without a backend" — the +e621-facing pages work the same as in the browser. diff --git a/desktop/build/icon.ico b/desktop/build/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ca48711930718ef203260533ebe0f485f4d9c0d7 GIT binary patch literal 370070 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 literal 0 HcmV?d00001 diff --git a/desktop/electron-builder.yml b/desktop/electron-builder.yml new file mode 100644 index 0000000..1e538e8 --- /dev/null +++ b/desktop/electron-builder.yml @@ -0,0 +1,42 @@ +appId: io.j621.desktop +productName: J621 +copyright: Copyright (c) 2026 JakeBreath — Jake Labs Non-Commercial Software Licence + +directories: + output: release + buildResources: build + +# The Electron main process and preload live in dist/ (tsc output). The SPA is +# copied from the web build as an extra resource and served over app://j621. +files: + - dist/** + - package.json + +extraResources: + - from: ../frontend/dist + to: dist + filter: + - "**/*" + +linux: + target: + - deb + - pacman + category: AudioVideo + synopsis: Desktop client for the J621 self-hosted media archive + description: >- + J621 is a self-hosted browser for an e621-linked media library. This + desktop build talks to a J621 backend over the network, the same way the + web app does. + icon: build/icon.png + +win: + target: + - nsis + icon: build/icon.ico + +nsis: + oneClick: false + perMachine: false + allowToChangeInstallationDirectory: true + shortcutName: J621 diff --git a/desktop/package-lock.json b/desktop/package-lock.json new file mode 100644 index 0000000..fd80b7e --- /dev/null +++ b/desktop/package-lock.json @@ -0,0 +1,3617 @@ +{ + "name": "j621-desktop", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "j621-desktop", + "version": "0.1.0", + "license": "UNLICENSED", + "devDependencies": { + "@types/node": "^24.13.6", + "electron": "^44.4.3", + "electron-builder": "^26.15.3", + "typescript": "^6.0.3" + } + }, + "node_modules/@electron-internal/extract-zip": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@electron-internal/extract-zip/-/extract-zip-1.0.5.tgz", + "integrity": "sha512-+bqFCP98pLI0Tt0XQo1TmlXtwjWchISndDOxCkEcIuUgXWpBnLyRI+2DU+mesvnMMX6L1XDqYNA0lXNDHd/yiA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=22.12.0" + } + }, + "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": { + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/@electron/asar/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/@electron/asar/node_modules/brace-expansion": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@electron/asar/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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": { + "chalk": "^4.1.1", + "fs-extra": "^9.0.1", + "minimist": "^1.2.5" + }, + "bin": { + "electron-fuses": "dist/bin.js" + } + }, + "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": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/get": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-5.1.0.tgz", + "integrity": "sha512-3kSBtG8ObcTVfXanm5vVJ6UnBLEVmVsRk1M+vGqCuMBV+XLCbJYuWQful+yIy0GQDsSlK0kHEriEHn7SPk4EnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^3.0.0", + "graceful-fs": "^4.2.11", + "progress": "^2.0.3", + "semver": "^7.6.3", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=22.12.0" + }, + "optionalDependencies": { + "undici": "^7.24.4" + } + }, + "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": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "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": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "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": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/@electron/rebuild": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-4.2.0.tgz", + "integrity": "sha512-RKL/O+jGoXJMxrx/5771y1n0xTKmFuOYGO3gMmwypBM6rsH0kou0mswwdXA2JrhIkE4xyC7v9vGk0n6NPzgOxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.1.1", + "node-abi": "^4.2.0", + "node-api-version": "^0.2.1", + "node-gyp": "^12.2.0", + "read-binary-file-arch": "^1.0.6" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=22.12.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": { + "@electron/asar": "^3.3.1", + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.3.1", + "dir-compare": "^4.2.0", + "fs-extra": "^11.1.1", + "minimatch": "^9.0.3", + "plist": "^3.1.0" + }, + "engines": { + "node": ">=16.4" + } + }, + "node_modules/@electron/universal/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/@electron/universal/node_modules/brace-expansion": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", + "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz", + "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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", + "optional": true, + "peer": true, + "dependencies": { + "cross-dirname": "^0.1.0", + "debug": "^4.3.4", + "fs-extra": "^11.1.1", + "minimist": "^1.2.8", + "postject": "^1.0.0-alpha.6" + }, + "bin": { + "electron-windows-sign": "bin/electron-windows-sign.js" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/windows-sign/node_modules/fs-extra": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz", + "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "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": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "license": "Apache-2.0", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "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": { + "debug": "^4.1.1", + "fs-extra": "^9.0.0", + "lodash": "^4.17.15", + "tmp-promise": "^3.0.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "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": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@noble/hashes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.4.0.tgz", + "integrity": "sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.9.5.tgz", + "integrity": "sha512-Ez3wLKVjaxdsLcgeWN4OE31QkM7oBOgKuuBJxldRYAkfYw2C+8zJPcSd/SThnbhszsEOlAmoaS5kIIkN29fGKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@peculiar/utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", + "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/webcrypto": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.7.1.tgz", + "integrity": "sha512-ODOov0sGMJMf3jPonOkgGqPknTsu+DdQ7kD++gz8aI+aFMOMHFbWAA2taqXXVTdP+OTOQR/znGvSpmkeI0WTYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.7.0", + "@peculiar/json-schema": "^1.1.12", + "@peculiar/utils": "^2.0.2", + "tslib": "^2.8.1", + "webcrypto-core": "^1.9.2" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "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": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "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": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "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": { + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "dev": true, + "license": "MIT" + }, + "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": { + "@types/node": "*" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.13.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.6.tgz", + "integrity": "sha512-SGrw/h3KPFshy3OE6ZL53LMBG5vGQQ8/gIpiqz/kRZhPJ7HgwCEs8LBuNtWLa8dvGZVpSF7+Bf+c11HUrCb/yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "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": { + "@types/node": "*" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.15.tgz", + "integrity": "sha512-/5NV/vDALVFDXgLmfsy9TRCBlKwO2LNBFzpzvb9iIj+jR+eSc6DLYYvVOdivT/jm7MtU6TebYuRmzEOI7w40UA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/app-builder-lib": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.15.3.tgz", + "integrity": "sha512-2VnyWkqsP5v5XbBhL3tD5Syx8iNPBYsoU7kY4S2fz7wg8Rj/nztWKCUzGKaFRTv0Xwf3/H058CR1Kvtd/3lRow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/asar": "3.4.1", + "@electron/fuses": "^1.8.0", + "@electron/get": "^3.0.0", + "@electron/notarize": "2.5.0", + "@electron/osx-sign": "1.3.3", + "@electron/rebuild": "^4.0.4", + "@electron/universal": "2.0.3", + "@malept/flatpak-bundler": "^0.4.0", + "@noble/hashes": "^2.2.0", + "@peculiar/webcrypto": "^1.7.1", + "@types/fs-extra": "9.0.13", + "ajv": "^8.18.0", + "asn1js": "^3.0.10", + "async-exit-hook": "^2.0.1", + "builder-util": "26.15.3", + "builder-util-runtime": "9.7.0", + "chromium-pickle-js": "^0.2.0", + "ci-info": "4.3.1", + "debug": "^4.3.4", + "dotenv": "^16.4.5", + "dotenv-expand": "^11.0.6", + "ejs": "^3.1.8", + "electron-publish": "26.15.3", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", + "isbinaryfile": "^5.0.0", + "jiti": "^2.4.2", + "js-yaml": "^4.1.0", + "json5": "^2.2.3", + "lazy-val": "^1.0.5", + "minimatch": "^10.2.5", + "pkijs": "^3.4.0", + "plist": "3.1.0", + "proper-lockfile": "^4.1.2", + "resedit": "^1.7.0", + "semver": "~7.7.3", + "tar": "^7.5.7", + "temp-file": "^3.4.0", + "tiny-async-pool": "1.3.0", + "unzipper": "^0.12.3", + "which": "^5.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "dmg-builder": "26.15.3", + "electron-builder-squirrel-windows": "26.15.3" + } + }, + "node_modules/app-builder-lib/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": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/app-builder-lib/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": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/app-builder-lib/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": { + "semver": "bin/semver.js" + } + }, + "node_modules/app-builder-lib/node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/app-builder-lib/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/app-builder-lib/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": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/app-builder-lib/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/app-builder-lib/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": { + "node": ">= 4.0.0" + } + }, + "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==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/asn1js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", + "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "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/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": { + "node": ">=0.12.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/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/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/brace-expansion": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "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.15.3", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.15.3.tgz", + "integrity": "sha512-q2hn7Mbo2nFNkVekPiHFx6Nfo3hURmES3tfBn+k5Pqxl2RkmP3QGqZUhH/q9Pch/4G05NRhPjDlVj1O8q4Txvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/debug": "^4.1.6", + "builder-util-runtime": "9.7.0", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.6", + "debug": "^4.3.4", + "fs-extra": "^10.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "js-yaml": "^4.1.0", + "sanitize-filename": "^1.6.3", + "source-map-support": "^0.5.19", + "stat-mode": "^1.0.0", + "temp-file": "^3.4.0", + "tiny-async-pool": "1.3.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/builder-util-runtime": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.7.0.tgz", + "integrity": "sha512-g/kR520giAFYkSXTzcmF3kqQq7wi8F6N6SzeDgZrqTBN+VHdmgWOyTdD1yD7AATDId/yXLvuP34CxW46/BwCdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/bytestreamjs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz", + "integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=6.0.0" + } + }, + "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": { + "node": ">=10.6.0" + } + }, + "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": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "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": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "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": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/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==", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "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": { + "node": ">= 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": { + "node": ">=0.10.0" + } + }, + "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/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "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", + "optional": true, + "peer": true + }, + "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": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": { + "node": ">=10" + } + }, + "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, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/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": { + "minimatch": "^3.0.5", + "p-limit": "^3.1.0 " + } + }, + "node_modules/dir-compare/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/dir-compare/node_modules/brace-expansion": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/dir-compare/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dmg-builder": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.15.3.tgz", + "integrity": "sha512-O3zJUFUYHJKgzPqioHxfxzBzlSC1eXCSr79gMSBKBP5AgjjpmrydMsMLotEg9fAJF36vdUncb+4ndRNxoPdlSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "26.15.3", + "builder-util": "26.15.3", + "fs-extra": "^10.1.0", + "js-yaml": "^4.1.0" + } + }, + "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": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "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": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "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": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron": { + "version": "44.4.3", + "resolved": "https://registry.npmjs.org/electron/-/electron-44.4.3.tgz", + "integrity": "sha512-LTpSFTB40qVCXIX5xMo+cgHI/Jjkbjw7VpB26PccEbroqOn72LBukeaDwPVo1fBYzSzs0c9iPuAucFCO7Tw81Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-internal/extract-zip": "^1.0.1", + "@electron/get": "^5.0.0", + "@types/node": "^24.9.0" + }, + "bin": { + "electron": "cli.js", + "install-electron": "install.js" + }, + "engines": { + "node": ">= 22.12.0" + } + }, + "node_modules/electron-builder": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.15.3.tgz", + "integrity": "sha512-a1KM5heqS3gQCZzizXEI8RjJy3QVogULPdeSknt76uLDpBIW/HDGsMg/XgP0riP6PI9COsRvFITKKGDqA8fJxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "26.15.3", + "builder-util": "26.15.3", + "builder-util-runtime": "9.7.0", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "dmg-builder": "26.15.3", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "simple-update-notifier": "2.0.0", + "yargs": "^17.6.2" + }, + "bin": { + "electron-builder": "cli.js", + "install-app-deps": "install-app-deps.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/electron-builder-squirrel-windows": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.15.3.tgz", + "integrity": "sha512-Jc19XPV9y9+2bAdZPkXuVNGNIEFBq9poHC61l8Kv6FdK7DRG3+Ic0rerC0DXOaeHNz8yW0fg/JnF8GQROOF5MA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "app-builder-lib": "26.15.3", + "builder-util": "26.15.3", + "electron-winstaller": "5.4.0" + } + }, + "node_modules/electron-publish": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.15.3.tgz", + "integrity": "sha512-g/2bn8YTavY4cuS5F+jOS7zmZbXXBV8KZ8yHKfJjFPoKtzBqrpCdNPxBd3tqdBwP7BVd0lGzf7Bk2s0KesWZ4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^9.0.11", + "aws4": "^1.13.2", + "builder-util": "26.15.3", + "builder-util-runtime": "9.7.0", + "chalk": "^4.1.2", + "form-data": "^4.0.5", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "mime": "^2.5.2" + } + }, + "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", + "peer": true, + "dependencies": { + "@electron/asar": "^3.2.1", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "lodash": "^4.17.21", + "temp": "^0.9.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "@electron/windows-sign": "^1.1.2" + } + }, + "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", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "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", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.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", + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/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/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true, + "license": "Apache-2.0" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz", + "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filelist": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", + "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/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/filelist/node_modules/brace-expansion": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", + "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/form-data": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "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/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/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/glob/node_modules/brace-expansion": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "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, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "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": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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-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": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "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": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "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": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.7.tgz", + "integrity": "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-yaml": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "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": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "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": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.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": { + "json-buffer": "3.0.1" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, + "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": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "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": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/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": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "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", + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-abi": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-4.35.0.tgz", + "integrity": "sha512-ymk4aIzxdPopw2giv8Fs1Ec6vybGkjmyxUwVqhkI4MCy2tVfXdkOGGWieWVjL0THgH+7a8lRdevyupoYj3Js/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.6.3" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "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": { + "semver": "^7.3.5" + } + }, + "node_modules/node-gyp": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.4.0.tgz", + "integrity": "sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "undici": "^6.25.0", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/node-gyp/node_modules/undici": { + "version": "6.28.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.1.tgz", + "integrity": "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "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": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "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": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkijs": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.1.tgz", + "integrity": "sha512-Oo/NZcSWccq8KyoG7gLE9fnltgHns+pNCjCAp/WmjsUySi+sX7y4z4Xqu4fVb42CDHzRPl33fjzT15V1wvcyhA==", + "dev": true, + "license": "BSD-3-Clause", + "workspaces": [ + "website" + ], + "dependencies": { + "@noble/hashes": "1.8.0", + "asn1js": "^3.0.6", + "bytestreamjs": "^2.0.1", + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/pkijs/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "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": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "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", + "optional": true, + "peer": true, + "dependencies": { + "commander": "^9.4.0" + }, + "bin": { + "postject": "dist/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "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", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "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": { + "node": ">=0.4.0" + } + }, + "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": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.2.0.tgz", + "integrity": "sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "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": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": { + "debug": "^4.3.4" + }, + "bin": { + "read-binary-file-arch": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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": { + "pe-library": "^0.4.1" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "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": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": { + "node": ">= 4" + } + }, + "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", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "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, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/sanitize-filename": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.4.tgz", + "integrity": "sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==", + "dev": true, + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sax": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.1.tgz", + "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/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, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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-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": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "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": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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", + "optional": true + }, + "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": { + "node": ">= 6" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "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": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "7.5.22", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz", + "integrity": "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "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", + "peer": true, + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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": { + "async-exit-hook": "^2.0.1", + "fs-extra": "^10.0.0" + } + }, + "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": { + "semver": "^5.5.0" + } + }, + "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": { + "semver": "bin/semver" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tmp": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "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": { + "utf8-byte-length": "^1.0.1" + } + }, + "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==", + "dev": true, + "license": "0BSD" + }, + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.1.tgz", + "integrity": "sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unzipper": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.12.5.tgz", + "integrity": "sha512-tXYOi9R57Uj/2Z25SOs5RRSzq886MBQj2gY8dPL+xl/kv6s6SvByoKfAtvfVeEuhntWDgjd2o9p2lb4TVPAz0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "~3.7.2", + "duplexer2": "~0.1.4", + "fs-extra": "11.3.1", + "graceful-fs": "^4.2.2", + "node-int64": "^0.4.0" + } + }, + "node_modules/unzipper/node_modules/fs-extra": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", + "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/webcrypto-core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.9.2.tgz", + "integrity": "sha512-gsXecm82UQNlTBURJGuqOWy1Ww08S3kZUcr3aOJS02Pk0xLtkfeUAVC0u0xhgdonFme80edSJUIJyuvL/7250Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.7.0", + "@peculiar/json-schema": "^1.1.12", + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "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": { + "node": ">=8.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/desktop/package.json b/desktop/package.json new file mode 100644 index 0000000..4749101 --- /dev/null +++ b/desktop/package.json @@ -0,0 +1,27 @@ +{ + "name": "j621-desktop", + "productName": "J621", + "version": "0.1.0", + "private": true, + "description": "Desktop shell for the J621 self-hosted media archive", + "author": "JakeBreath", + "license": "SEE LICENSE IN ../LICENSE", + "main": "dist/main.js", + "scripts": { + "build:main": "tsc -p tsconfig.json", + "build:renderer": "npm --prefix ../frontend run build", + "build": "npm run build:main && npm run build:renderer", + "dev": "npm run build:main && J621_DEV_SERVER=http://localhost:5173 electron .", + "start": "npm run build && electron .", + "smoke": "npm run build && xvfb-run -a electron . --j621-smoke", + "dist:linux": "npm run build && electron-builder --linux", + "dist:win": "npm run build && electron-builder --win", + "dist:all": "npm run build && electron-builder --linux --win" + }, + "devDependencies": { + "@types/node": "^24.13.6", + "electron": "^44.4.3", + "electron-builder": "^26.15.3", + "typescript": "^6.0.3" + } +} diff --git a/desktop/src/main.ts b/desktop/src/main.ts new file mode 100644 index 0000000..84bd669 --- /dev/null +++ b/desktop/src/main.ts @@ -0,0 +1,395 @@ +/** + * Electron shell for the J621 SPA. + * + * The renderer is the normal web build (`frontend/dist`), served from the + * privileged `app://j621` scheme so it is a real secure origin: localStorage, + * OPFS, Web Workers, WebCodecs and `history.pushState` all behave exactly + * like they do in Chrome. In development `J621_DEV_SERVER` points the window + * at the Vite dev server instead, which keeps HMR and the `/api` proxy. + * + * The shell is deliberately thin: the SPA still asks for its backend URL on + * first launch (or runs in local e621-only mode) and talks to it over HTTP + * the same way it does in a browser. The only desktop-specific bits are the + * origin, external-link handling and (later) updates. + */ +import { app, BrowserWindow, ipcMain, Menu, protocol, shell } from "electron"; +import { readFileSync } from "node:fs"; +import { readFile, stat, writeFile } from "node:fs/promises"; +import path from "node:path"; + +const SCHEME = "app"; +const HOST = "j621"; +const APP_ORIGIN = `${SCHEME}://${HOST}`; +const DEV_SERVER = (process.env.J621_DEV_SERVER ?? "").replace(/\/+$/, ""); +const SMOKE = process.argv.includes("--j621-smoke"); + +protocol.registerSchemesAsPrivileged([ + { + scheme: SCHEME, + privileges: { + standard: true, + secure: true, + supportFetchAPI: true, + corsEnabled: true, + stream: true, + }, + }, +]); + +const MIME_TYPES: Record = { + ".html": "text/html; charset=utf-8", + ".js": "text/javascript; charset=utf-8", + ".mjs": "text/javascript; charset=utf-8", + ".css": "text/css; charset=utf-8", + ".json": "application/json; charset=utf-8", + ".map": "application/json; charset=utf-8", + ".svg": "image/svg+xml", + ".png": "image/png", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".webp": "image/webp", + ".gif": "image/gif", + ".ico": "image/x-icon", + ".woff": "font/woff", + ".woff2": "font/woff2", + ".wasm": "application/wasm", + ".mp4": "video/mp4", + ".webm": "video/webm", + ".txt": "text/plain; charset=utf-8", +}; + +/** Where `vite build` output lives, packaged or not. */ +function rendererRoot(): string { + return app.isPackaged + ? path.join(process.resourcesPath, "dist") + : path.resolve(__dirname, "..", "..", "frontend", "dist"); +} + +async function existingFile(candidate: string): Promise { + try { + return (await stat(candidate)).isFile(); + } catch { + return false; + } +} + +async function fileResponse(file: string): Promise { + const body = await readFile(file); + const type = + MIME_TYPES[path.extname(file).toLowerCase()] ?? "application/octet-stream"; + return new Response(body, { + headers: { "content-type": type, "cache-control": "no-cache" }, + }); +} + +async function handleAppRequest(request: Request): Promise { + const url = new URL(request.url); + if (url.host !== HOST) return new Response("Not found", { status: 404 }); + + const root = rendererRoot(); + let pathname = decodeURIComponent(url.pathname); + if (!pathname || pathname === "/") pathname = "/index.html"; + + const target = path.resolve(root, "." + pathname); + if (target !== root && !target.startsWith(root + path.sep)) { + return new Response("Forbidden", { status: 403 }); + } + + try { + if (await existingFile(target)) return await fileResponse(target); + // Missing assets keep their 404; anything else is a client route and + // falls back to the SPA entry point (BrowserRouter). + if (path.extname(pathname)) return new Response("Not found", { status: 404 }); + return await fileResponse(path.join(root, "index.html")); + } catch (error) { + const hint = app.isPackaged + ? "The bundled frontend is missing from the application resources." + : "Build the frontend first: npm --prefix ../frontend run build"; + console.error("[app://]", error); + return new Response(`${hint}\n`, { status: 500 }); + } +} + +interface WindowState { + x?: number; + y?: number; + width: number; + height: number; + maximized: boolean; +} + +const DEFAULT_WINDOW_STATE: WindowState = { + width: 1440, + height: 900, + maximized: false, +}; + +function stateFile(): string { + return path.join(app.getPath("userData"), "window-state.json"); +} + +function readWindowState(): WindowState { + try { + const parsed = JSON.parse( + readFileSync(stateFile(), "utf8"), + ) as Partial; + return { ...DEFAULT_WINDOW_STATE, ...parsed }; + } catch { + return DEFAULT_WINDOW_STATE; + } +} + +function saveWindowState(win: BrowserWindow): void { + if (win.isDestroyed()) return; + const { x, y, width, height } = win.getNormalBounds(); + const state: WindowState = { + x, + y, + width, + height, + maximized: win.isMaximized(), + }; + void writeFile(stateFile(), JSON.stringify(state)).catch(() => { + // Window geometry is a nice-to-have; never fail a quit over it. + }); +} + +function openExternal(rawUrl: string): void { + if (/^https?:/i.test(rawUrl)) void shell.openExternal(rawUrl); +} + +/** File extensions the SPA navigates to when it wants a save dialog. */ +const DOWNLOAD_EXTENSIONS = new Set([ + ".jpg", + ".jpeg", + ".jpe", + ".png", + ".gif", + ".webp", + ".avif", + ".mp4", + ".webm", + ".mov", + ".swf", + ".zip", + ".pdf", + ".bin", +]); + +/** + * Downloads in the SPA are same-window navigations (`location.href = + * url?download=1`, ``), and Chromium cancels those when + * `will-navigate` is prevented. Recognise them so they become real + * downloads instead of being opened in the browser. + */ +function isDownloadNavigation(url: URL): boolean { + if (/(?:^|&)download=1(?:&|$)/.test(url.search.slice(1))) return true; + return DOWNLOAD_EXTENSIONS.has(path.extname(url.pathname).toLowerCase()); +} + +let mainWindow: BrowserWindow | null = null; + +function buildMenu(win: BrowserWindow): void { + const template: Electron.MenuItemConstructorOptions[] = [ + { + label: "J621", + submenu: [ + { + label: "Backend setup…", + click: () => void win.loadURL(`${APP_ORIGIN}/setup`), + }, + { + label: "Open backend in browser", + click: () => win.webContents.send("j621:open-backend"), + }, + { type: "separator" }, + { role: "quit" }, + ], + }, + { role: "editMenu" }, + { + label: "View", + submenu: [ + { role: "reload" }, + { role: "forceReload" }, + { role: "toggleDevTools" }, + { type: "separator" }, + { role: "resetZoom" }, + { role: "zoomIn" }, + { role: "zoomOut" }, + { type: "separator" }, + { role: "togglefullscreen" }, + ], + }, + ]; + Menu.setApplicationMenu(Menu.buildFromTemplate(template)); +} + +function createWindow(): BrowserWindow { + const state = readWindowState(); + const win = new BrowserWindow({ + x: state.x, + y: state.y, + width: state.width, + height: state.height, + minWidth: 960, + minHeight: 600, + backgroundColor: "#11111b", + show: false, + webPreferences: { + preload: path.join(__dirname, "preload.js"), + contextIsolation: true, + nodeIntegration: false, + sandbox: true, + spellcheck: false, + }, + }); + + if (state.maximized) win.maximize(); + win.once("ready-to-show", () => win.show()); + win.on("close", () => saveWindowState(win)); + win.on("closed", () => { + mainWindow = null; + }); + + // Links to the web open in the user's browser, never in this window. + win.webContents.setWindowOpenHandler(({ url }) => { + openExternal(url); + return { action: "deny" }; + }); + win.webContents.on("will-navigate", (event, url) => { + const allowed = DEV_SERVER + ? url.startsWith(DEV_SERVER) + : url.startsWith(APP_ORIGIN); + if (allowed) return; + event.preventDefault(); + let parsed: URL; + try { + parsed = new URL(url); + } catch { + return; + } + if (/^https?:$/.test(parsed.protocol) && isDownloadNavigation(parsed)) { + win.webContents.downloadURL(url); + return; + } + openExternal(url); + }); + + buildMenu(win); + void win.loadURL(DEV_SERVER || `${APP_ORIGIN}/`); + if (SMOKE) runSmokeTest(win); + return win; +} + +/** + * `npm run smoke`: load the bundled SPA and check the things that are only + * true under the custom scheme. Exits non-zero on the first broken promise. + */ +function runSmokeTest(win: BrowserWindow): void { + win.webContents.once("did-finish-load", () => { + void (async () => { + try { + const result = (await win.webContents.executeJavaScript(`(async () => { + const waitFor = async (probe, timeout = 8000) => { + const start = Date.now(); + while (Date.now() - start < timeout) { + if (probe()) return true; + await new Promise((resolve) => setTimeout(resolve, 100)); + } + return false; + }; + const asset = await fetch("/favicon.svg"); + const route = await fetch("/gallery/some/deep/route"); + const routeBody = await route.text(); + localStorage.setItem("j621.smoke", "ok"); + history.pushState({}, "", "/gallery"); + return { + origin: location.origin, + title: document.title, + assetOk: asset.ok && (await asset.text()).includes(" (document.querySelector("#root")?.childElementCount ?? 0) > 0), + setupOk: document.body.innerText.includes("Where is your backend?"), + storageOk: localStorage.getItem("j621.smoke") === "ok", + historyOk: location.pathname === "/gallery", + opfsOk: typeof navigator.storage?.getDirectory === "function", + webcodecsOk: typeof VideoEncoder !== "undefined", + bridgeOk: window.j621Desktop?.isDesktop === true, + }; + })()`, true)) as Record; + + const expected: Record = { + origin: APP_ORIGIN, + title: "J621", + assetOk: true, + routeOk: true, + mounted: true, + setupOk: true, + storageOk: true, + historyOk: true, + opfsOk: true, + webcodecsOk: true, + bridgeOk: true, + }; + const failures = Object.entries(expected).filter( + ([key, value]) => result[key] !== value, + ); + console.log( + "[smoke] electron", + process.versions.electron, + "chrome", + process.versions.chrome, + ); + console.log("[smoke]", JSON.stringify(result)); + if (failures.length > 0) { + console.error( + "[smoke] FAILED:", + failures.map(([key]) => key).join(", "), + ); + app.exit(1); + return; + } + console.log("[smoke] OK"); + app.exit(0); + } catch (error) { + console.error("[smoke] FAILED:", error); + app.exit(1); + } + })(); + }); +} + +const gotLock = app.requestSingleInstanceLock(); +if (!gotLock) { + app.quit(); +} else { + app.on("second-instance", () => { + if (!mainWindow) return; + if (mainWindow.isMinimized()) mainWindow.restore(); + mainWindow.focus(); + }); + + app.setAppUserModelId("io.j621.desktop"); + + app.whenReady().then(() => { + protocol.handle(SCHEME, handleAppRequest); + + ipcMain.handle("j621:version", () => app.getVersion()); + ipcMain.handle("j621:open-external", (_event, url: unknown) => { + if (typeof url === "string") openExternal(url); + }); + + mainWindow = createWindow(); + + app.on("activate", () => { + if (BrowserWindow.getAllWindows().length === 0) { + mainWindow = createWindow(); + } + }); + }); + + app.on("window-all-closed", () => { + if (process.platform !== "darwin") app.quit(); + }); +} diff --git a/desktop/src/preload.ts b/desktop/src/preload.ts new file mode 100644 index 0000000..b3f81d5 --- /dev/null +++ b/desktop/src/preload.ts @@ -0,0 +1,27 @@ +/** + * The only bridge between the desktop shell and the SPA. Keep it tiny: the + * renderer is the normal web build and must not need Electron to work. + */ +import { contextBridge, ipcRenderer } from "electron"; + +contextBridge.exposeInMainWorld("j621Desktop", { + isDesktop: true as const, + platform: process.platform, + // The SPA's own origin (`app://j621`), shown by the setup screen when it + // has to explain which origin to allow in the backend's CORS settings. + origin: window.location.origin, + getVersion: (): Promise => ipcRenderer.invoke("j621:version"), +}); + +// Menu → "Open backend in browser": read the SPA's stored backend URL and +// hand it to the main process after checking it is a real web URL. +ipcRenderer.on("j621:open-backend", () => { + let url = ""; + try { + url = window.localStorage.getItem("j621.backend") ?? ""; + } catch { + // Storage can be unavailable in rare cases; nothing to open then. + } + if (url === "none") url = ""; + if (url) void ipcRenderer.invoke("j621:open-external", url); +}); diff --git a/desktop/tsconfig.json b/desktop/tsconfig.json new file mode 100644 index 0000000..67db737 --- /dev/null +++ b/desktop/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "node16", + "moduleResolution": "node16", + "lib": ["ES2023", "DOM"], + "types": ["node"], + "outDir": "dist", + "rootDir": "src", + "sourceMap": true, + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src"] +} diff --git a/frontend/src/features/setup/SetupPage.tsx b/frontend/src/features/setup/SetupPage.tsx index b2fb8f2..9b7a518 100644 --- a/frontend/src/features/setup/SetupPage.tsx +++ b/frontend/src/features/setup/SetupPage.tsx @@ -41,11 +41,17 @@ async function testBackend(base: string): Promise { text: `The backend answered HTTP ${response.status}.`, }; } catch { + // The desktop shell is a different origin from the backend, and that is + // the usual reason the first connection test fails there. + const desktopHint = window.j621Desktop + ? ` The desktop app's origin is ${window.j621Desktop.origin} — allow it in CORS_ALLOWED_ORIGINS on the backend.` + : ""; return { ok: false, text: "Could not reach the backend. Check the URL, and if it lives on " + - "another domain add this site to CORS_ALLOWED_ORIGINS there.", + "another domain add this site to CORS_ALLOWED_ORIGINS there." + + desktopHint, }; } finally { window.clearTimeout(timeout); diff --git a/frontend/src/globals.d.ts b/frontend/src/globals.d.ts index 9962902..d22ba69 100644 --- a/frontend/src/globals.d.ts +++ b/frontend/src/globals.d.ts @@ -1,2 +1,18 @@ /** Baked at build time by Vite (see vite.config.ts). */ declare const __GIT_HASH__: string; + +/** + * Injected by the Electron shell (desktop/src/preload.ts) when it hosts the + * SPA. Absent in browsers. + */ +interface J621DesktopBridge { + readonly isDesktop: true; + readonly platform: string; + /** The shell's origin (e.g. `app://j621`), for backend CORS hints. */ + readonly origin: string; + getVersion(): Promise; +} + +interface Window { + j621Desktop?: J621DesktopBridge; +}