diff --git a/.env b/.env index 16b84a1..8270548 100644 --- a/.env +++ b/.env @@ -63,7 +63,7 @@ DEBUG_ELECTRON=true # OPTIONAL SETTINGS (main — VITE_* figées au build) # =========================================== VITE_WINDOW_WIDTH=1200 -VITE_WINDOW_HEIGHT=800 +VITE_WINDOW_HEIGHT=750 VITE_ENABLE_DEVTOOLS=false VITE_ELECTRON_ENABLE_LOGGING=true diff --git a/.env.example b/.env.example index 309c784..2616db8 100644 --- a/.env.example +++ b/.env.example @@ -74,3 +74,46 @@ VITE_ENABLE_DEVTOOLS=true # Logs fichier au niveau debug VITE_ELECTRON_ENABLE_LOGGING=true +# =========================================== +# HTTP / DOWNLOAD / GAME (main process) +# =========================================== +# Timeouts in milliseconds +# VITE_HTTP_TIMEOUT_API_MS=8000 +# VITE_HTTP_TIMEOUT_VERSION_PING_MS=5000 +# VITE_HTTP_TIMEOUT_GITHUB_MS=10000 +# VITE_DOWNLOAD_TIMEOUT_MS=600000 +# VITE_GAME_PROCESS_POLL_MS=2000 + +# Optional download host (defaults to API base when empty) +# VITE_GAME_DOWNLOAD_BASE_UNIVERSE= +# VITE_GAME_DOWNLOAD_BASE_TESTING= + +# Cachet status API ids (defaults: component 3, metric 2) +# VITE_STATUS_COMPONENT_ID_UNIVERSE=3 +# VITE_STATUS_COMPONENT_ID_TESTING=3 +# VITE_STATUS_METRIC_ID_UNIVERSE=2 +# VITE_STATUS_METRIC_ID_TESTING=2 + +# Game install layout +# VITE_GAME_INSTALL_SUBDIR=DyingStar +# VITE_GAME_EXE_WINDOWS=DyingStar.exe +# VITE_GAME_EXE_LINUX=DyingStar.x86_64 +# VITE_GAME_EXE_DARWIN=DyingStar.app + +# OAuth / custom protocol +# VITE_APP_PROTOCOL=dyingstar +# VITE_AUTH_CLIENT_ID=dyingstar-launcher +# VITE_AUTH_REALM=dyingstar +# VITE_AUTH_REDIRECT_URI=dyingstar://auth/callback +# VITE_DOWNLOAD_USER_AGENT=DyingStar-Launcher/1.0 + +# Window max size when auto-fitting content +# VITE_WINDOW_MAX_WIDTH=1920 +# VITE_WINDOW_MAX_HEIGHT=1200 + +# =========================================== +# UI TIMING (renderer) +# =========================================== +# VITE_UI_TOAST_DURATION_MS=3800 +# VITE_UI_SOCIAL_PANEL_CLOSE_MS=1200 + diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..e792b6e --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,125 @@ +name: Build & Deploy Launcher + +on: + push: + branches: + - develop + tags: + - 'v*' + pull_request: + +jobs: + check: + name: Lint & Typecheck + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install dependencies + run: pnpm install + + - name: Lint + run: pnpm run lint + + - name: Typecheck + run: pnpm run typecheck + + build: + name: Build (${{ matrix.os }}) + needs: check + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: ubuntu-latest + cmd: build:linux + artifact_name: build-linux + - os: windows-latest + cmd: build:win + artifact_name: build-windows + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install dependencies + run: pnpm install + + - name: Set NODE_ENV to production + shell: bash + run: sed -i 's/NODE_ENV=development/NODE_ENV=production/' .env + + - name: Build + run: pnpm run ${{ matrix.cmd }} + + - name: Upload Linux artifacts + if: matrix.os == 'ubuntu-latest' + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.artifact_name }} + path: | + release/*.AppImage + release/*.rpm + release/*.deb + if-no-files-found: error + retention-days: ${{ github.event_name == 'pull_request' && 1 || 7 }} + + - name: Upload Windows artifacts + if: matrix.os == 'windows-latest' + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.artifact_name }} + path: release/*.exe + if-no-files-found: error + retention-days: ${{ github.event_name == 'pull_request' && 1 || 7 }} + + release: + name: Create GitHub Release + needs: build + if: github.ref_type == 'tag' + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Get version + id: version + run: echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT + + - name: Download Linux artifacts + uses: actions/download-artifact@v4 + with: + name: build-linux + path: artifacts/ + + - name: Download Windows artifacts + uses: actions/download-artifact@v4 + with: + name: build-windows + path: artifacts/ + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: | + "artifacts/Dying_Star_Launcher Setup ${{ steps.version.outputs.version }}.exe" + artifacts/Dying_Star_Launcher-${{ steps.version.outputs.version }}.AppImage + artifacts/dying-star-launcher-${{ steps.version.outputs.version }}.x86_64.rpm + artifacts/dying-star-launcher-${{ steps.version.outputs.version }}_amd64.deb diff --git a/.gitignore b/.gitignore index 6e48aa9..d31d55c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,44 +1,35 @@ # Dependencies -node_modules -npm-debug.log* -yarn-debug.log* -yarn-error.log* +node_modules/ +.pnpm-store/ + +# Logs & cache +*.log +logs/ .eslintcache -# Next.js -.next/ -out +# Environment (secrets — ne jamais committer) +.env +.env.local +.env.*.local + +# Builds Electron / Vite +out/ +dist/ +release/ build/ -# Production builds -dist +# Archives *.tgz -# Environment variables -.env.local -.env.development.local -.env.test.local -.env.production.local - -# Logs -*.log* -logs/ +# OS +.DS_Store +Thumbs.db +ehthumbs.db -# Editor directories and files -.vscode/ +# Editors (préférences personnelles uniquement) .idea/ *.swp *.swo -# OS generated files -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db -Thumbs.db - -# Electron +# Electron legacy app/ -release/ diff --git a/.npmrc b/.npmrc index 66f3729..c483022 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1 @@ -shamefully-hoist=true -node-linker=hoisted \ No newline at end of file +shamefully-hoist=true \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..1d7ac85 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..0b6b9a6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,39 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Main Process", + "type": "node", + "request": "launch", + "cwd": "${workspaceRoot}", + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite", + "windows": { + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite.cmd" + }, + "runtimeArgs": ["--sourcemap"], + "env": { + "REMOTE_DEBUGGING_PORT": "9222" + } + }, + { + "name": "Debug Renderer Process", + "port": 9222, + "request": "attach", + "type": "chrome", + "webRoot": "${workspaceFolder}/src/renderer", + "timeout": 60000, + "presentation": { + "hidden": true + } + } + ], + "compounds": [ + { + "name": "Debug All", + "configurations": ["Debug Main Process", "Debug Renderer Process"], + "presentation": { + "order": 1 + } + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c0ffdc1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"], + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } +} diff --git a/README.md b/README.md index 402541e..c75ed5d 100644 --- a/README.md +++ b/README.md @@ -1,323 +1,81 @@ -# 🌟 Dying Star Launcher +# Dying Star Launcher -Un lanceur de jeu moderne et élégant construit avec Next.js et Electron. +Launcher desktop open source pour le jeu **Dying Star**, basé sur [Electron](https://www.electronjs.org/) + [electron-vite](https://electron-vite.org/), avec une interface **React 19** et **Tailwind CSS v4**. -## 🛠️ Technologies utilisées +## Stack -- **Next.js 14** - Framework React pour l'interface utilisateur -- **Electron 38** - Framework pour créer des applications desktop -- **React 18** - Bibliothèque JavaScript pour l'UI -- **Node.js** - Environnement d'exécution JavaScript -- **Nodemon** - Rechargement automatique en développement -- **Concurrently** - Exécution simultanée de processus -- **dotenv** - Gestion des variables d'environnement +| Couche | Technologie | +| ------------- | ------------------------- | +| Shell desktop | Electron 38 | +| Build | electron-vite, Vite 7 | +| UI | React 19, Tailwind CSS v4 | +| État | Zustand | +| i18n | i18next / react-i18next | +| Packaging | electron-builder | -## 📦 Installation +## Structure du projet -### Prérequis -- **Node.js** (version 18 ou supérieure) -- **npm** ou **yarn** - -### Installation automatique - -```bash -# Clonez le repository -git clone https://github.com/DyingStar-game/launcher.git -cd launcher - -# Installation complète avec configuration -npm run setup -``` - -### Installation manuelle - -```bash -# 1. Clonez le repository -git clone https://github.com/DyingStar-game/launcher.git -cd launcher - -# 2. Installez les dépendances -npm install - -# 3. Copiez la configuration d'environnement -cp .env.example .env.local - -# 4. Lancez en mode développement -npm run electron-dev -``` - -## 🎮 Scripts disponibles - -### Développement -- `npm run dev` - Lance Next.js en mode développement -- `npm run electron-dev` - 🚀 **Recommandé** - Lance Next.js + Electron (logs propres) -- `npm run electron-dev-verbose` - Lance avec logs détaillés de nodemon -- `npm run electron` - Lance Electron seul - -### Production -- `npm run build` - Build l'application Next.js -- `npm run electron-pack` - Build l'application Electron pour la production -- `npm run export` - Export statique Next.js - -### Utilitaires -- `npm run clean` - Nettoie les dossiers de build -- `npm run setup` - Installation complète automatique - -## ⚙️ Configuration environnement - -Le projet utilise des variables d'environnement pour une configuration flexible. - -### Fichiers de configuration - -- **`.env.example`** - Template avec toutes les variables disponibles -- **`.env.local`** - Configuration locale (ignorée par git) - -### Variables principales - -```bash -# Mode de développement -NODE_ENV=development - -# Configuration Electron -ELECTRON_DISABLE_SECURITY_WARNINGS=true -WINDOW_WIDTH=1200 -WINDOW_HEIGHT=800 -ENABLE_DEVTOOLS=true - -# Configuration Next.js -NEXT_DEV_URL=http://localhost:3000 - -# Debug -DEBUG_ELECTRON=false -NODEMON_VERBOSE=false -``` - -### Personnalisation - -Modifiez `.env.local` pour adapter le launcher à vos préférences : - -```bash -# Fenêtre plus grande -WINDOW_WIDTH=1600 -WINDOW_HEIGHT=1000 - -# Désactiver les DevTools -ENABLE_DEVTOOLS=false - -# Activer le debug complet -DEBUG_ELECTRON=true -NODEMON_VERBOSE=true -``` - -## 📁 Structure du projet - -``` -dying-star-launcher/ -├── electron/ # Fichiers Electron -│ ├── main.js # Point d'entrée Electron (avec config env) -│ └── preload.js # Script de préchargement (optionnel) -├── pages/ # Pages Next.js -│ ├── index.js # Page d'accueil -│ └── _app.js # App wrapper -├── public/ # Ressources statiques -├── styles/ # Fichiers CSS -├── .env.example # Template de configuration -├── .env.local # Configuration locale (à créer) -├── nodemon.json # Configuration nodemon -├── package.json # Configuration npm -├── next.config.js # Configuration Next.js -└── README.md # Documentation -``` - -## 🔧 Développement - -### Mode développement recommandé - -```bash -npm run electron-dev -``` - -Cette commande lance simultanément : -- 🌐 **Next.js** sur `http://localhost:3000` avec hot-reload -- ⚡ **Electron** avec rechargement automatique via nodemon - -### Logs propres - -Les logs sont maintenant formatés avec des préfixes colorés : -``` -🌐 Next.js | ✓ Ready in 1141ms -⚡ Electron | ✅ Electron window ready -⚡ Electron | [nodemon] restarting due to changes... -``` - -### Debug avancé - -Pour plus de détails pendant le développement : - -```bash -# Mode verbose avec tous les logs -npm run electron-dev-verbose - -# Ou modifiez .env.local -DEBUG_ELECTRON=true -NODEMON_VERBOSE=true -``` - -### Build pour production - -```bash -# Build complet -npm run preelectron-pack -npm run electron-pack - -# Ou séparément -npm run build -npm run electron-pack -``` - -Les exécutables seront générés dans le dossier `dist/`. - -## 🎯 Fonctionnalités - -### ✅ Implémenté -- ✅ Interface Next.js moderne -- ✅ Application Electron native -- ✅ Hot-reload en développement -- ✅ Configuration par variables d'environnement -- ✅ Logs propres et colorés -- ✅ Rechargement automatique avec nodemon -- ✅ Build de production -- ✅ Gestion des erreurs - -### 🚧 En développement -- 🚧 Interface utilisateur du launcher -- 🚧 Gestion des jeux installés -- 🚧 Système de mise à jour -- 🚧 Thèmes personnalisables - -### 📋 Roadmap -- [ ] Intégration Steam/Epic Games -- [ ] Chat intégré -- [ ] Store de mods -- [ ] Système d'achievements -- [ ] Profils utilisateur - -## 🛠️ Problèmes courants - -### Erreurs Electron - -Si vous rencontrez des erreurs `Autofill.enable` : -```bash -# Dans .env.local -ELECTRON_DISABLE_SECURITY_WARNINGS=true ``` - -### Port déjà utilisé - -Si le port 3000 est occupé : -```bash -# Dans .env.local -NEXT_DEV_URL=http://localhost:3001 -``` - -Puis lancez Next.js sur le nouveau port : -```bash -npx next dev -p 3001 +src/ +├── main/ # Process principal Electron (IPC, auth, téléchargement, jeu) +├── preload/ # Pont sécurisé contextBridge → window.api +├── renderer/ # Application React (composants, vues, stores, i18n) +└── shared/ # Types TypeScript partagés (main, preload, renderer) +docs/ # Documentation contributeur (en/ et fr/) +resources/ # Icônes et entitlements macOS (versionnés) ``` -### Problèmes de performance +Alias TypeScript / Vite : `@shared`, `@components`, `@views`, `@stores`, `@hooks`, `@lib`, `@i18n`, `@content`, `@assets`. -Pour optimiser les performances : -```bash -# Dans .env.local -ENABLE_DEVTOOLS=false -DEBUG_ELECTRON=false -``` +## Prérequis -## 🤝 Contribution +- Node.js 20+ +- [pnpm](https://pnpm.io/) (gestionnaire de paquets du dépôt) -Les contributions sont les bienvenues ! Voici comment procéder : - -### Setup développeur +## Installation ```bash -# Fork et clone -git clone https://github.com/VOTRE-USERNAME/launcher.git +git clone https://github.com/DyingStar-game/launcher.git cd launcher - -# Installation -npm run setup - -# Créer une branche -git checkout -b feature/ma-fonctionnalite +git checkout develop +pnpm install +cp .env.example .env +# Éditer .env selon l’environnement (API, ZIP de test, etc.) ``` -### Workflow de contribution - -1. **Fork** le projet -2. **Créer** une branche pour votre fonctionnalité (`git checkout -b feature/AmazingFeature`) -3. **Commit** vos changements (`git commit -m 'Add some AmazingFeature'`) -4. **Push** vers la branche (`git push origin feature/AmazingFeature`) -5. **Ouvrir** une Pull Request - -### Standards de code - -- Utilisez les variables d'environnement pour la configuration -- Ajoutez des logs avec les préfixes appropriés -- Testez en mode développement ET production -- Documentez les nouvelles variables d'environnement - -## 📝 License - -Ce projet est sous licence MIT - voir le fichier [LICENSE](LICENSE) pour plus de détails. - -## 📞 Support - -Pour toute question ou problème : +## Scripts -- 🐛 **Bugs** : [Ouvrir une issue](https://github.com/DyingStar-game/launcher/issues) -- 💡 **Suggestions** : [Discussions](https://github.com/DyingStar-game/launcher/discussions) -- 📧 **Contact** : Contactez l'équipe de développement +| Commande | Description | +| ---------------------- | ------------------------------------------------------ | +| `pnpm run dev` | Développement avec rechargement à chaud | +| `pnpm run build` | Vérification TypeScript + build de production (`out/`) | +| `pnpm run start` | Prévisualiser le build packagé | +| `pnpm run typecheck` | Contrôle TypeScript (main + renderer) | +| `pnpm run lint` | ESLint | +| `pnpm run lint:fix` | ESLint avec corrections automatiques | +| `pnpm run format` | Prettier | +| `pnpm run build:win` | Installateur Windows (NSIS) | +| `pnpm run build:mac` | Application macOS | +| `pnpm run build:linux` | AppImage / deb / rpm | -## 🏆 Contributeurs +Les artefacts de distribution sont générés dans `release/`. -Merci à tous les contributeurs qui ont participé à ce projet ! +## Variables d’environnement ---- +Copier `.env.example` vers `.env`. Les variables exposées au code utilisent le préfixe `VITE_` (voir le fichier d’exemple pour les URLs d’API, archives de jeu, navigation, statut serveur, etc.). -*Développé avec ❤️ par l'équipe DyingStar* +## Contribution -# README GENERATED BY ELECTRON +**Branche de développement par défaut : `develop`** (ne pas partir de `main` pour le dev quotidien). -An Electron application with React and TypeScript +Documentation bilingue : -## Recommended IDE Setup +- Index : [docs/README.md](docs/README.md) +- Onboarding : [English](docs/en/ONBOARDING.md) · [Français](docs/fr/ONBOARDING.md) +- Contributing : [English](docs/en/CONTRIBUTING.md) · [Français](docs/fr/CONTRIBUTING.md) -- [VSCode](https://code.visualstudio.com/) + [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) +Avant une PR : `pnpm run typecheck && pnpm run lint` -## Project Setup +## Licence -### Install - -```bash -$ npm install -``` - -### Development - -```bash -$ npm run dev -``` - -### Build - -```bash -# For windows -$ npm run build:win - -# For macOS -$ npm run build:mac - -# For Linux -$ npm run build:linux -``` +[MIT License](LICENSE) — Copyright (c) Dying Star diff --git a/dev-app-update.yml b/dev-app-update.yml deleted file mode 100644 index ee464d9..0000000 --- a/dev-app-update.yml +++ /dev/null @@ -1,3 +0,0 @@ -provider: generic -url: https://example.com/auto-updates -updaterCacheDirName: react-ts-updater diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..ff533f9 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,10 @@ +# Project documentation + +Bilingual documentation for contributors and maintainers. + +| Language | Onboarding | Contributing | Code of conduct | Security | Changelog | +| -------- | ------------------------------------ | ---------------------------------------- | ---------------------------------------------- | -------------------------------- | ---------------------------------- | +| English | [en/ONBOARDING.md](en/ONBOARDING.md) | [en/CONTRIBUTING.md](en/CONTRIBUTING.md) | [en/CODE_OF_CONDUCT.md](en/CODE_OF_CONDUCT.md) | [en/SECURITY.md](en/SECURITY.md) | [en/CHANGELOG.md](en/CHANGELOG.md) | +| Français | [fr/ONBOARDING.md](fr/ONBOARDING.md) | [fr/CONTRIBUTING.md](fr/CONTRIBUTING.md) | [fr/CODE_OF_CONDUCT.md](fr/CODE_OF_CONDUCT.md) | [fr/SECURITY.md](fr/SECURITY.md) | [fr/CHANGELOG.md](fr/CHANGELOG.md) | + +**Default development branch:** `develop` (create feature branches from `develop`, not `main`). diff --git a/docs/en/CHANGELOG.md b/docs/en/CHANGELOG.md new file mode 100644 index 0000000..e70ca78 --- /dev/null +++ b/docs/en/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog + +All notable changes to this project are documented here. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.2.0] - 2026-05-16 + +### Added + +- Bilingual contributor docs under `docs/en/` and `docs/fr/` (onboarding, contributing, security, code of conduct) +- Structured install progress labels with full UI i18n (`installProgress.*`) +- Browser language detection and persisted UI language (`ds-language`) +- github actions for build the launcher + +### Changed + +- Package manager standardized on **pnpm** (removed `package-lock.json`) +- Native install folder dialog localized (fr/en) via main-process l10n +- Social `addFriend` mock validates duplicate names and throws typed errors + +### Removed + +- Unused `game:get-state` IPC stub + +## [0.1.0] - 2025-01-01 + +### Added + +- Initial open-source Electron launcher: auth, game install/update, server status, lore, social UI (mock) + +[Unreleased]: https://github.com/DyingStar-game/launcher/compare/v0.1.0...develop +[0.1.0]: https://github.com/DyingStar-game/launcher/releases/tag/v0.1.0 diff --git a/docs/en/CODE_OF_CONDUCT.md b/docs/en/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..10356dd --- /dev/null +++ b/docs/en/CODE_OF_CONDUCT.md @@ -0,0 +1,32 @@ +# Contributor Code of Conduct + +## Our pledge + +We pledge to make participation in the Dying Star Launcher project a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our standards + +Examples of behavior that contributes to a positive environment: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy toward other community members + +Examples of unacceptable behavior: + +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others’ private information without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement + +Project maintainers may remove, edit, or reject comments, commits, code, issues, and other contributions that are not aligned with this Code of Conduct, and may ban contributors temporarily or permanently. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to **contact@dyingstar-game.com**. All complaints will be reviewed and investigated promptly and fairly. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1. diff --git a/docs/en/CONTRIBUTING.md b/docs/en/CONTRIBUTING.md new file mode 100644 index 0000000..962438f --- /dev/null +++ b/docs/en/CONTRIBUTING.md @@ -0,0 +1,58 @@ +# Contributing + +Thank you for contributing to Dying Star Launcher. + +## Quick links + +- [Onboarding](ONBOARDING.md) — architecture, setup, branches +- [Code of conduct](CODE_OF_CONDUCT.md) +- [Security policy](SECURITY.md) +- [Changelog](CHANGELOG.md) + +## Development workflow + +1. Fork the repository (if external contributor) and clone locally +2. Check out **`develop`** and create a branch: `feature/short-description` or `fix/short-description` +3. Install dependencies with **pnpm only**: `pnpm install` +4. Copy `.env.example` to `.env` and configure as needed +5. Make your changes +6. Run checks: + ```bash + pnpm run format + pnpm run typecheck + pnpm run lint + ``` +7. Open a Pull Request **into `develop`** + +## Code guidelines + +- **TypeScript** everywhere; avoid `any` unless justified +- **Comments and JSDoc** on public APIs and non-obvious logic — in **English** +- **User-facing strings** only via i18n (`src/renderer/i18n/*.json`), not hardcoded in components +- **IPC**: add handlers in `src/main`, expose in `src/preload/index.ts`, types in `src/preload/index.d.ts` and `@shared/types` when shared +- Keep PRs small and focused; one topic per PR when possible + +## Commit messages + +Use clear, imperative subjects, e.g.: + +- `feat(files): add install path validation` +- `fix(auth): handle cancelled OAuth flow` +- `docs: update onboarding for pnpm` + +## Pull request checklist + +- [ ] Based on latest `develop` +- [ ] `pnpm run typecheck` passes +- [ ] `pnpm run lint` passes (or only pre-existing warnings documented) +- [ ] User-visible changes reflected in `docs/en/CHANGELOG.md` and `docs/fr/CHANGELOG.md` +- [ ] No secrets or `.env` files committed +- [ ] Screenshots attached for UI changes (optional but appreciated) + +## Releases + +Maintainers merge `develop` → `main` and tag releases. Built artifacts are published via GitHub Releases (see root `README.md` build scripts). + +## License + +By contributing, you agree that your contributions are licensed under the [MIT License](../../LICENSE) of this project. diff --git a/docs/en/ONBOARDING.md b/docs/en/ONBOARDING.md new file mode 100644 index 0000000..6250d19 --- /dev/null +++ b/docs/en/ONBOARDING.md @@ -0,0 +1,166 @@ +# Contributor onboarding + +Welcome to the **Dying Star Launcher** repository. This guide helps you understand the project and get a working dev environment quickly. + +## What this project is + +A desktop **Electron** launcher for the game _Dying Star_. It handles: + +- Discord / Keycloak authentication (per environment) +- Game download, install, and updates (ZIP from configurable URLs) +- Server status and player count +- Launcher update checks (GitHub Releases) +- Lore articles (bundled markdown) and a **social UI** (currently mock data) + +## Repository layout + +``` +src/ +├── main/ # Electron main process (IPC, auth, download, game launch) +├── preload/ # contextBridge API exposed as window.api +├── renderer/ # React UI (views, components, Zustand stores, i18n) +└── shared/ # TypeScript types shared across processes +docs/ # Contributor docs (en/ and fr/) +resources/ # App icons and macOS entitlements +``` + +Path aliases (Vite/TS): `@shared`, `@components`, `@views`, `@stores`, `@hooks`, `@lib`, `@i18n`, `@content`, `@assets`. + +## Branches + +| Branch | Purpose | +| ---------------- | ----------------------------------------------------------- | +| **`develop`** | **Default branch for development.** Open PRs here. | +| `main` | Stable / release-aligned (maintainers merge from `develop`) | +| Feature branches | `feature/your-topic` from `develop` | + +```bash +git checkout develop +git pull origin develop +git checkout -b feature/my-change +``` + +## Prerequisites + +- **Node.js 20+** +- **pnpm** (only package manager used in this repo — see root `packageManager` in `package.json`) +- Git + +## First-time setup + +```bash +git clone https://github.com/DyingStar-game/launcher.git +cd launcher +git checkout develop +pnpm install +cp .env.example .env +# Edit .env — at minimum set API/ZIP URLs for universe-testing if you want installs +pnpm run dev +``` + +### Environment files + +- Copy `.env.example` → `.env` (never commit `.env`) +- Variables prefixed with `VITE_` are embedded at build time in the app binary +- For local UI-only work, testing URLs in `.env.example` may be enough; production URLs are often empty until configured + +### Useful scripts + +| Command | Description | +| -------------------- | ---------------------------- | +| `pnpm run dev` | Hot-reload development | +| `pnpm run typecheck` | TypeScript (main + renderer) | +| `pnpm run lint` | ESLint | +| `pnpm run format` | Prettier | +| `pnpm run build` | Production build to `out/` | + +## ESLint and Prettier + +The repo ships with **ESLint 9** (flat config) and **Prettier**. They are installed with `pnpm install` — no global install required. + +### Configuration files + +| File | Role | +| ------------------- | ------------------------------------------------------------------- | +| `eslint.config.mjs` | ESLint flat config (TypeScript, React, Hooks, Prettier integration) | +| `.prettierrc.yaml` | Prettier rules (single quotes, no semicolons, print width 100) | +| `.prettierignore` | Paths excluded from formatting (`out/`, lockfiles, etc.) | + +ESLint uses `@electron-toolkit/eslint-config-prettier` so formatting is handled by Prettier, not duplicate ESLint style rules. + +### Commands (repo root) + +```bash +# Lint check (required before a PR) +pnpm run lint + +# Auto-fix what ESLint can (including Prettier issues reported via eslint) +pnpm run lint:fix + +# Format the whole project with Prettier +pnpm run format +``` + +Recommended workflow before committing: + +```bash +pnpm run format +pnpm run typecheck +pnpm run lint +``` + +### VS Code / Cursor + +Recommended workspace files live in `.vscode/`: + +1. Install extensions (folder prompt or manually): + - **ESLint** (`dbaeumer.vscode-eslint`) + - **Prettier** (`esbenp.prettier-vscode`) +2. `.vscode/settings.json` sets Prettier as the default formatter and enables format on save for TypeScript/JavaScript/JSON. + +If format on save does not run, set **Default Formatter** to Prettier and enable **Editor: Format On Save**. + +### CI + +When GitHub Actions is added, run `pnpm run typecheck` and `pnpm run lint` on every PR to `develop`. + +## How the app is structured (mental model) + +1. **Renderer** (React + Zustand) calls **`window.api.*`** from the preload script. +2. **Preload** forwards calls via `ipcRenderer.invoke` to **main** handlers. +3. **Main** performs filesystem, network, OAuth, and game process work, then pushes events back (e.g. auth state, install progress). + +Install progress uses **structured keys** (`InstallProgressLabel` in `src/shared/types/installProgress.ts`) sent from main; the renderer translates them with i18next (`installProgress.*` keys). + +## Internationalization (i18n) + +- UI strings: `src/renderer/i18n/en.json` and `fr.json` +- Use `useTranslation()` and `t('key')` in components — no user-facing hardcoded strings in TSX +- Language: browser detection + `localStorage` key `ds-language`; navbar flags switch EN/FR +- Native folder picker (main): `src/main/l10n/dialogs.ts` (OS locale fr/en) + +## Features to know about + +### Social page (mock) + +`src/renderer/stores/social.ts` uses **in-memory mock data** until backend APIs exist. Friend/org actions simulate latency; errors use `SocialStoreError` codes mapped in `src/renderer/lib/socialErrors.ts`. + +### Two game environments + +- `universe` — production +- `universe-testing` — test server / data + +The navbar env switcher changes `useEnvStore().activeEnv`; most stores are keyed by `Env`. + +## Before opening a PR + +1. Branch from **`develop`** +2. Run `pnpm run typecheck && pnpm run lint` +3. Keep changes focused; match existing code style +4. Update `docs/en/CHANGELOG.md` and `docs/fr/CHANGELOG.md` for user-visible changes (Unreleased section) +5. Read [CONTRIBUTING.md](CONTRIBUTING.md) + +## Getting help + +- Open a GitHub Discussion or Issue (for bugs, use the issue template when available) +- Security issues: see [SECURITY.md](SECURITY.md) — do **not** open public issues for vulnerabilities diff --git a/docs/en/SECURITY.md b/docs/en/SECURITY.md new file mode 100644 index 0000000..8149a0e --- /dev/null +++ b/docs/en/SECURITY.md @@ -0,0 +1,36 @@ +# Security policy + +## Supported versions + +Security fixes are applied to the latest release on the default branch and backported at maintainers’ discretion. + +| Version | Supported | +| -------------- | ----------- | +| Latest release | Yes | +| Older releases | Best effort | + +## Reporting a vulnerability + +**Please do not open a public GitHub issue for security vulnerabilities.** + +Instead, email **contact@dyingstar-game.com** with: + +- A description of the issue and impact +- Steps to reproduce +- Affected versions or commits if known +- Any proof-of-concept (optional) + +We aim to acknowledge reports within a few business days and will coordinate disclosure after a fix is available. + +## Scope notes for this project + +- The launcher runs with elevated filesystem access for game install paths; only install to directories you trust. +- OAuth tokens are stored locally per environment; protect your user profile on shared machines. +- Variables prefixed with `VITE_` are embedded in the built application — never put secrets in `.env` with that prefix. +- Lore markdown is bundled locally; remote untrusted markdown is not loaded in production paths today. + +## Safe defaults for contributors + +- Keep `VITE_ENABLE_DEVTOOLS=false` in release builds +- Do not commit `.env`, tokens, or private keys +- Review IPC handlers for path traversal when touching filesystem code diff --git a/docs/fr/CHANGELOG.md b/docs/fr/CHANGELOG.md new file mode 100644 index 0000000..90ed62e --- /dev/null +++ b/docs/fr/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog + +Toutes les modifications notables du projet sont documentées ici. + +Format inspiré de [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/), +versionnage [Semantic Versioning](https://semver.org/lang/fr/). + +## [Non publié] + +## [0.2.0] - 2026-05-16 + +### Ajouté + +- Documentation contributeur bilingue dans `docs/en/` et `docs/fr/` (onboarding, contribution, sécurité, code de conduite) +- Libellés de progression d’installation structurés et i18n UI (`installProgress.*`) +- Détection de la langue navigateur et persistance (`ds-language`) +- github actions pour build le launcher + +### Modifié + +- Gestionnaire de paquets **pnpm** uniquement (suppression de `package-lock.json`) +- Dialogue natif de dossier d’installation localisé (fr/en) côté main +- Mock `addFriend` : validation des doublons et erreurs typées + +### Supprimé + +- Stub IPC inutilisé `game:get-state` + +## [0.1.0] - 2025-01-01 + +### Ajouté + +- Premier launcher Electron open source : auth, install/mise à jour jeu, statut serveur, lore, UI social (mock) + +[Non publié]: https://github.com/DyingStar-game/launcher/compare/v0.1.0...develop +[0.1.0]: https://github.com/DyingStar-game/launcher/releases/tag/v0.1.0 diff --git a/docs/fr/CODE_OF_CONDUCT.md b/docs/fr/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..4aed1fb --- /dev/null +++ b/docs/fr/CODE_OF_CONDUCT.md @@ -0,0 +1,32 @@ +# Code de conduite des contributeurs + +## Engagement + +Nous nous engageons à faire de la participation au projet Dying Star Launcher une expérience sans harcèlement pour tous, quels que soient l’âge, le corps, le handicap, l’ethnie, l’identité et l’expression de genre, le niveau d’expérience, la nationalité, l’apparence, la race, la religion ou l’orientation sexuelle. + +## Comportements attendus + +Exemples de comportements qui contribuent à un environnement positif : + +- Langage accueillant et inclusif +- Respect des points de vue et expériences différentes +- Acceptation constructive des critiques +- Priorité à l’intérêt de la communauté +- Empathie envers les autres membres + +Exemples de comportements inacceptables : + +- Trolling, insultes, attaques personnelles ou politiques +- Harcèlement public ou privé +- Publication d’informations privées sans consentement +- Tout comportement inapproprié dans un cadre professionnel + +## Application + +Les mainteneurs peuvent supprimer, modifier ou rejeter contributions, issues et commentaires non conformes, et exclure temporairement ou définitivement un contributeur. + +Les signalements peuvent être envoyés à **contact@dyingstar-game.com**. Ils seront traités de manière confidentielle et équitable. + +## Attribution + +Adapté du [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1. diff --git a/docs/fr/CONTRIBUTING.md b/docs/fr/CONTRIBUTING.md new file mode 100644 index 0000000..c06e293 --- /dev/null +++ b/docs/fr/CONTRIBUTING.md @@ -0,0 +1,58 @@ +# Contribuer + +Merci de contribuer au Dying Star Launcher. + +## Liens utiles + +- [Onboarding](ONBOARDING.md) — architecture, installation, branches +- [Code de conduite](CODE_OF_CONDUCT.md) +- [Politique de sécurité](SECURITY.md) +- [Changelog](CHANGELOG.md) + +## Workflow + +1. Fork (contributeur externe) et clone +2. Se placer sur **`develop`**, créer une branche : `feature/description` ou `fix/description` +3. Installer avec **pnpm uniquement** : `pnpm install` +4. Copier `.env.example` → `.env` +5. Implémenter les changements +6. Vérifications : + ```bash + pnpm run format + pnpm run typecheck + pnpm run lint + ``` +7. Ouvrir une Pull Request **vers `develop`** + +## Conventions de code + +- **TypeScript** ; éviter `any` sans raison +- **Commentaires et JSDoc** en **anglais** sur les APIs et logique non triviale +- **Textes UI** uniquement via i18n (`src/renderer/i18n/*.json`) +- **IPC** : handler dans `src/main`, exposition dans `preload`, types dans `@shared/types` si partagés +- PRs courtes et ciblées + +## Messages de commit + +Sujets clairs à l’impératif, par ex. : + +- `feat(files): validate install path` +- `fix(auth): handle cancelled OAuth` +- `docs: onboarding pnpm` + +## Checklist PR + +- [ ] Basée sur `develop` à jour +- [ ] `pnpm run typecheck` OK +- [ ] `pnpm run lint` OK +- [ ] Changelog EN + FR mis à jour si changement visible +- [ ] Pas de secrets ni de `.env` commité +- [ ] Captures d’écran pour changements UI (optionnel) + +## Releases + +Les mainteneurs fusionnent `develop` → `main` et taguent. Voir le `README.md` racine pour les builds. + +## Licence + +En contribuant, tu acceptes la licence [MIT](../../LICENSE) du projet. diff --git a/docs/fr/ONBOARDING.md b/docs/fr/ONBOARDING.md new file mode 100644 index 0000000..c20b574 --- /dev/null +++ b/docs/fr/ONBOARDING.md @@ -0,0 +1,166 @@ +# Onboarding contributeur + +Bienvenue dans le dépôt **Dying Star Launcher**. Ce guide t’aide à comprendre le projet et à lancer un environnement de dev rapidement. + +## De quoi il s’agit + +Un **launcher Electron** pour le jeu _Dying Star_. Il gère notamment : + +- Authentification Discord / Keycloak (par environnement) +- Téléchargement, installation et mises à jour du jeu (ZIP via URLs configurables) +- Statut serveur et nombre de joueurs +- Vérification des mises à jour du launcher (GitHub Releases) +- Articles de lore (markdown embarqué) et une **UI social** (données mock pour l’instant) + +## Arborescence + +``` +src/ +├── main/ # Process Electron principal (IPC, auth, téléchargement, lancement jeu) +├── preload/ # API contextBridge exposée en window.api +├── renderer/ # UI React (vues, composants, stores Zustand, i18n) +└── shared/ # Types TypeScript partagés entre processus +docs/ # Documentation contributeur (en/ et fr/) +resources/ # Icônes et entitlements macOS +``` + +Alias (Vite/TS) : `@shared`, `@components`, `@views`, `@stores`, `@hooks`, `@lib`, `@i18n`, `@content`, `@assets`. + +## Branches + +| Branche | Rôle | +| ---------------- | ---------------------------------------------------------------------- | +| **`develop`** | **Branche par défaut pour le développement.** Ouvre tes PR ici. | +| `main` | Stable / alignée releases (merge depuis `develop` par les mainteneurs) | +| Branches feature | `feature/ton-sujet` depuis `develop` | + +```bash +git checkout develop +git pull origin develop +git checkout -b feature/ma-modif +``` + +## Prérequis + +- **Node.js 20+** +- **pnpm** (seul gestionnaire de paquets du dépôt — voir `packageManager` dans `package.json`) +- Git + +## Première installation + +```bash +git clone https://github.com/DyingStar-game/launcher.git +cd launcher +git checkout develop +pnpm install +cp .env.example .env +# Éditer .env — au minimum les URLs universe-testing pour tester l’install +pnpm run dev +``` + +### Fichiers d’environnement + +- Copier `.env.example` → `.env` (ne jamais committer `.env`) +- Les variables `VITE_*` sont incluses dans le binaire au build +- Pour travailler sur l’UI seule, les URLs de test dans l’exemple peuvent suffire + +### Scripts utiles + +| Commande | Description | +| -------------------- | ----------------------------- | +| `pnpm run dev` | Dev avec rechargement à chaud | +| `pnpm run typecheck` | TypeScript (main + renderer) | +| `pnpm run lint` | ESLint | +| `pnpm run format` | Prettier | +| `pnpm run build` | Build production dans `out/` | + +## ESLint et Prettier + +Le dépôt inclut **ESLint 9** (flat config) et **Prettier**, installés via `pnpm install` (pas d’installation globale nécessaire). + +### Fichiers de configuration + +| Fichier | Rôle | +| ------------------- | --------------------------------------------------------------------- | +| `eslint.config.mjs` | Config ESLint flat (TypeScript, React, Hooks, intégration Prettier) | +| `.prettierrc.yaml` | Règles Prettier (guillemets simples, sans point-virgule, largeur 100) | +| `.prettierignore` | Chemins exclus (`out/`, lockfiles, etc.) | + +`@electron-toolkit/eslint-config-prettier` évite les conflits : le formatage est géré par Prettier. + +### Commandes (racine du dépôt) + +```bash +# Vérifier le lint (obligatoire avant une PR) +pnpm run lint + +# Corriger automatiquement (y compris Prettier via eslint) +pnpm run lint:fix + +# Formater tout le projet +pnpm run format +``` + +Workflow recommandé avant commit : + +```bash +pnpm run format +pnpm run typecheck +pnpm run lint +``` + +### VS Code / Cursor + +Fichiers recommandés dans `.vscode/` : + +1. Extensions : + - **ESLint** (`dbaeumer.vscode-eslint`) + - **Prettier** (`esbenp.prettier-vscode`) +2. `.vscode/settings.json` : Prettier par défaut + format à l’enregistrement. + +Sinon : formateur par défaut **Prettier** + **Format On Save** activé. + +### CI + +À terme : `pnpm run typecheck` et `pnpm run lint` sur chaque PR vers `develop`. + +## Modèle mental de l’app + +1. Le **renderer** (React + Zustand) appelle **`window.api.*`** via le preload. +2. Le **preload** transmet via `ipcRenderer.invoke` vers les handlers **main**. +3. Le **main** fait le réseau, fichiers, OAuth, process jeu, et renvoie des événements (auth, progression install). + +La progression d’installation utilise des **clés structurées** (`InstallProgressLabel` dans `src/shared/types/installProgress.ts`) ; le renderer les traduit via i18next (`installProgress.*`). + +## Internationalisation (i18n) + +- Chaînes UI : `src/renderer/i18n/en.json` et `fr.json` +- `useTranslation()` + `t('clé')` dans les composants — pas de texte utilisateur en dur dans le TSX +- Langue : détection navigateur + `localStorage` (`ds-language`) ; drapeaux dans la navbar +- Dialogue dossier natif (main) : `src/main/l10n/dialogs.ts` (locale OS fr/en) + +## Points importants + +### Page Social (mock) + +`src/renderer/stores/social.ts` utilise des **données mock** en attendant les APIs. Les erreurs passent par `SocialStoreError` et `src/renderer/lib/socialErrors.ts`. + +### Deux environnements jeu + +- `universe` — production +- `universe-testing` — test + +Le sélecteur de la navbar change `useEnvStore().activeEnv` ; la plupart des stores sont indexés par `Env`. + +## Avant d’ouvrir une PR + +1. Partir de **`develop`** +2. `pnpm run typecheck && pnpm run lint` +3. PR focalisée, style cohérent avec le dépôt +4. Mettre à jour `docs/en/CHANGELOG.md` et `docs/fr/CHANGELOG.md` si changement visible utilisateur (section Unreleased) +5. Lire [CONTRIBUTING.md](CONTRIBUTING.md) + +## Aide + +- Discussion ou Issue GitHub +- Sécurité : [SECURITY.md](SECURITY.md) — **pas** d’issue publique pour une vulnérabilité diff --git a/docs/fr/SECURITY.md b/docs/fr/SECURITY.md new file mode 100644 index 0000000..3047e12 --- /dev/null +++ b/docs/fr/SECURITY.md @@ -0,0 +1,36 @@ +# Politique de sécurité + +## Versions prises en charge + +Les correctifs de sécurité sont appliqués sur la dernière release et la branche principale, avec backport au jugement des mainteneurs. + +| Version | Support | +| -------------------- | --------------- | +| Dernière release | Oui | +| Versions antérieures | Meilleur effort | + +## Signaler une vulnérabilité + +**Ne pas ouvrir d’issue GitHub publique pour une vulnérabilité.** + +Envoyer un e-mail à **contact@dyingstar-game.com** avec : + +- Description et impact +- Étapes de reproduction +- Versions ou commits concernés +- PoC éventuel + +Accusé de réception sous quelques jours ouvrés ; coordination de la divulgation après correctif. + +## Périmètre spécifique au launcher + +- Accès disque pour l’installation du jeu — n’installer que dans des dossiers de confiance. +- Jetons OAuth stockés localement par environnement — protéger le profil utilisateur sur machine partagée. +- Les variables `VITE_*` sont incluses dans le binaire — **jamais** de secrets avec ce préfixe. +- Le lore est du markdown embarqué ; pas de chargement markdown distant non fiable en prod aujourd’hui. + +## Bonnes pratiques contributeurs + +- `VITE_ENABLE_DEVTOOLS=false` pour les builds release +- Ne pas committer `.env`, jetons ou clés privées +- Vérifier le path traversal sur les handlers IPC touchant le filesystem diff --git a/electron-builder.yml b/electron-builder.yml deleted file mode 100644 index 9b4abf4..0000000 --- a/electron-builder.yml +++ /dev/null @@ -1,48 +0,0 @@ -appId: com.electron.app -productName: react-ts -protocols: - - name: DyingStar Launcher - schemes: - - dyingstar -directories: - buildResources: build -files: - - '!**/.vscode/*' - - '!src/*' - - '!electron.vite.config.{js,ts,mjs,cjs}' - - '!{.eslintcache,eslint.config.mjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' - - '!{.env,.env.*,.npmrc,pnpm-lock.yaml}' - - '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}' -asarUnpack: - - resources/** -win: - executableName: react-ts -nsis: - artifactName: ${name}-${version}-setup.${ext} - shortcutName: ${productName} - uninstallDisplayName: ${productName} - createDesktopShortcut: always -mac: - entitlementsInherit: build/entitlements.mac.plist - extendInfo: - - NSCameraUsageDescription: Application requests access to the device's camera. - - NSMicrophoneUsageDescription: Application requests access to the device's microphone. - - NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder. - - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. - notarize: false -dmg: - artifactName: ${name}-${version}.${ext} -linux: - target: - - AppImage - - snap - - deb - - rpm - maintainer: electronjs.org - category: Utility -appImage: - artifactName: ${name}-${version}.${ext} -npmRebuild: false -publish: - provider: generic - url: https://example.com/auto-updates diff --git a/electron.vite.config.ts b/electron.vite.config.ts index 274b8df..6b1bbbf 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -3,24 +3,35 @@ import { defineConfig, loadEnv } from 'electron-vite' import react from '@vitejs/plugin-react' import tailwindcss from '@tailwindcss/vite' -export default defineConfig(({mode}) => { - +const sharedAlias = { + '@shared': resolve(__dirname, 'src/shared') +} + +const rendererAlias = { + ...sharedAlias, + '@hooks': resolve(__dirname, 'src/renderer/hooks'), + '@lib': resolve(__dirname, 'src/renderer/lib'), + '@assets': resolve(__dirname, 'src/renderer/assets'), + '@content': resolve(__dirname, 'src/renderer/content'), + '@stores': resolve(__dirname, 'src/renderer/stores'), + '@components': resolve(__dirname, 'src/renderer/components'), + '@views': resolve(__dirname, 'src/renderer/views'), + '@i18n': resolve(__dirname, 'src/renderer/i18n/index.ts') +} + +export default defineConfig(({ mode }) => { const env = loadEnv(mode) Object.assign(process.env, env) return { - main: {}, - preload: {}, + main: { + resolve: { alias: sharedAlias } + }, + preload: { + resolve: { alias: sharedAlias } + }, renderer: { - resolve: { - alias: { - '@renderer': resolve(__dirname, 'src/renderer/src'), - '@store': resolve(__dirname, 'src/renderer/store'), - '@components': resolve(__dirname, 'src/renderer/components'), - '@views': resolve(__dirname, 'src/renderer/views'), - '@i18n': resolve(__dirname, 'src/renderer/i18n') - } - }, + resolve: { alias: rendererAlias }, plugins: [tailwindcss(), react()] } } diff --git a/eslint.config.mjs b/eslint.config.mjs index aff5d3f..4ffc272 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -25,7 +25,8 @@ export default defineConfig( }, rules: { ...eslintPluginReactHooks.configs.recommended.rules, - ...eslintPluginReactRefresh.configs.vite.rules + ...eslintPluginReactRefresh.configs.vite.rules, + 'react/prop-types': 'off' } }, eslintConfigPrettier diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 6e7dbd9..0000000 --- a/package-lock.json +++ /dev/null @@ -1,12257 +0,0 @@ -{ - "name": "dying-star-launcher", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "dying-star-launcher", - "version": "1.0.0", - "hasInstallScript": true, - "dependencies": { - "@electron-toolkit/preload": "^3.0.2", - "@electron-toolkit/utils": "^4.0.0", - "axios": "^1.16.0", - "debug": "^4.4.3", - "electron-store": "^11.0.2", - "electron-updater": "^6.3.9", - "extract-zip": "^2.0.1", - "get-stream": "^9.0.1", - "i18next": "^26.0.8", - "ms": "^2.1.3", - "openid-client": "^6.8.4", - "react-i18next": "^17.0.6", - "react-markdown": "^10.1.0", - "rehype-raw": "^7.0.0", - "rehype-sanitize": "^6.0.0", - "remark-gfm": "^4.0.1", - "yauzl": "^3.3.0", - "zustand": "^5.0.13" - }, - "devDependencies": { - "@electron-toolkit/eslint-config-prettier": "^3.0.0", - "@electron-toolkit/eslint-config-ts": "^3.1.0", - "@electron-toolkit/tsconfig": "^2.0.0", - "@tailwindcss/vite": "^4.2.4", - "@types/extract-zip": "^2.0.3", - "@types/node": "^22.19.1", - "@types/react": "^19.2.7", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^5.1.1", - "autoprefixer": "^10.5.0", - "electron": "^39.2.6", - "electron-builder": "^26.0.12", - "electron-vite": "^5.0.0", - "eslint": "^9.39.1", - "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.4.24", - "prettier": "^3.7.4", - "react": "^19.2.1", - "react-dom": "^19.2.1", - "tailwindcss": "^4.2.4", - "typescript": "^5.9.3", - "vite": "^7.2.6" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", - "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", - "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", - "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", - "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@develar/schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/@electron-toolkit/eslint-config-prettier": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@electron-toolkit/eslint-config-prettier/-/eslint-config-prettier-3.0.0.tgz", - "integrity": "sha512-YapmIOVkbYdHLuTa+ad1SAVtcqYL9A/SJsc7cxQokmhcwAwonGevNom37jBf9slXegcZ/Slh01I/JARG1yhNFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-config-prettier": "^10.0.1", - "eslint-plugin-prettier": "^5.2.3" - }, - "peerDependencies": { - "eslint": ">= 9.0.0", - "prettier": ">= 3.0.0" - } - }, - "node_modules/@electron-toolkit/eslint-config-ts": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@electron-toolkit/eslint-config-ts/-/eslint-config-ts-3.1.0.tgz", - "integrity": "sha512-MowZQKd3yxXSDLack5QvjQwYHhpOJFoWBGBwJ/k+DCd7NUSendplECbQGFp86tPQYPUrPBPceR/hdsSAnaY5ZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint/js": "^9.24.0", - "globals": "^16.0.0", - "typescript-eslint": "^8.29.1" - }, - "peerDependencies": { - "eslint": ">=9.0.0", - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@electron-toolkit/preload": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@electron-toolkit/preload/-/preload-3.0.2.tgz", - "integrity": "sha512-TWWPToXd8qPRfSXwzf5KVhpXMfONaUuRAZJHsKthKgZR/+LqX1dZVSSClQ8OTAEduvLGdecljCsoT2jSshfoUg==", - "license": "MIT", - "peerDependencies": { - "electron": ">=13.0.0" - } - }, - "node_modules/@electron-toolkit/tsconfig": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@electron-toolkit/tsconfig/-/tsconfig-2.0.0.tgz", - "integrity": "sha512-AdPsP770WhW7b260h13SHMdmjEEHJL6xFtgi3jwgdsSQbJOkJLeNnnpZW9qxTPCvmRI6vmdzWz5K3gibFS6SNg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/node": "*" - } - }, - "node_modules/@electron-toolkit/utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@electron-toolkit/utils/-/utils-4.0.0.tgz", - "integrity": "sha512-qXSntwEzluSzKl4z5yFNBknmPGjPa3zFhE4mp9+h0cgokY5ornAeP+CJQDBhKsL1S58aOQfcwkD3NwLZCl+64g==", - "license": "MIT", - "peerDependencies": { - "electron": ">=13.0.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.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "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/fuses/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/@electron/fuses/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/@electron/get": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", - "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", - "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": ">=12" - }, - "optionalDependencies": { - "global-agent": "^3.0.0" - } - }, - "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/notarize/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/@electron/notarize/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/@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/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/@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/osx-sign/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/@electron/osx-sign/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/@electron/rebuild": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-4.0.4.tgz", - "integrity": "sha512-Rzc39XPdk/+/wBG8MfwAHohXflep0ITUfulb6Rgz3R0NeSB1noE+E9/M/cb8ftCAiyDD9PPhLuuWgE1GaInbKg==", - "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.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@electron/universal/node_modules/fs-extra": { - "version": "11.3.5", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz", - "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==", - "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/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/@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/universal/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/@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.3.5", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz", - "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==", - "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/@electron/windows-sign/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", - "optional": true, - "peer": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/windows-sign/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", - "optional": true, - "peer": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", - "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.5" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-array/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/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/config-array/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/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.14.0", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.5", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/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/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/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/@eslint/js": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", - "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", - "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/types": "^0.15.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", - "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.2", - "@humanfs/types": "^0.15.0", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/types": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", - "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "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/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "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/@malept/flatpak-bundler/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/@malept/flatpak-bundler/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/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", - "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.3.tgz", - "integrity": "sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.3.tgz", - "integrity": "sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.3.tgz", - "integrity": "sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.3.tgz", - "integrity": "sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.3.tgz", - "integrity": "sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.3.tgz", - "integrity": "sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.3.tgz", - "integrity": "sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==", - "cpu": [ - "arm" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.3.tgz", - "integrity": "sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==", - "cpu": [ - "arm" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.3.tgz", - "integrity": "sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.3.tgz", - "integrity": "sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.3.tgz", - "integrity": "sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==", - "cpu": [ - "loong64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.3.tgz", - "integrity": "sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==", - "cpu": [ - "loong64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.3.tgz", - "integrity": "sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.3.tgz", - "integrity": "sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.3.tgz", - "integrity": "sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.3.tgz", - "integrity": "sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.3.tgz", - "integrity": "sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.3.tgz", - "integrity": "sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.3.tgz", - "integrity": "sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.3.tgz", - "integrity": "sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.3.tgz", - "integrity": "sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.3.tgz", - "integrity": "sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.3.tgz", - "integrity": "sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.3.tgz", - "integrity": "sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.3.tgz", - "integrity": "sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sec-ant/readable-stream": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", - "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", - "license": "MIT" - }, - "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==", - "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==", - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tailwindcss/node": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz", - "integrity": "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.21.0", - "jiti": "^2.6.1", - "lightningcss": "1.32.0", - "magic-string": "^0.30.21", - "source-map-js": "^1.2.1", - "tailwindcss": "4.3.0" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz", - "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 20" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.3.0", - "@tailwindcss/oxide-darwin-arm64": "4.3.0", - "@tailwindcss/oxide-darwin-x64": "4.3.0", - "@tailwindcss/oxide-freebsd-x64": "4.3.0", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0", - "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0", - "@tailwindcss/oxide-linux-arm64-musl": "4.3.0", - "@tailwindcss/oxide-linux-x64-gnu": "4.3.0", - "@tailwindcss/oxide-linux-x64-musl": "4.3.0", - "@tailwindcss/oxide-wasm32-wasi": "4.3.0", - "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0", - "@tailwindcss/oxide-win32-x64-msvc": "4.3.0" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.0.tgz", - "integrity": "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.0.tgz", - "integrity": "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.0.tgz", - "integrity": "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.0.tgz", - "integrity": "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.0.tgz", - "integrity": "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.0.tgz", - "integrity": "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.0.tgz", - "integrity": "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.0.tgz", - "integrity": "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.0.tgz", - "integrity": "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.0.tgz", - "integrity": "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.10.0", - "@emnapi/runtime": "^1.10.0", - "@emnapi/wasi-threads": "^1.2.1", - "@napi-rs/wasm-runtime": "^1.1.4", - "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.0.tgz", - "integrity": "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.0.tgz", - "integrity": "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/vite": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.0.tgz", - "integrity": "sha512-t6J3OrB5Fc0ExuhohouH0fWUGMYL6PTLhW+E7zIk/pdbnJARZDCwjBznFnkh5ynRnIRSI4YjtTH0t6USjJISrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tailwindcss/node": "4.3.0", - "@tailwindcss/oxide": "4.3.0", - "tailwindcss": "4.3.0" - }, - "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7 || ^8" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } - }, - "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==", - "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==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", - "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", - "license": "MIT" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/extract-zip": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/extract-zip/-/extract-zip-2.0.3.tgz", - "integrity": "sha512-yrO7h+0qOIGxHCmBeL5fKFzR+PBafh9LG6sOLBFFi2JuN+Hj663TAxfnqJh5vkQn963VimrhBF1GZzea3A+4Ig==", - "deprecated": "This is a stub types definition. extract-zip provides its own type definitions, so you do not need this installed.", - "dev": true, - "license": "MIT", - "dependencies": { - "extract-zip": "*" - } - }, - "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/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "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==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.19.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.18.tgz", - "integrity": "sha512-9v00a+dn2yWVsYDEunWC4g/TcRKVq3r8N5FuZp7u0SGrPvdN9c2yXI9bBuf5Fl0hNCb+QTIePTn5pJs2pwBOQQ==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/plist": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", - "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*", - "xmlbuilder": ">=11.0.1" - } - }, - "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", - "license": "MIT", - "dependencies": { - "csstype": "^3.2.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.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==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, - "node_modules/@types/verror": { - "version": "1.10.11", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", - "integrity": "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.2.tgz", - "integrity": "sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.59.2", - "@typescript-eslint/type-utils": "8.59.2", - "@typescript-eslint/utils": "8.59.2", - "@typescript-eslint/visitor-keys": "8.59.2", - "ignore": "^7.0.5", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.59.2", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.2.tgz", - "integrity": "sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.59.2", - "@typescript-eslint/types": "8.59.2", - "@typescript-eslint/typescript-estree": "8.59.2", - "@typescript-eslint/visitor-keys": "8.59.2", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.2.tgz", - "integrity": "sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.59.2", - "@typescript-eslint/types": "^8.59.2", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.2.tgz", - "integrity": "sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.59.2", - "@typescript-eslint/visitor-keys": "8.59.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.2.tgz", - "integrity": "sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.2.tgz", - "integrity": "sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.59.2", - "@typescript-eslint/typescript-estree": "8.59.2", - "@typescript-eslint/utils": "8.59.2", - "debug": "^4.4.3", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.2.tgz", - "integrity": "sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz", - "integrity": "sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.59.2", - "@typescript-eslint/tsconfig-utils": "8.59.2", - "@typescript-eslint/types": "8.59.2", - "@typescript-eslint/visitor-keys": "8.59.2", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.2.tgz", - "integrity": "sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.59.2", - "@typescript-eslint/types": "8.59.2", - "@typescript-eslint/typescript-estree": "8.59.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.2.tgz", - "integrity": "sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.59.2", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", - "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", - "license": "ISC" - }, - "node_modules/@vitejs/plugin-react": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz", - "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.29.0", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-rc.3", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.18.0" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.13", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", - "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/7zip-bin": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz", - "integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==", - "dev": true, - "license": "MIT" - }, - "node_modules/abbrev": { - "version": "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/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.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": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/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==", - "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/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "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-bin": { - "version": "5.0.0-alpha.12", - "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz", - "integrity": "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/app-builder-lib": { - "version": "26.8.1", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.8.1.tgz", - "integrity": "sha512-p0Im/Dx5C4tmz8QEE1Yn4MkuPC8PrnlRneMhWJj7BBXQfNTJUshM/bp3lusdEsDbvvfJZpXWnYesgSLvwtM2Zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@develar/schema-utils": "~2.6.5", - "@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.3", - "@electron/universal": "2.0.3", - "@malept/flatpak-bundler": "^0.4.0", - "@types/fs-extra": "9.0.13", - "async-exit-hook": "^2.0.1", - "builder-util": "26.8.1", - "builder-util-runtime": "9.5.1", - "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.8.1", - "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.0.3", - "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", - "which": "^5.0.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "dmg-builder": "26.8.1", - "electron-builder-squirrel-windows": "26.8.1" - } - }, - "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/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/app-builder-lib/node_modules/fs-extra/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/app-builder-lib/node_modules/fs-extra/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/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/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", - "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.0", - "es-object-atoms": "^1.1.1", - "get-intrinsic": "^1.3.0", - "is-string": "^1.1.1", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", - "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", - "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "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/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/atomically": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.1.1.tgz", - "integrity": "sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ==", - "license": "MIT", - "dependencies": { - "stubborn-fs": "^2.0.0", - "when-exit": "^2.1.4" - } - }, - "node_modules/autoprefixer": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz", - "integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.28.2", - "caniuse-lite": "^1.0.30001787", - "fraction.js": "^5.3.4", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axios": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", - "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.16.0", - "form-data": "^4.0.5", - "proxy-from-env": "^2.1.0" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/baseline-browser-mapping": { - "version": "2.10.29", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz", - "integrity": "sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "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.", - "license": "MIT", - "optional": true - }, - "node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", - "update-browserslist-db": "^1.2.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/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.8.1", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.8.1.tgz", - "integrity": "sha512-pm1lTYbGyc90DHgCDO7eo8Rl4EqKLciayNbZqGziqnH9jrlKe8ZANGdityLZU+pJh16dfzjAx2xQq9McuIPEtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/debug": "^4.1.6", - "7zip-bin": "~5.2.0", - "app-builder-bin": "5.0.0-alpha.12", - "builder-util-runtime": "9.5.1", - "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" - } - }, - "node_modules/builder-util-runtime": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.5.1.tgz", - "integrity": "sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/builder-util/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/builder-util/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/builder-util/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/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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==", - "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==", - "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/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/call-bind": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", - "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "get-intrinsic": "^1.3.0", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001792", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", - "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "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==", - "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==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/conf": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/conf/-/conf-15.1.0.tgz", - "integrity": "sha512-Uy5YN9KEu0WWDaZAVJ5FAmZoaJt9rdK6kH+utItPyGsCqCgaTKkrmZx3zoE0/3q6S3bcp3Ihkk+ZqPxWxFK5og==", - "license": "MIT", - "dependencies": { - "ajv": "^8.17.1", - "ajv-formats": "^3.0.1", - "atomically": "^2.0.3", - "debounce-fn": "^6.0.0", - "dot-prop": "^10.0.0", - "env-paths": "^3.0.0", - "json-schema-typed": "^8.0.1", - "semver": "^7.7.2", - "uint8array-extras": "^1.5.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/conf/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==", - "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/conf/node_modules/env-paths": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", - "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/conf/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/conf/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "buffer": "^5.1.0" - } - }, - "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/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "license": "MIT" - }, - "node_modules/data-view-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/inspect-js" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debounce-fn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-6.0.0.tgz", - "integrity": "sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==", - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", - "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "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==", - "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==", - "devOptional": true, - "license": "MIT", - "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==", - "devOptional": true, - "license": "MIT", - "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==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "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==", - "license": "MIT", - "optional": true - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "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.8.1", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.8.1.tgz", - "integrity": "sha512-glMJgnTreo8CFINujtAhCgN96QAqApDMZ8Vl1r8f0QT8QprvC1UCltV4CcWj20YoIyLZx6IUskaJZ0NV8fokcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "app-builder-lib": "26.8.1", - "builder-util": "26.8.1", - "fs-extra": "^10.1.0", - "iconv-lite": "^0.6.2", - "js-yaml": "^4.1.0" - }, - "optionalDependencies": { - "dmg-license": "^1.0.11" - } - }, - "node_modules/dmg-builder/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/dmg-builder/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/dmg-builder/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/dmg-license": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", - "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "@types/plist": "^3.0.1", - "@types/verror": "^1.10.3", - "ajv": "^6.10.0", - "crc": "^3.8.0", - "iconv-corefoundation": "^1.1.7", - "plist": "^3.0.4", - "smart-buffer": "^4.0.2", - "verror": "^1.10.0" - }, - "bin": { - "dmg-license": "bin/dmg-license.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/dot-prop": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-10.1.0.tgz", - "integrity": "sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==", - "license": "MIT", - "dependencies": { - "type-fest": "^5.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "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==", - "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/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": "39.8.10", - "resolved": "https://registry.npmjs.org/electron/-/electron-39.8.10.tgz", - "integrity": "sha512-zbYtGPYUI7PzqLAzkk21Rk6j67WN0hxn0Mq/njErZo1d0HSf33is4f8ICI5fMLy5vYe0JtCtM5sYunNOaochSQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@electron/get": "^2.0.0", - "@types/node": "^22.7.7", - "extract-zip": "^2.0.1" - }, - "bin": { - "electron": "cli.js" - }, - "engines": { - "node": ">= 12.20.55" - } - }, - "node_modules/electron-builder": { - "version": "26.8.1", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.8.1.tgz", - "integrity": "sha512-uWhx1r74NGpCagG0ULs/P9Nqv2nsoo+7eo4fLUOB8L8MdWltq9odW/uuLXMFCDGnPafknYLZgjNX0ZIFRzOQAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "app-builder-lib": "26.8.1", - "builder-util": "26.8.1", - "builder-util-runtime": "9.5.1", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "dmg-builder": "26.8.1", - "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.8.1", - "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.8.1.tgz", - "integrity": "sha512-o288fIdgPLHA76eDrFADHPoo7VyGkDCYbLV1GzndaMSAVBoZrGvM9m2IehdcVMzdAZJ2eV9bgyissQXHv5tGzA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "app-builder-lib": "26.8.1", - "builder-util": "26.8.1", - "electron-winstaller": "5.4.0" - } - }, - "node_modules/electron-builder/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/electron-builder/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/electron-builder/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/electron-publish": { - "version": "26.8.1", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.8.1.tgz", - "integrity": "sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/fs-extra": "^9.0.11", - "builder-util": "26.8.1", - "builder-util-runtime": "9.5.1", - "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-publish/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/electron-publish/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/electron-publish/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/electron-store": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-11.0.2.tgz", - "integrity": "sha512-4VkNRdN+BImL2KcCi41WvAYbh6zLX5AUTi4so68yPqiItjbgTjqpEnGAqasgnG+lB6GuAyUltKwVopp6Uv+gwQ==", - "license": "MIT", - "dependencies": { - "conf": "^15.0.2", - "type-fest": "^5.0.1" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.353", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.353.tgz", - "integrity": "sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w==", - "dev": true, - "license": "ISC" - }, - "node_modules/electron-updater": { - "version": "6.8.3", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.8.3.tgz", - "integrity": "sha512-Z6sgw3jgbikWKXei1ENdqFOxBP0WlXg3TtKfz0rgw2vIZFJUyI4pD7ZN7jrkm7EoMK+tcm/qTnPUdqfZukBlBQ==", - "license": "MIT", - "dependencies": { - "builder-util-runtime": "9.5.1", - "fs-extra": "^10.1.0", - "js-yaml": "^4.1.0", - "lazy-val": "^1.0.5", - "lodash.escaperegexp": "^4.1.2", - "lodash.isequal": "^4.5.0", - "semver": "~7.7.3", - "tiny-typed-emitter": "^2.1.0" - } - }, - "node_modules/electron-updater/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/electron-updater/node_modules/jsonfile": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", - "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-updater/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-updater/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/electron-vite": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/electron-vite/-/electron-vite-5.0.0.tgz", - "integrity": "sha512-OHp/vjdlubNlhNkPkL/+3JD34ii5ov7M0GpuXEVdQeqdQ3ulvVR7Dg/rNBLfS5XPIFwgoBLDf9sjjrL+CuDyRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.28.4", - "@babel/plugin-transform-arrow-functions": "^7.27.1", - "cac": "^6.7.14", - "esbuild": "^0.25.11", - "magic-string": "^0.30.19", - "picocolors": "^1.1.1" - }, - "bin": { - "electron-vite": "bin/electron-vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "@swc/core": "^1.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - } - } - }, - "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/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==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.21.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.2.tgz", - "integrity": "sha512-xe9vQb5kReirPUxgQrXA3ihgbCqssmTiM7cOZ+Gzu+VeGWgpV98lLZvp0dl4yriyAePcewxGUs9UpKD8PET9KQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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-abstract": { - "version": "1.24.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", - "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.2", - "arraybuffer.prototype.slice": "^1.0.4", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.3.0", - "get-proto": "^1.0.1", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.2.1", - "is-set": "^2.0.3", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.1", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.4", - "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.4", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "stop-iteration-iterator": "^1.1.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.19" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-iterator-helpers": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.2.tgz", - "integrity": "sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.9", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.2", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.1.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.3.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "iterator.prototype": "^1.1.5", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "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/es-shim-unscopables": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", - "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "license": "MIT", - "optional": true - }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, - "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==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", - "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.2", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "9.39.4", - "@eslint/plugin-kit": "^0.4.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.14.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.5", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-config-prettier": { - "version": "10.1.8", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", - "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "funding": { - "url": "https://opencollective.com/eslint-config-prettier" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.5.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz", - "integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.1", - "synckit": "^0.11.12" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.37.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", - "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.8", - "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.3", - "array.prototype.tosorted": "^1.1.4", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.2.1", - "estraverse": "^5.3.0", - "hasown": "^2.0.2", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.9", - "object.fromentries": "^2.0.8", - "object.values": "^1.2.1", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.12", - "string.prototype.repeat": "^1.0.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", - "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.24.4", - "@babel/parser": "^7.24.4", - "hermes-parser": "^0.25.1", - "zod": "^3.25.0 || ^4.0.0", - "zod-validation-error": "^3.5.0 || ^4.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" - } - }, - "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.26", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz", - "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "eslint": ">=8.40" - } - }, - "node_modules/eslint-plugin-react/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/eslint-plugin-react/node_modules/brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-react/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/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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/eslint/node_modules/brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/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/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "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/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/extract-zip/node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/extsprintf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", - "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "optional": true - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/fdir": { - "version": "6.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/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "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.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", - "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/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", - "dev": true, - "license": "ISC" - }, - "node_modules/follow-redirects": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", - "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fraction.js": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", - "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/rawify" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/generator-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", - "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "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==", - "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==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "license": "MIT", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "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.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "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==", - "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/global-agent/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/globals": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", - "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "devOptional": true, - "license": "MIT", - "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==", - "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==", - "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==", - "license": "ISC" - }, - "node_modules/has-bigints": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "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==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", - "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", - "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^9.0.0", - "property-information": "^7.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", - "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-sanitize": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", - "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "unist-util-position": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", - "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", - "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", - "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hermes-estree": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", - "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", - "dev": true, - "license": "MIT" - }, - "node_modules/hermes-parser": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", - "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "hermes-estree": "0.25.1" - } - }, - "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/hosted-git-info/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/hosted-git-info/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/html-parse-stringify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", - "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", - "license": "MIT", - "dependencies": { - "void-elements": "3.1.0" - } - }, - "node_modules/html-url-attributes": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", - "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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==", - "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==", - "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/i18next": { - "version": "26.0.10", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.0.10.tgz", - "integrity": "sha512-k3yGPAlWR2RdMYoVXJoDZDT87qeHIWKH7gVksdZMpRty7QX/D9QZeYGvN08KGbKHke9wn01eYT+EEsrqX/YTlw==", - "funding": [ - { - "type": "individual", - "url": "https://www.locize.com/i18next" - }, - { - "type": "individual", - "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" - }, - { - "type": "individual", - "url": "https://www.locize.com" - } - ], - "license": "MIT", - "peerDependencies": { - "typescript": "^5 || ^6" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/iconv-corefoundation": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", - "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "cli-truncate": "^2.1.0", - "node-addon-api": "^1.6.3" - }, - "engines": { - "node": "^8.11.2 || >=10" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "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": "BSD-3-Clause", - "optional": true - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "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/inline-style-parser": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", - "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", - "license": "MIT" - }, - "node_modules/internal-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-async-function": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "async-function": "^1.0.0", - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", - "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/is-generator-function": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", - "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.4", - "generator-function": "^2.0.0", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "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/iterator.prototype": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", - "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "get-proto": "^1.0.0", - "has-symbols": "^1.1.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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/jose": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", - "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-typed": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", - "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", - "license": "BSD-2-Clause" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "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==", - "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": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - }, - "engines": { - "node": ">=4.0" - } - }, - "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==", - "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==", - "license": "MIT" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lightningcss": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.32.0", - "lightningcss-darwin-arm64": "1.32.0", - "lightningcss-darwin-x64": "1.32.0", - "lightningcss-freebsd-x64": "1.32.0", - "lightningcss-linux-arm-gnueabihf": "1.32.0", - "lightningcss-linux-arm64-gnu": "1.32.0", - "lightningcss-linux-arm64-musl": "1.32.0", - "lightningcss-linux-x64-gnu": "1.32.0", - "lightningcss-linux-x64-musl": "1.32.0", - "lightningcss-win32-arm64-msvc": "1.32.0", - "lightningcss-win32-x64-msvc": "1.32.0" - } - }, - "node_modules/lightningcss-android-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", - "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", - "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", - "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", - "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", - "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", - "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", - "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", - "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", - "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", - "license": "MIT" - }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/markdown-table": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "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==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", - "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", - "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", - "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", - "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "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==", - "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==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "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==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-abi": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-4.31.0.tgz", - "integrity": "sha512-Erq5w/t3syw3s4sDsUaX4QttIdBPsGKTT1DTRsCkTonGggczhlDKm/wDX3o+HPJpQ41EjXCbcmXf0tgr5YZJXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.6.3" - }, - "engines": { - "node": ">=22.12.0" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/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-api-version/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-exports-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", - "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array.prototype.flatmap": "^1.3.3", - "es-errors": "^1.3.0", - "object.entries": "^1.1.9", - "semver": "^6.3.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/node-gyp": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.3.0.tgz", - "integrity": "sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg==", - "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/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/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "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-releases": { - "version": "2.0.38", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", - "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", - "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==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/oauth4webapi": { - "version": "3.8.6", - "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.6.tgz", - "integrity": "sha512-iwemM91xz8nryHti2yTmg5fhyEMVOkOXwHNqbvcATjyajb5oQxCQzrNOA6uElRHuMhQQTKUyFKV9y/CNyg25BQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", - "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", - "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/openid-client": { - "version": "6.8.4", - "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.8.4.tgz", - "integrity": "sha512-QSw0BA08piujetEwfZsHoTrDpMEha7GDZDicQqVwX4u0ChCjefvjDB++TZ8BTg76UpwhzIQgdvvfgfl3HpCSAw==", - "license": "MIT", - "dependencies": { - "jose": "^6.2.2", - "oauth4webapi": "^3.8.5" - }, - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/own-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.6", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "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/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-entities": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", - "license": "MIT" - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/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/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "license": "MIT" - }, - "node_modules/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.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "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/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.5.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", - "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "license": "MIT" - }, - "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/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", - "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", - "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "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/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "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/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "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/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/proxy-from-env": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", - "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/pump": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react": { - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", - "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", - "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "scheduler": "^0.27.0" - }, - "peerDependencies": { - "react": "^19.2.6" - } - }, - "node_modules/react-i18next": { - "version": "17.0.7", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.7.tgz", - "integrity": "sha512-rwtPXsb/zwzDafN+gytcjF5YnqGQQIRmCQ6DctBC1VSipRB8GD/MWEVrFP42vjMyuYydxWxM8CZRt+yiNuuoHg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.29.2", - "html-parse-stringify": "^3.0.1", - "use-sync-external-store": "^1.6.0" - }, - "peerDependencies": { - "i18next": ">= 26.0.10", - "react": ">= 16.8.0", - "typescript": "^5 || ^6" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/react-markdown": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", - "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "html-url-attributes": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "unified": "^11.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=18", - "react": ">=18" - } - }, - "node_modules/react-refresh": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", - "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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/reflect.getprototypeof": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-sanitize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz", - "integrity": "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-sanitize": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "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==", - "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": { - "version": "2.0.0-next.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", - "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "node-exports-info": "^1.6.0", - "object-keys": "^1.1.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/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==", - "license": "MIT" - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "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==", - "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/rollup": { - "version": "4.60.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.3.tgz", - "integrity": "sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.60.3", - "@rollup/rollup-android-arm64": "4.60.3", - "@rollup/rollup-darwin-arm64": "4.60.3", - "@rollup/rollup-darwin-x64": "4.60.3", - "@rollup/rollup-freebsd-arm64": "4.60.3", - "@rollup/rollup-freebsd-x64": "4.60.3", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.3", - "@rollup/rollup-linux-arm-musleabihf": "4.60.3", - "@rollup/rollup-linux-arm64-gnu": "4.60.3", - "@rollup/rollup-linux-arm64-musl": "4.60.3", - "@rollup/rollup-linux-loong64-gnu": "4.60.3", - "@rollup/rollup-linux-loong64-musl": "4.60.3", - "@rollup/rollup-linux-ppc64-gnu": "4.60.3", - "@rollup/rollup-linux-ppc64-musl": "4.60.3", - "@rollup/rollup-linux-riscv64-gnu": "4.60.3", - "@rollup/rollup-linux-riscv64-musl": "4.60.3", - "@rollup/rollup-linux-s390x-gnu": "4.60.3", - "@rollup/rollup-linux-x64-gnu": "4.60.3", - "@rollup/rollup-linux-x64-musl": "4.60.3", - "@rollup/rollup-openbsd-x64": "4.60.3", - "@rollup/rollup-openharmony-arm64": "4.60.3", - "@rollup/rollup-win32-arm64-msvc": "4.60.3", - "@rollup/rollup-win32-ia32-msvc": "4.60.3", - "@rollup/rollup-win32-x64-gnu": "4.60.3", - "@rollup/rollup-win32-x64-msvc": "4.60.3", - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup/node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/safe-array-concat": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", - "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.9", - "call-bound": "^1.0.4", - "get-intrinsic": "^1.3.0", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-push-apply": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/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.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", - "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=11.0.0" - } - }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/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==", - "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==", - "license": "MIT", - "optional": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "license": "(MIT OR CC0-1.0)", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", - "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "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/simple-update-notifier/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "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-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "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/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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==", - "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/stop-iteration-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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/string.prototype.matchall": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", - "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "regexp.prototype.flags": "^1.5.3", - "set-function-name": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.repeat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", - "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-data-property": "^1.1.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stubborn-fs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-2.0.0.tgz", - "integrity": "sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==", - "license": "MIT", - "dependencies": { - "stubborn-utils": "^1.0.1" - } - }, - "node_modules/stubborn-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stubborn-utils/-/stubborn-utils-1.0.2.tgz", - "integrity": "sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==", - "license": "MIT" - }, - "node_modules/style-to-js": { - "version": "1.1.21", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", - "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", - "license": "MIT", - "dependencies": { - "style-to-object": "1.0.14" - } - }, - "node_modules/style-to-object": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", - "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.2.7" - } - }, - "node_modules/sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "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/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/synckit": { - "version": "0.11.12", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", - "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.2.9" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, - "node_modules/tagged-tag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", - "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tailwindcss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz", - "integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/tapable": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", - "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/tar": { - "version": "7.5.15", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.15.tgz", - "integrity": "sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==", - "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/temp-file/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/temp-file/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/temp-file/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/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/tiny-typed-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", - "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==", - "license": "MIT" - }, - "node_modules/tinyglobby": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", - "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", - "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.5", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", - "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", - "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/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/ts-api-utils": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", - "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", - "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", - "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.15", - "reflect.getprototypeof": "^1.0.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "devOptional": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "8.59.2", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.2.tgz", - "integrity": "sha512-pJw051uomb3ZeCzGTpRb8RbEqB5Y4WWet8gl/GcTlU35BSx0PVdZ86/bqkQCyKKuraVQEK7r6kBHQXF+fBhkoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.59.2", - "@typescript-eslint/parser": "8.59.2", - "@typescript-eslint/typescript-estree": "8.59.2", - "@typescript-eslint/utils": "8.59.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/uint8array-extras": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", - "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unbox-primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", - "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", - "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/use-sync-external-store": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", - "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "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/verror": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", - "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", - "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.3.tgz", - "integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", - "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", - "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", - "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", - "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", - "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", - "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", - "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", - "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", - "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", - "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", - "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", - "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", - "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", - "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", - "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", - "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", - "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", - "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", - "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", - "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", - "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", - "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", - "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", - "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", - "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", - "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", - "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.7", - "@esbuild/android-arm": "0.27.7", - "@esbuild/android-arm64": "0.27.7", - "@esbuild/android-x64": "0.27.7", - "@esbuild/darwin-arm64": "0.27.7", - "@esbuild/darwin-x64": "0.27.7", - "@esbuild/freebsd-arm64": "0.27.7", - "@esbuild/freebsd-x64": "0.27.7", - "@esbuild/linux-arm": "0.27.7", - "@esbuild/linux-arm64": "0.27.7", - "@esbuild/linux-ia32": "0.27.7", - "@esbuild/linux-loong64": "0.27.7", - "@esbuild/linux-mips64el": "0.27.7", - "@esbuild/linux-ppc64": "0.27.7", - "@esbuild/linux-riscv64": "0.27.7", - "@esbuild/linux-s390x": "0.27.7", - "@esbuild/linux-x64": "0.27.7", - "@esbuild/netbsd-arm64": "0.27.7", - "@esbuild/netbsd-x64": "0.27.7", - "@esbuild/openbsd-arm64": "0.27.7", - "@esbuild/openbsd-x64": "0.27.7", - "@esbuild/openharmony-arm64": "0.27.7", - "@esbuild/sunos-x64": "0.27.7", - "@esbuild/win32-arm64": "0.27.7", - "@esbuild/win32-ia32": "0.27.7", - "@esbuild/win32-x64": "0.27.7" - } - }, - "node_modules/void-elements": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", - "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/when-exit": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.5.tgz", - "integrity": "sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==", - "license": "MIT" - }, - "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/which-boxed-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.20", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", - "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.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==", - "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": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "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/yauzl": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.3.0.tgz", - "integrity": "sha512-PtGEvEP30p7sbIBJKUBjUnqgTVOyMURc4dLo9iNyAJnNIEz9pm88cCXF21w94Kg3k6RXkeZh5DHOGS0qEONvNQ==", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "pend": "~1.2.0" - }, - "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" - } - }, - "node_modules/zod": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", - "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-validation-error": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", - "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "zod": "^3.25.0 || ^4.0.0" - } - }, - "node_modules/zustand": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.13.tgz", - "integrity": "sha512-efI2tVaVQPqtOh114loML/Z80Y4NP3yc+Ff0fYiZJPauNeWZeIp/bRFD7I9bfmCOYBh/PHxlglQ9+wvlwnPikQ==", - "license": "MIT", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@types/react": ">=18.0.0", - "immer": ">=9.0.6", - "react": ">=18.0.0", - "use-sync-external-store": ">=1.2.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - }, - "use-sync-external-store": { - "optional": true - } - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/package.json b/package.json index 4c24bf1..27e3e9b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,11 @@ { "name": "dying-star-launcher", - "version": "0.1.0", + "version": "0.2.0", + "packageManager": "pnpm@10.33.3", "description": "Launcher for DyingStar Game", + "engines": { + "node": ">=20" + }, "main": "./out/main/index.js", "author": { "name": "dyingstar-game.com", @@ -15,7 +19,6 @@ "output": "release" }, "files": [ - "dist/**/*", "out/**/*", "!**/*.map" ], @@ -26,6 +29,17 @@ "npmRebuild": true, "nodeGypRebuild": false, "buildDependenciesFromSource": false, + "extraResources": [ + { + "from": "resources/", + "to": ".", + "filter": [ + "icon.ico", + "icon.icns", + "icon.png" + ] + } + ], "win": { "target": [ { @@ -35,7 +49,12 @@ ] } ], - "icon": "build/icon.ico" + "icon": "resources/icon.ico" + }, + "mac": { + "icon": "resources/icon.icns", + "entitlements": "resources/entitlements.mac.plist", + "entitlementsInherit": "resources/entitlements.mac.plist" }, "nsis": { "oneClick": false, @@ -64,12 +83,14 @@ ] } ], + "icon": "resources/icon.png", "category": "Game" } }, "scripts": { "format": "prettier --write .", "lint": "eslint --cache .", + "lint:fix": "eslint --cache . --fix", "typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false", "typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false", "typecheck": "npm run typecheck:node && npm run typecheck:web", @@ -79,28 +100,31 @@ "postinstall": "electron-builder install-app-deps", "build:unpack": "npm run build && electron-builder --dir", "build:win": "npm run build && electron-builder --win", - "build:mac": "electron-vite build && electron-builder --mac", - "build:linux": "electron-vite build && electron-builder --linux" + "build:mac": "npm run build && electron-builder --mac", + "build:linux": "npm run build && electron-builder --linux" }, "dependencies": { "@electron-toolkit/preload": "^3.0.2", "@electron-toolkit/utils": "^4.0.0", "axios": "^1.16.0", - "debug": "^4.4.3", + "buffer-crc32": "^0.2.13", "electron-log": "^5.4.3", - "electron-store": "^11.0.2", - "electron-updater": "^6.3.9", + "end-of-stream": "^1.4.5", "extract-zip": "^2.0.1", - "get-stream": "^9.0.1", + "fd-slicer": "^1.1.0", + "get-stream": "^5.2.0", "i18next": "^26.0.8", "ms": "^2.1.3", - "openid-client": "^6.8.4", + "once": "^1.4.0", + "pend": "^1.2.0", + "pump": "^3.0.4", "react-i18next": "^17.0.6", "react-markdown": "^10.1.0", "rehype-raw": "^7.0.0", "rehype-sanitize": "^6.0.0", "remark-gfm": "^4.0.1", - "yauzl": "^3.3.0", + "wrappy": "^1.0.2", + "yauzl": "^2.10.0", "zustand": "^5.0.13" }, "devDependencies": { @@ -113,7 +137,6 @@ "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.1", - "autoprefixer": "^10.5.0", "electron-builder": "^26.0.12", "electron-vite": "^5.0.0", "eslint": "^9.39.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 78295bc..f5c251e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,43 +10,49 @@ importers: dependencies: '@electron-toolkit/preload': specifier: ^3.0.2 - version: 3.0.2(electron@42.0.1) + version: 3.0.2(electron@42.1.0) '@electron-toolkit/utils': specifier: ^4.0.0 - version: 4.0.0(electron@42.0.1) + version: 4.0.0(electron@42.1.0) axios: specifier: ^1.16.0 - version: 1.16.0(debug@4.4.3) - debug: - specifier: ^4.4.3 - version: 4.4.3 + version: 1.16.1 + buffer-crc32: + specifier: ^0.2.13 + version: 0.2.13 electron-log: specifier: ^5.4.3 - version: 5.4.3 - electron-store: - specifier: ^11.0.2 - version: 11.0.2 - electron-updater: - specifier: ^6.3.9 - version: 6.8.3 + version: 5.4.4 + end-of-stream: + specifier: ^1.4.5 + version: 1.4.5 extract-zip: specifier: ^2.0.1 version: 2.0.1 + fd-slicer: + specifier: ^1.1.0 + version: 1.1.0 get-stream: - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^5.2.0 + version: 5.2.0 i18next: specifier: ^26.0.8 - version: 26.0.10(typescript@5.9.3) + version: 26.2.0(typescript@5.9.3) ms: specifier: ^2.1.3 version: 2.1.3 - openid-client: - specifier: ^6.8.4 - version: 6.8.4 + once: + specifier: ^1.4.0 + version: 1.4.0 + pend: + specifier: ^1.2.0 + version: 1.2.0 + pump: + specifier: ^3.0.4 + version: 3.0.4 react-i18next: specifier: ^17.0.6 - version: 17.0.7(i18next@26.0.10(typescript@5.9.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3) + version: 17.0.8(i18next@26.2.0(typescript@5.9.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3) react-markdown: specifier: ^10.1.0 version: 10.1.0(@types/react@19.2.14)(react@19.2.6) @@ -59,9 +65,12 @@ importers: remark-gfm: specifier: ^4.0.1 version: 4.0.1 + wrappy: + specifier: ^1.0.2 + version: 1.0.2 yauzl: - specifier: ^3.3.0 - version: 3.3.0 + specifier: ^2.10.0 + version: 2.10.0 zustand: specifier: ^5.0.13 version: 5.0.13(@types/react@19.2.14)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)) @@ -74,16 +83,16 @@ importers: version: 3.1.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) '@electron-toolkit/tsconfig': specifier: ^2.0.0 - version: 2.0.0(@types/node@22.19.18) + version: 2.0.0(@types/node@22.19.19) '@tailwindcss/vite': specifier: ^4.2.4 - version: 4.3.0(vite@7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0)) + version: 4.3.0(vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0)) '@types/extract-zip': specifier: ^2.0.3 version: 2.0.3 '@types/node': specifier: ^22.19.1 - version: 22.19.18 + version: 22.19.19 '@types/react': specifier: ^19.2.7 version: 19.2.14 @@ -92,16 +101,13 @@ importers: version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: ^5.1.1 - version: 5.2.0(vite@7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0)) - autoprefixer: - specifier: ^10.5.0 - version: 10.5.0(postcss@8.5.14) + version: 5.2.0(vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0)) electron-builder: specifier: ^26.0.12 version: 26.8.1(electron-builder-squirrel-windows@26.8.1) electron-vite: specifier: ^5.0.0 - version: 5.0.0(vite@7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0)) + version: 5.0.0(vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0)) eslint: specifier: ^9.39.1 version: 9.39.4(jiti@2.7.0) @@ -131,7 +137,7 @@ importers: version: 5.9.3 vite: specifier: ^7.2.6 - version: 7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0) + version: 7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0) packages: @@ -710,147 +716,144 @@ packages: '@rolldown/pluginutils@1.0.0-rc.3': resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} - '@rollup/rollup-android-arm-eabi@4.60.3': - resolution: {integrity: sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==} + '@rollup/rollup-android-arm-eabi@4.60.4': + resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.3': - resolution: {integrity: sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==} + '@rollup/rollup-android-arm64@4.60.4': + resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.3': - resolution: {integrity: sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==} + '@rollup/rollup-darwin-arm64@4.60.4': + resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.3': - resolution: {integrity: sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==} + '@rollup/rollup-darwin-x64@4.60.4': + resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.3': - resolution: {integrity: sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==} + '@rollup/rollup-freebsd-arm64@4.60.4': + resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.3': - resolution: {integrity: sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==} + '@rollup/rollup-freebsd-x64@4.60.4': + resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.3': - resolution: {integrity: sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==} + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': + resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.60.3': - resolution: {integrity: sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==} + '@rollup/rollup-linux-arm-musleabihf@4.60.4': + resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.60.3': - resolution: {integrity: sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==} + '@rollup/rollup-linux-arm64-gnu@4.60.4': + resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.60.3': - resolution: {integrity: sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==} + '@rollup/rollup-linux-arm64-musl@4.60.4': + resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.60.3': - resolution: {integrity: sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==} + '@rollup/rollup-linux-loong64-gnu@4.60.4': + resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.60.3': - resolution: {integrity: sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==} + '@rollup/rollup-linux-loong64-musl@4.60.4': + resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.60.3': - resolution: {integrity: sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==} + '@rollup/rollup-linux-ppc64-gnu@4.60.4': + resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.60.3': - resolution: {integrity: sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==} + '@rollup/rollup-linux-ppc64-musl@4.60.4': + resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.60.3': - resolution: {integrity: sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==} + '@rollup/rollup-linux-riscv64-gnu@4.60.4': + resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.60.3': - resolution: {integrity: sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==} + '@rollup/rollup-linux-riscv64-musl@4.60.4': + resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.60.3': - resolution: {integrity: sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==} + '@rollup/rollup-linux-s390x-gnu@4.60.4': + resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.60.3': - resolution: {integrity: sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==} + '@rollup/rollup-linux-x64-gnu@4.60.4': + resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.60.3': - resolution: {integrity: sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==} + '@rollup/rollup-linux-x64-musl@4.60.4': + resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.60.3': - resolution: {integrity: sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==} + '@rollup/rollup-openbsd-x64@4.60.4': + resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.60.3': - resolution: {integrity: sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==} + '@rollup/rollup-openharmony-arm64@4.60.4': + resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.60.3': - resolution: {integrity: sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==} + '@rollup/rollup-win32-arm64-msvc@4.60.4': + resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.3': - resolution: {integrity: sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==} + '@rollup/rollup-win32-ia32-msvc@4.60.4': + resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.3': - resolution: {integrity: sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==} + '@rollup/rollup-win32-x64-gnu@4.60.4': + resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.60.3': - resolution: {integrity: sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==} + '@rollup/rollup-win32-x64-msvc@4.60.4': + resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} cpu: [x64] os: [win32] - '@sec-ant/readable-stream@0.4.1': - resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - '@sindresorhus/is@4.6.0': resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} @@ -1005,11 +1008,11 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@22.19.18': - resolution: {integrity: sha512-9v00a+dn2yWVsYDEunWC4g/TcRKVq3r8N5FuZp7u0SGrPvdN9c2yXI9bBuf5Fl0hNCb+QTIePTn5pJs2pwBOQQ==} + '@types/node@22.19.19': + resolution: {integrity: sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==} - '@types/node@24.12.3': - resolution: {integrity: sha512-8oljBDGun9cIsZRJR6fkihn0TSXJI0UDOOhncYaERq6M0JMDoPLxyscwruJcb4GKS6dvK/d8xebYBg27h/duaQ==} + '@types/node@24.12.4': + resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} '@types/plist@3.0.5': resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} @@ -1037,63 +1040,63 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.59.2': - resolution: {integrity: sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==} + '@typescript-eslint/eslint-plugin@8.59.3': + resolution: {integrity: sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.59.2 + '@typescript-eslint/parser': ^8.59.3 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.59.2': - resolution: {integrity: sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==} + '@typescript-eslint/parser@8.59.3': + resolution: {integrity: sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.59.2': - resolution: {integrity: sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==} + '@typescript-eslint/project-service@8.59.3': + resolution: {integrity: sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.59.2': - resolution: {integrity: sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==} + '@typescript-eslint/scope-manager@8.59.3': + resolution: {integrity: sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.59.2': - resolution: {integrity: sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==} + '@typescript-eslint/tsconfig-utils@8.59.3': + resolution: {integrity: sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.59.2': - resolution: {integrity: sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==} + '@typescript-eslint/type-utils@8.59.3': + resolution: {integrity: sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.59.2': - resolution: {integrity: sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==} + '@typescript-eslint/types@8.59.3': + resolution: {integrity: sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.59.2': - resolution: {integrity: sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==} + '@typescript-eslint/typescript-estree@8.59.3': + resolution: {integrity: sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.59.2': - resolution: {integrity: sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==} + '@typescript-eslint/utils@8.59.3': + resolution: {integrity: sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.59.2': - resolution: {integrity: sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==} + '@typescript-eslint/visitor-keys@8.59.3': + resolution: {integrity: sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.1': @@ -1127,18 +1130,14 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} - ajv-formats@3.0.1: - resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: @@ -1147,9 +1146,6 @@ packages: ajv@6.15.0: resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} - ajv@8.20.0: - resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1225,22 +1221,12 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} - atomically@2.1.1: - resolution: {integrity: sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ==} - - autoprefixer@10.5.0: - resolution: {integrity: sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.16.0: - resolution: {integrity: sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==} + axios@1.16.1: + resolution: {integrity: sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==} bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -1400,10 +1386,6 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - conf@15.1.0: - resolution: {integrity: sha512-Uy5YN9KEu0WWDaZAVJ5FAmZoaJt9rdK6kH+utItPyGsCqCgaTKkrmZx3zoE0/3q6S3bcp3Ihkk+ZqPxWxFK5og==} - engines: {node: '>=20'} - convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -1435,10 +1417,6 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} - debounce-fn@6.0.0: - resolution: {integrity: sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==} - engines: {node: '>=18'} - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1504,10 +1482,6 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} - dot-prop@10.1.0: - resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==} - engines: {node: '>=20'} - dotenv-expand@11.0.7: resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} engines: {node: '>=12'} @@ -1533,22 +1507,15 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - electron-log@5.4.3: - resolution: {integrity: sha512-sOUsM3LjZdugatazSQ/XTyNcw8dfvH1SYhXWiJyfYodAAKOZdHs0txPiLDXFzOZbhXgAgshQkshH2ccq0feyLQ==} + electron-log@5.4.4: + resolution: {integrity: sha512-istWgaXjBfURBSS8LWVW9C3jsc6+ac+tY1lXrQEOTp0lVj+a4OlO1Tmqb36GgnEUDv92DGC9VI1HNXwJinWpgA==} engines: {node: '>= 14'} electron-publish@26.8.1: resolution: {integrity: sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==} - electron-store@11.0.2: - resolution: {integrity: sha512-4VkNRdN+BImL2KcCi41WvAYbh6zLX5AUTi4so68yPqiItjbgTjqpEnGAqasgnG+lB6GuAyUltKwVopp6Uv+gwQ==} - engines: {node: '>=20'} - - electron-to-chromium@1.5.353: - resolution: {integrity: sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w==} - - electron-updater@6.8.3: - resolution: {integrity: sha512-Z6sgw3jgbikWKXei1ENdqFOxBP0WlXg3TtKfz0rgw2vIZFJUyI4pD7ZN7jrkm7EoMK+tcm/qTnPUdqfZukBlBQ==} + electron-to-chromium@1.5.356: + resolution: {integrity: sha512-9NgFd7m5t5MCJ5rUSjJITUXAH9mEGlrlofnMf4YEr+pz6JlP7cWmTAH+JFmbPnaSW8koVTkuW7pacORWAnA5Yw==} electron-vite@5.0.0: resolution: {integrity: sha512-OHp/vjdlubNlhNkPkL/+3JD34ii5ov7M0GpuXEVdQeqdQ3ulvVR7Dg/rNBLfS5XPIFwgoBLDf9sjjrL+CuDyRQ==} @@ -1565,8 +1532,8 @@ packages: resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} engines: {node: '>=8.0.0'} - electron@42.0.1: - resolution: {integrity: sha512-d8HnycE970DGESe91Nj30eonFBUcAI9EZ1TwUGJVzSAnJZdh0BkFEinAXjdklvDYst+bVDc8HsksCuqVLrnqdg==} + electron@42.1.0: + resolution: {integrity: sha512-0szNwC/0dWtkvNce5j3ThiuL0TxBNrZN/BZhdOiGwbLreiD/+u3MGpkct4hA5Ycagb8MXjpEr5/oosi+FwuKRQ==} engines: {node: '>= 22.12.0'} hasBin: true @@ -1576,8 +1543,8 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.21.2: - resolution: {integrity: sha512-xe9vQb5kReirPUxgQrXA3ihgbCqssmTiM7cOZ+Gzu+VeGWgpV98lLZvp0dl4yriyAePcewxGUs9UpKD8PET9KQ==} + enhanced-resolve@5.21.3: + resolution: {integrity: sha512-QyL119InA+XXEkNLNTPCXPugSvOfhwv0JOlGNzvxs0hZaiHLNvXSpudUWsOlsXGWJh8G6ckCScEkVHfX3kw/2Q==} engines: {node: '>=10.13.0'} entities@6.0.1: @@ -1765,9 +1732,6 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-uri@3.1.2: - resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} - fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} @@ -1815,9 +1779,6 @@ packages: resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} - fraction.js@5.3.4: - resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} - fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} @@ -1880,10 +1841,6 @@ packages: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} - get-stream@9.0.1: - resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} - engines: {node: '>=18'} - get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} @@ -2004,12 +1961,16 @@ packages: resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} engines: {node: '>=10.19.0'} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} - i18next@26.0.10: - resolution: {integrity: sha512-k3yGPAlWR2RdMYoVXJoDZDT87qeHIWKH7gVksdZMpRty7QX/D9QZeYGvN08KGbKHke9wn01eYT+EEsrqX/YTlw==} + i18next@26.2.0: + resolution: {integrity: sha512-zwBHldHdTmwN7r6UNc7lC6GWNN+YYg3DrRSeHR5PRRBf5QnJZcYHrQc0uaU26qZeYxR7iFZD+Y315dPnKP47wA==} peerDependencies: typescript: ^5 || ^6 peerDependenciesMeta: @@ -2150,10 +2111,6 @@ packages: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} - is-stream@4.0.1: - resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} - engines: {node: '>=18'} - is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} @@ -2213,9 +2170,6 @@ packages: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true - jose@6.2.3: - resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==} - js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2234,12 +2188,6 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - - json-schema-typed@8.0.2: - resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -2349,13 +2297,6 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash.escaperegexp@4.1.2: - resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} - - lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -2536,10 +2477,6 @@ packages: engines: {node: '>=4.0.0'} hasBin: true - mimic-function@5.0.1: - resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} - engines: {node: '>=18'} - mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -2608,8 +2545,8 @@ packages: engines: {node: ^20.17.0 || >=22.9.0} hasBin: true - node-releases@2.0.38: - resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} + node-releases@2.0.44: + resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==} nopt@9.0.0: resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==} @@ -2620,9 +2557,6 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} - oauth4webapi@3.8.6: - resolution: {integrity: sha512-iwemM91xz8nryHti2yTmg5fhyEMVOkOXwHNqbvcATjyajb5oQxCQzrNOA6uElRHuMhQQTKUyFKV9y/CNyg25BQ==} - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -2654,9 +2588,6 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - openid-client@6.8.4: - resolution: {integrity: sha512-QSw0BA08piujetEwfZsHoTrDpMEha7GDZDicQqVwX4u0ChCjefvjDB++TZ8BTg76UpwhzIQgdvvfgfl3HpCSAw==} - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -2728,9 +2659,6 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.14: resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} engines: {node: ^10 || ^12 || >=14} @@ -2794,10 +2722,10 @@ packages: peerDependencies: react: ^19.2.6 - react-i18next@17.0.7: - resolution: {integrity: sha512-rwtPXsb/zwzDafN+gytcjF5YnqGQQIRmCQ6DctBC1VSipRB8GD/MWEVrFP42vjMyuYydxWxM8CZRt+yiNuuoHg==} + react-i18next@17.0.8: + resolution: {integrity: sha512-0ooKbGLU8JXhe1zwpQUWIeXSgLPOfwJmgheWRIUpcoA0CpyabpGhayjdG+/eA5esC1AQ8h2jWpXjJfzQzeDOCw==} peerDependencies: - i18next: '>= 26.0.10' + i18next: '>= 26.2.0' react: '>= 16.8.0' react-dom: '*' react-native: '*' @@ -2861,10 +2789,6 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - resedit@1.7.2: resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==} engines: {node: '>=12', npm: '>=6'} @@ -2876,8 +2800,8 @@ packages: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} - resolve@2.0.0-next.6: - resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} + resolve@2.0.0-next.7: + resolution: {integrity: sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==} engines: {node: '>= 0.4'} hasBin: true @@ -2897,8 +2821,8 @@ packages: resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} engines: {node: '>=8.0'} - rollup@4.60.3: - resolution: {integrity: sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==} + rollup@4.60.4: + resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3062,12 +2986,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - stubborn-fs@2.0.0: - resolution: {integrity: sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==} - - stubborn-utils@1.0.2: - resolution: {integrity: sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==} - style-to-js@1.1.21: resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} @@ -3090,10 +3008,6 @@ packages: resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} engines: {node: ^14.18.0 || >=16.0.0} - tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} - tailwindcss@4.3.0: resolution: {integrity: sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==} @@ -3115,9 +3029,6 @@ packages: tiny-async-pool@1.3.0: resolution: {integrity: sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==} - tiny-typed-emitter@2.1.0: - resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==} - tinyglobby@0.2.16: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} @@ -3152,10 +3063,6 @@ packages: resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} engines: {node: '>=10'} - type-fest@5.6.0: - resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==} - engines: {node: '>=20'} - typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -3172,8 +3079,8 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.59.2: - resolution: {integrity: sha512-pJw051uomb3ZeCzGTpRb8RbEqB5Y4WWet8gl/GcTlU35BSx0PVdZ86/bqkQCyKKuraVQEK7r6kBHQXF+fBhkoQ==} + typescript-eslint@8.59.3: + resolution: {integrity: sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3184,10 +3091,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - uint8array-extras@1.5.0: - resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} - engines: {node: '>=18'} - unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -3309,9 +3212,6 @@ packages: web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} - when-exit@2.1.5: - resolution: {integrity: sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==} - which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -3383,10 +3283,6 @@ packages: yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - yauzl@3.3.0: - resolution: {integrity: sha512-PtGEvEP30p7sbIBJKUBjUnqgTVOyMURc4dLo9iNyAJnNIEz9pm88cCXF21w94Kg3k6RXkeZh5DHOGS0qEONvNQ==} - engines: {node: '>=12'} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -3563,23 +3459,23 @@ snapshots: '@eslint/js': 9.39.4 eslint: 9.39.4(jiti@2.7.0) globals: 16.5.0 - typescript-eslint: 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + typescript-eslint: 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@electron-toolkit/preload@3.0.2(electron@42.0.1)': + '@electron-toolkit/preload@3.0.2(electron@42.1.0)': dependencies: - electron: 42.0.1 + electron: 42.1.0 - '@electron-toolkit/tsconfig@2.0.0(@types/node@22.19.18)': + '@electron-toolkit/tsconfig@2.0.0(@types/node@22.19.19)': dependencies: - '@types/node': 22.19.18 + '@types/node': 22.19.19 - '@electron-toolkit/utils@4.0.0(electron@42.0.1)': + '@electron-toolkit/utils@4.0.0(electron@42.1.0)': dependencies: - electron: 42.0.1 + electron: 42.1.0 '@electron/asar@3.4.1': dependencies: @@ -3931,83 +3827,81 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.3': {} - '@rollup/rollup-android-arm-eabi@4.60.3': + '@rollup/rollup-android-arm-eabi@4.60.4': optional: true - '@rollup/rollup-android-arm64@4.60.3': + '@rollup/rollup-android-arm64@4.60.4': optional: true - '@rollup/rollup-darwin-arm64@4.60.3': + '@rollup/rollup-darwin-arm64@4.60.4': optional: true - '@rollup/rollup-darwin-x64@4.60.3': + '@rollup/rollup-darwin-x64@4.60.4': optional: true - '@rollup/rollup-freebsd-arm64@4.60.3': + '@rollup/rollup-freebsd-arm64@4.60.4': optional: true - '@rollup/rollup-freebsd-x64@4.60.3': + '@rollup/rollup-freebsd-x64@4.60.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.3': + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.3': + '@rollup/rollup-linux-arm-musleabihf@4.60.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.3': + '@rollup/rollup-linux-arm64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.60.3': + '@rollup/rollup-linux-arm64-musl@4.60.4': optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.3': + '@rollup/rollup-linux-loong64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-loong64-musl@4.60.3': + '@rollup/rollup-linux-loong64-musl@4.60.4': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.3': + '@rollup/rollup-linux-ppc64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.3': + '@rollup/rollup-linux-ppc64-musl@4.60.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.3': + '@rollup/rollup-linux-riscv64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.3': + '@rollup/rollup-linux-riscv64-musl@4.60.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.3': + '@rollup/rollup-linux-s390x-gnu@4.60.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.60.3': + '@rollup/rollup-linux-x64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-x64-musl@4.60.3': + '@rollup/rollup-linux-x64-musl@4.60.4': optional: true - '@rollup/rollup-openbsd-x64@4.60.3': + '@rollup/rollup-openbsd-x64@4.60.4': optional: true - '@rollup/rollup-openharmony-arm64@4.60.3': + '@rollup/rollup-openharmony-arm64@4.60.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.3': + '@rollup/rollup-win32-arm64-msvc@4.60.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.3': + '@rollup/rollup-win32-ia32-msvc@4.60.4': optional: true - '@rollup/rollup-win32-x64-gnu@4.60.3': + '@rollup/rollup-win32-x64-gnu@4.60.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.60.3': + '@rollup/rollup-win32-x64-msvc@4.60.4': optional: true - '@sec-ant/readable-stream@0.4.1': {} - '@sindresorhus/is@4.6.0': {} '@szmarczak/http-timer@4.0.6': @@ -4017,7 +3911,7 @@ snapshots: '@tailwindcss/node@4.3.0': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.21.2 + enhanced-resolve: 5.21.3 jiti: 2.7.0 lightningcss: 1.32.0 magic-string: 0.30.21 @@ -4075,12 +3969,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.3.0 '@tailwindcss/oxide-win32-x64-msvc': 4.3.0 - '@tailwindcss/vite@4.3.0(vite@7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0))': + '@tailwindcss/vite@4.3.0(vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0))': dependencies: '@tailwindcss/node': 4.3.0 '@tailwindcss/oxide': 4.3.0 tailwindcss: 4.3.0 - vite: 7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0) + vite: 7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0) '@types/babel__core@7.20.5': dependencies: @@ -4107,7 +4001,7 @@ snapshots: dependencies: '@types/http-cache-semantics': 4.2.0 '@types/keyv': 3.1.4 - '@types/node': 22.19.18 + '@types/node': 22.19.19 '@types/responselike': 1.0.3 '@types/debug@4.1.13': @@ -4130,7 +4024,7 @@ snapshots: '@types/fs-extra@9.0.13': dependencies: - '@types/node': 22.19.18 + '@types/node': 22.19.19 '@types/hast@3.0.4': dependencies: @@ -4142,7 +4036,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 22.19.18 + '@types/node': 22.19.19 '@types/mdast@4.0.4': dependencies: @@ -4150,17 +4044,17 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@22.19.18': + '@types/node@22.19.19': dependencies: undici-types: 6.21.0 - '@types/node@24.12.3': + '@types/node@24.12.4': dependencies: undici-types: 7.16.0 '@types/plist@3.0.5': dependencies: - '@types/node': 22.19.18 + '@types/node': 22.19.19 xmlbuilder: 15.1.1 optional: true @@ -4174,7 +4068,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 22.19.18 + '@types/node': 22.19.19 '@types/unist@2.0.11': {} @@ -4185,17 +4079,17 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.19.18 + '@types/node': 22.19.19 optional: true - '@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.59.2 - '@typescript-eslint/type-utils': 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.59.2 + '@typescript-eslint/parser': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/type-utils': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.3 eslint: 9.39.4(jiti@2.7.0) ignore: 7.0.5 natural-compare: 1.4.0 @@ -4204,41 +4098,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.59.2 - '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.59.2 + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.3 debug: 4.4.3 eslint: 9.39.4(jiti@2.7.0) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.59.2(typescript@5.9.3)': + '@typescript-eslint/project-service@8.59.3(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) - '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3) + '@typescript-eslint/types': 8.59.3 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.59.2': + '@typescript-eslint/scope-manager@8.59.3': dependencies: - '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/visitor-keys': 8.59.2 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/visitor-keys': 8.59.3 - '@typescript-eslint/tsconfig-utils@8.59.2(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.3(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.4(jiti@2.7.0) ts-api-utils: 2.5.0(typescript@5.9.3) @@ -4246,14 +4140,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.59.2': {} + '@typescript-eslint/types@8.59.3': {} - '@typescript-eslint/typescript-estree@8.59.2(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.59.3(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.59.2(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) - '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/visitor-keys': 8.59.2 + '@typescript-eslint/project-service': 8.59.3(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3) + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/visitor-keys': 8.59.3 debug: 4.4.3 minimatch: 10.2.5 semver: 7.8.0 @@ -4263,25 +4157,25 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/utils@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.59.2 - '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) eslint: 9.39.4(jiti@2.7.0) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.59.2': + '@typescript-eslint/visitor-keys@8.59.3': dependencies: - '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/types': 8.59.3 eslint-visitor-keys: 5.0.1 '@ungap/structured-clone@1.3.1': {} - '@vitejs/plugin-react@5.2.0(vite@7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0))': + '@vitejs/plugin-react@5.2.0(vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) @@ -4289,7 +4183,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-rc.3 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0) + vite: 7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0) transitivePeerDependencies: - supports-color @@ -4306,11 +4200,13 @@ snapshots: acorn@8.16.0: {} - agent-base@7.1.4: {} + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color - ajv-formats@3.0.1(ajv@8.20.0): - optionalDependencies: - ajv: 8.20.0 + agent-base@7.1.4: {} ajv-keywords@3.5.2(ajv@6.15.0): dependencies: @@ -4323,13 +4219,6 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.20.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.2 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - ansi-regex@5.0.1: {} ansi-styles@4.3.0: @@ -4456,31 +4345,19 @@ snapshots: at-least-node@1.0.0: {} - atomically@2.1.1: - dependencies: - stubborn-fs: 2.0.0 - when-exit: 2.1.5 - - autoprefixer@10.5.0(postcss@8.5.14): - dependencies: - browserslist: 4.28.2 - caniuse-lite: 1.0.30001792 - fraction.js: 5.3.4 - picocolors: 1.1.1 - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 - axios@1.16.0(debug@4.4.3): + axios@1.16.1: dependencies: - follow-redirects: 1.16.0(debug@4.4.3) + follow-redirects: 1.16.0 form-data: 4.0.5 + https-proxy-agent: 5.0.1 proxy-from-env: 2.1.0 transitivePeerDependencies: - debug + - supports-color bail@2.0.2: {} @@ -4512,8 +4389,8 @@ snapshots: dependencies: baseline-browser-mapping: 2.10.29 caniuse-lite: 1.0.30001792 - electron-to-chromium: 1.5.353 - node-releases: 2.0.38 + electron-to-chromium: 1.5.356 + node-releases: 2.0.44 update-browserslist-db: 1.2.3(browserslist@4.28.2) buffer-crc32@0.2.13: {} @@ -4649,18 +4526,6 @@ snapshots: concat-map@0.0.1: {} - conf@15.1.0: - dependencies: - ajv: 8.20.0 - ajv-formats: 3.0.1(ajv@8.20.0) - atomically: 2.1.1 - debounce-fn: 6.0.0 - dot-prop: 10.1.0 - env-paths: 3.0.0 - json-schema-typed: 8.0.2 - semver: 7.8.0 - uint8array-extras: 1.5.0 - convert-source-map@2.0.0: {} core-util-is@1.0.2: @@ -4700,10 +4565,6 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - debounce-fn@6.0.0: - dependencies: - mimic-function: 5.0.1 - debug@4.4.3: dependencies: ms: 2.1.3 @@ -4779,10 +4640,6 @@ snapshots: dependencies: esutils: 2.0.3 - dot-prop@10.1.0: - dependencies: - type-fest: 5.6.0 - dotenv-expand@11.0.7: dependencies: dotenv: 16.6.1 @@ -4824,7 +4681,7 @@ snapshots: - electron-builder-squirrel-windows - supports-color - electron-log@5.4.3: {} + electron-log@5.4.4: {} electron-publish@26.8.1: dependencies: @@ -4839,27 +4696,9 @@ snapshots: transitivePeerDependencies: - supports-color - electron-store@11.0.2: - dependencies: - conf: 15.1.0 - type-fest: 5.6.0 - - electron-to-chromium@1.5.353: {} - - electron-updater@6.8.3: - dependencies: - builder-util-runtime: 9.5.1 - fs-extra: 10.1.0 - js-yaml: 4.1.1 - lazy-val: 1.0.5 - lodash.escaperegexp: 4.1.2 - lodash.isequal: 4.5.0 - semver: 7.7.4 - tiny-typed-emitter: 2.1.0 - transitivePeerDependencies: - - supports-color + electron-to-chromium@1.5.356: {} - electron-vite@5.0.0(vite@7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0)): + electron-vite@5.0.0(vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0)): dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) @@ -4867,7 +4706,7 @@ snapshots: esbuild: 0.25.12 magic-string: 0.30.21 picocolors: 1.1.1 - vite: 7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0) + vite: 7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0) transitivePeerDependencies: - supports-color @@ -4883,10 +4722,10 @@ snapshots: transitivePeerDependencies: - supports-color - electron@42.0.1: + electron@42.1.0: dependencies: '@electron/get': 5.0.0 - '@types/node': 24.12.3 + '@types/node': 24.12.4 extract-zip: 2.0.1 transitivePeerDependencies: - supports-color @@ -4897,7 +4736,7 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.21.2: + enhanced-resolve@5.21.3: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -5123,7 +4962,7 @@ snapshots: object.fromentries: 2.0.8 object.values: 1.2.1 prop-types: 15.8.1 - resolve: 2.0.0-next.6 + resolve: 2.0.0-next.7 semver: 6.3.1 string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 @@ -5225,8 +5064,6 @@ snapshots: fast-levenshtein@2.0.6: {} - fast-uri@3.1.2: {} - fd-slicer@1.1.0: dependencies: pend: 1.2.0 @@ -5255,9 +5092,7 @@ snapshots: flatted@3.4.2: {} - follow-redirects@1.16.0(debug@4.4.3): - optionalDependencies: - debug: 4.4.3 + follow-redirects@1.16.0: {} for-each@0.3.5: dependencies: @@ -5271,8 +5106,6 @@ snapshots: hasown: 2.0.3 mime-types: 2.1.35 - fraction.js@5.3.4: {} - fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 @@ -5350,11 +5183,6 @@ snapshots: dependencies: pump: 3.0.4 - get-stream@9.0.1: - dependencies: - '@sec-ant/readable-stream': 0.4.1 - is-stream: 4.0.1 - get-symbol-description@1.1.0: dependencies: call-bound: 1.0.4 @@ -5544,6 +5372,13 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 @@ -5551,7 +5386,7 @@ snapshots: transitivePeerDependencies: - supports-color - i18next@26.0.10(typescript@5.9.3): + i18next@26.2.0(typescript@5.9.3): optionalDependencies: typescript: 5.9.3 @@ -5689,8 +5524,6 @@ snapshots: dependencies: call-bound: 1.0.4 - is-stream@4.0.1: {} - is-string@1.1.1: dependencies: call-bound: 1.0.4 @@ -5746,8 +5579,6 @@ snapshots: jiti@2.7.0: {} - jose@6.2.3: {} - js-tokens@4.0.0: {} js-yaml@4.1.1: @@ -5760,10 +5591,6 @@ snapshots: json-schema-traverse@0.4.1: {} - json-schema-traverse@1.0.0: {} - - json-schema-typed@8.0.2: {} - json-stable-stringify-without-jsonify@1.0.1: {} json-stringify-safe@5.0.1: @@ -5852,10 +5679,6 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash.escaperegexp@4.1.2: {} - - lodash.isequal@4.5.0: {} - lodash.merge@4.6.2: {} lodash@4.18.1: {} @@ -6241,8 +6064,6 @@ snapshots: mime@2.6.0: {} - mimic-function@5.0.1: {} - mimic-response@1.0.1: {} mimic-response@3.1.0: {} @@ -6312,7 +6133,7 @@ snapshots: undici: 6.25.0 which: 6.0.1 - node-releases@2.0.38: {} + node-releases@2.0.44: {} nopt@9.0.0: dependencies: @@ -6320,8 +6141,6 @@ snapshots: normalize-url@6.1.0: {} - oauth4webapi@3.8.6: {} - object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -6362,11 +6181,6 @@ snapshots: dependencies: wrappy: 1.0.2 - openid-client@6.8.4: - dependencies: - jose: 6.2.3 - oauth4webapi: 3.8.6 - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -6441,8 +6255,6 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-value-parser@4.2.0: {} - postcss@8.5.14: dependencies: nanoid: 3.3.12 @@ -6501,11 +6313,11 @@ snapshots: react: 19.2.6 scheduler: 0.27.0 - react-i18next@17.0.7(i18next@26.0.10(typescript@5.9.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3): + react-i18next@17.0.8(i18next@26.2.0(typescript@5.9.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3): dependencies: '@babel/runtime': 7.29.2 html-parse-stringify: 3.0.1 - i18next: 26.0.10(typescript@5.9.3) + i18next: 26.2.0(typescript@5.9.3) react: 19.2.6 use-sync-external-store: 1.6.0(react@19.2.6) optionalDependencies: @@ -6609,8 +6421,6 @@ snapshots: require-directory@2.1.1: {} - require-from-string@2.0.2: {} - resedit@1.7.2: dependencies: pe-library: 0.4.1 @@ -6619,7 +6429,7 @@ snapshots: resolve-from@4.0.0: {} - resolve@2.0.0-next.6: + resolve@2.0.0-next.7: dependencies: es-errors: 1.3.0 is-core-module: 2.16.2 @@ -6648,35 +6458,35 @@ snapshots: sprintf-js: 1.1.3 optional: true - rollup@4.60.3: + rollup@4.60.4: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.3 - '@rollup/rollup-android-arm64': 4.60.3 - '@rollup/rollup-darwin-arm64': 4.60.3 - '@rollup/rollup-darwin-x64': 4.60.3 - '@rollup/rollup-freebsd-arm64': 4.60.3 - '@rollup/rollup-freebsd-x64': 4.60.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.3 - '@rollup/rollup-linux-arm-musleabihf': 4.60.3 - '@rollup/rollup-linux-arm64-gnu': 4.60.3 - '@rollup/rollup-linux-arm64-musl': 4.60.3 - '@rollup/rollup-linux-loong64-gnu': 4.60.3 - '@rollup/rollup-linux-loong64-musl': 4.60.3 - '@rollup/rollup-linux-ppc64-gnu': 4.60.3 - '@rollup/rollup-linux-ppc64-musl': 4.60.3 - '@rollup/rollup-linux-riscv64-gnu': 4.60.3 - '@rollup/rollup-linux-riscv64-musl': 4.60.3 - '@rollup/rollup-linux-s390x-gnu': 4.60.3 - '@rollup/rollup-linux-x64-gnu': 4.60.3 - '@rollup/rollup-linux-x64-musl': 4.60.3 - '@rollup/rollup-openbsd-x64': 4.60.3 - '@rollup/rollup-openharmony-arm64': 4.60.3 - '@rollup/rollup-win32-arm64-msvc': 4.60.3 - '@rollup/rollup-win32-ia32-msvc': 4.60.3 - '@rollup/rollup-win32-x64-gnu': 4.60.3 - '@rollup/rollup-win32-x64-msvc': 4.60.3 + '@rollup/rollup-android-arm-eabi': 4.60.4 + '@rollup/rollup-android-arm64': 4.60.4 + '@rollup/rollup-darwin-arm64': 4.60.4 + '@rollup/rollup-darwin-x64': 4.60.4 + '@rollup/rollup-freebsd-arm64': 4.60.4 + '@rollup/rollup-freebsd-x64': 4.60.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 + '@rollup/rollup-linux-arm-musleabihf': 4.60.4 + '@rollup/rollup-linux-arm64-gnu': 4.60.4 + '@rollup/rollup-linux-arm64-musl': 4.60.4 + '@rollup/rollup-linux-loong64-gnu': 4.60.4 + '@rollup/rollup-linux-loong64-musl': 4.60.4 + '@rollup/rollup-linux-ppc64-gnu': 4.60.4 + '@rollup/rollup-linux-ppc64-musl': 4.60.4 + '@rollup/rollup-linux-riscv64-gnu': 4.60.4 + '@rollup/rollup-linux-riscv64-musl': 4.60.4 + '@rollup/rollup-linux-s390x-gnu': 4.60.4 + '@rollup/rollup-linux-x64-gnu': 4.60.4 + '@rollup/rollup-linux-x64-musl': 4.60.4 + '@rollup/rollup-openbsd-x64': 4.60.4 + '@rollup/rollup-openharmony-arm64': 4.60.4 + '@rollup/rollup-win32-arm64-msvc': 4.60.4 + '@rollup/rollup-win32-ia32-msvc': 4.60.4 + '@rollup/rollup-win32-x64-gnu': 4.60.4 + '@rollup/rollup-win32-x64-msvc': 4.60.4 fsevents: 2.3.3 safe-array-concat@1.1.4: @@ -6878,12 +6688,6 @@ snapshots: strip-json-comments@3.1.1: {} - stubborn-fs@2.0.0: - dependencies: - stubborn-utils: 1.0.2 - - stubborn-utils@1.0.2: {} - style-to-js@1.1.21: dependencies: style-to-object: 1.0.14 @@ -6908,8 +6712,6 @@ snapshots: dependencies: '@pkgr/core': 0.2.9 - tagged-tag@1.0.0: {} - tailwindcss@4.3.0: {} tapable@2.3.3: {} @@ -6936,8 +6738,6 @@ snapshots: dependencies: semver: 5.7.2 - tiny-typed-emitter@2.1.0: {} - tinyglobby@0.2.16: dependencies: fdir: 6.5.0(picomatch@4.0.4) @@ -6968,10 +6768,6 @@ snapshots: type-fest@0.13.1: optional: true - type-fest@5.6.0: - dependencies: - tagged-tag: 1.0.0 - typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 @@ -7005,12 +6801,12 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3): + typescript-eslint@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) eslint: 9.39.4(jiti@2.7.0) typescript: 5.9.3 transitivePeerDependencies: @@ -7018,8 +6814,6 @@ snapshots: typescript@5.9.3: {} - uint8array-extras@1.5.0: {} - unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -7111,16 +6905,16 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@7.3.3(@types/node@22.19.18)(jiti@2.7.0)(lightningcss@1.32.0): + vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 postcss: 8.5.14 - rollup: 4.60.3 + rollup: 4.60.4 tinyglobby: 0.2.16 optionalDependencies: - '@types/node': 22.19.18 + '@types/node': 22.19.19 fsevents: 2.3.3 jiti: 2.7.0 lightningcss: 1.32.0 @@ -7129,8 +6923,6 @@ snapshots: web-namespaces@2.0.1: {} - when-exit@2.1.5: {} - which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -7221,11 +7013,6 @@ snapshots: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 - yauzl@3.3.0: - dependencies: - buffer-crc32: 0.2.13 - pend: 1.2.0 - yocto-queue@0.1.0: {} zod-validation-error@4.0.2(zod@4.4.3): diff --git a/resources/entitlements.mac.plist b/resources/entitlements.mac.plist new file mode 100644 index 0000000..38c887b --- /dev/null +++ b/resources/entitlements.mac.plist @@ -0,0 +1,12 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.allow-dyld-environment-variables + + + diff --git a/resources/icon.icns b/resources/icon.icns new file mode 100644 index 0000000..28644aa Binary files /dev/null and b/resources/icon.icns differ diff --git a/resources/icon.ico b/resources/icon.ico new file mode 100644 index 0000000..1b93f4c Binary files /dev/null and b/resources/icon.ico differ diff --git a/resources/icon.png b/resources/icon.png index cf9e8b2..ca3c5a6 100644 Binary files a/resources/icon.png and b/resources/icon.png differ diff --git a/src/main/config/env.ts b/src/main/config/api.ts similarity index 54% rename from src/main/config/env.ts rename to src/main/config/api.ts index 8f1ec73..053b695 100644 --- a/src/main/config/env.ts +++ b/src/main/config/api.ts @@ -1,27 +1,20 @@ -// Point d'accès unique aux variables d'environnement dans le main process. -// Avec electron-vite, les variables VITE_* sont injectées via import.meta.env. - -import type { Env } from '../../renderer/store/env' +import type { Env } from '@shared/types/env' /** - * Retourne l'URL de base de l'API pour un env donné. - * Retourne null si la variable est vide → env indisponible. + * Returns the API base URL for an environment, or null when unset. */ export function getApiBase(env: Env): string | null { - // import.meta.env.* est remplacé au build par electron-vite (fichiers .env / .env.production). - // process.env ne contient pas ces clés dans l’exe packagé. const raw = env === 'universe' ? import.meta.env.VITE_API_BASE_UNIVERSE : import.meta.env.VITE_API_BASE_TESTING - const trimmed = (raw ?? '').trim().replace(/\/$/, '') // supprime le slash final + const trimmed = (raw ?? '').trim().replace(/\/$/, '') return trimmed || null } /** - * URL utilisée uniquement pour télécharger les ZIP du jeu (optionnel). - * Si vide → on réutilise {@link getApiBase} (ex. CDN différent de l’API). + * Optional download host override; falls back to {@link getApiBase}. */ export function getDownloadBase(env: Env): string | null { const raw = @@ -33,6 +26,7 @@ export function getDownloadBase(env: Env): string | null { return trimmed || getApiBase(env) } +/** Picks the platform-specific ZIP URL from env overrides. */ function pickZipUrlForPlatform( platform: NodeJS.Platform, urls: { win: string; linux: string; darwin: string } @@ -43,39 +37,28 @@ function pickZipUrlForPlatform( return null } -/** - * URLs complètes des archives pour l’env **universe** (prod), une par OS. - * Si définie pour la plateforme courante, elle remplace `/game/latest-*.zip`. - */ +/** Full ZIP URL for production (`universe`) on the current platform. */ export function getUniverseZipUrlForPlatform(platform: NodeJS.Platform): string | null { return pickZipUrlForPlatform(platform, { - win: (import.meta.env.VITE_GAME_ZIP_WINDOWS ?? '').trim(), - linux: (import.meta.env.VITE_GAME_ZIP_LINUX ?? '').trim(), + win: (import.meta.env.VITE_GAME_ZIP_WINDOWS ?? '').trim(), + linux: (import.meta.env.VITE_GAME_ZIP_LINUX ?? '').trim(), darwin: (import.meta.env.VITE_GAME_ZIP_DARWIN ?? '').trim() }) } -/** - * URLs complètes des archives pour l’env **universe-testing** (une par OS). - * Si définie pour la plateforme courante, elle remplace `/game/latest-*.zip`. - */ +/** Full ZIP URL for testing (`universe-testing`) on the current platform. */ export function getTestingZipUrlForPlatform(platform: NodeJS.Platform): string | null { return pickZipUrlForPlatform(platform, { - win: (import.meta.env.VITE_GAME_ZIP_TESTING_WINDOWS ?? '').trim(), - linux: (import.meta.env.VITE_GAME_ZIP_TESTING_LINUX ?? '').trim(), + win: (import.meta.env.VITE_GAME_ZIP_TESTING_WINDOWS ?? '').trim(), + linux: (import.meta.env.VITE_GAME_ZIP_TESTING_LINUX ?? '').trim(), darwin: (import.meta.env.VITE_GAME_ZIP_TESTING_DARWIN ?? '').trim() }) } -/** - * Dérive l'URL de base du sous-domaine "status" depuis l'URL principale. - * https://dyingstar-game.com → https://status.dyingstar-game.com - * (sera transparent quand tout sera consolidé sous une seule URL) - */ +/** Derives the status subdomain from the main API base URL. */ export function getStatusBase(apiBase: string): string { try { const url = new URL(apiBase) - // Évite de doubler le préfixe si déjà présent if (!url.hostname.startsWith('status.')) { url.hostname = `status.${url.hostname}` } @@ -85,12 +68,13 @@ export function getStatusBase(apiBase: string): string { } } +/** Parses a positive Cachet component/metric id from env with fallback. */ function parseStatusNumericId(raw: string | undefined, fallback: number): number { const n = Number(String(raw ?? '').trim()) return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback } -/** ID Cachet du composant « statut » (API /api/components/:id) — par environnement. */ +/** Cachet component id for server status (`/api/components/:id`). */ export function getStatusComponentId(env: Env): number { const raw = env === 'universe' @@ -99,7 +83,7 @@ export function getStatusComponentId(env: Env): number { return parseStatusNumericId(raw, 3) } -/** ID Cachet de la métrique « joueurs » (API /api/metrics/:id/points) — par environnement. */ +/** Cachet metric id for player count (`/api/metrics/:id/points`). */ export function getStatusMetricId(env: Env): number { const raw = env === 'universe' @@ -108,17 +92,17 @@ export function getStatusMetricId(env: Env): number { return parseStatusNumericId(raw, 2) } -/** Tous les endpoints dérivés d'une URL de base */ +/** Endpoint builders derived from a base API URL. */ export const ENDPOINTS = { - version: (base: string): string => `${base}/version`, - status: (base: string, componentId: number): string => + version: (base: string): string => `${base}/version`, + status: (base: string, componentId: number): string => `${getStatusBase(base)}/api/components/${componentId}`, - metrics: (base: string, metricId: number): string => + metrics: (base: string, metricId: number): string => `${getStatusBase(base)}/api/metrics/${metricId}/points?sort=-id`, - zipWin32: (base: string): string => `${base}/game/latest-windows.zip`, - zipLinux: (base: string): string => `${base}/game/latest-linux.zip`, + zipWin32: (base: string): string => `${base}/game/latest-windows.zip`, + zipLinux: (base: string): string => `${base}/game/latest-linux.zip`, zipDarwin: (base: string): string => `${base}/game/latest-macos.zip`, - authBase: (base: string): string => { + authBase: (base: string): string => { try { const url = new URL(base) if (!url.hostname.startsWith('auth-preprod.') && !url.hostname.startsWith('auth.')) { @@ -129,4 +113,4 @@ export const ENDPOINTS = { return base } } -} \ No newline at end of file +} diff --git a/src/main/config/auth.ts b/src/main/config/auth.ts new file mode 100644 index 0000000..3d24dd4 --- /dev/null +++ b/src/main/config/auth.ts @@ -0,0 +1,19 @@ +import { APP_PROTOCOL } from './constants' + +/** OAuth2 / OpenID client id registered in Keycloak. */ +export const AUTH_CLIENT_ID = + (import.meta.env.VITE_AUTH_CLIENT_ID ?? 'dyingstar-launcher').trim() || 'dyingstar-launcher' + +/** Keycloak realm name. */ +export const AUTH_REALM = (import.meta.env.VITE_AUTH_REALM ?? 'dyingstar').trim() || 'dyingstar' + +/** Redirect URI registered for the desktop OAuth flow. */ +export const AUTH_REDIRECT_URI = + (import.meta.env.VITE_AUTH_REDIRECT_URI ?? `${APP_PROTOCOL}://auth/callback`).trim() || + `${APP_PROTOCOL}://auth/callback` + +/** OpenID scopes requested during login and refresh. */ +export const AUTH_SCOPES = 'openid email profile' + +/** Identity provider hint passed to Keycloak (Discord). */ +export const AUTH_IDP_HINT = 'discord' diff --git a/src/main/config/constants.ts b/src/main/config/constants.ts new file mode 100644 index 0000000..bf1bbae --- /dev/null +++ b/src/main/config/constants.ts @@ -0,0 +1,48 @@ +/** Parses a positive integer from an env string with a numeric fallback. */ +export function parsePositiveInt(raw: string | undefined, fallback: number): number { + const n = Number(raw) + return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback +} + +/** HTTP / fetch timeouts (milliseconds). Overridable via VITE_* env vars. */ +export const HTTP_TIMEOUT_MS = { + api: parsePositiveInt(import.meta.env.VITE_HTTP_TIMEOUT_API_MS, 8_000), + versionPing: parsePositiveInt(import.meta.env.VITE_HTTP_TIMEOUT_VERSION_PING_MS, 5_000), + github: parsePositiveInt(import.meta.env.VITE_HTTP_TIMEOUT_GITHUB_MS, 10_000), + download: parsePositiveInt(import.meta.env.VITE_DOWNLOAD_TIMEOUT_MS, 600_000) +} as const + +/** Game process poll interval when tracking a running child (milliseconds). */ +export const GAME_PROCESS_POLL_MS = parsePositiveInt( + import.meta.env.VITE_GAME_PROCESS_POLL_MS, + 2_000 +) + +/** Install layout: subdirectory name inside the user-chosen install path. */ +export const GAME_INSTALL_SUBDIR = + (import.meta.env.VITE_GAME_INSTALL_SUBDIR ?? 'DyingStar').trim() || 'DyingStar' + +/** Temporary ZIP filename during download. */ +export const GAME_DOWNLOAD_ZIP_NAME = '__game_download.zip' + +/** Platform-specific game executable names (relative to game root). */ +export const GAME_EXECUTABLES: Partial> = { + win32: (import.meta.env.VITE_GAME_EXE_WINDOWS ?? 'DyingStar.exe').trim() || 'DyingStar.exe', + linux: (import.meta.env.VITE_GAME_EXE_LINUX ?? 'DyingStar.x86_64').trim() || 'DyingStar.x86_64', + darwin: (import.meta.env.VITE_GAME_EXE_DARWIN ?? 'DyingStar.app').trim() || 'DyingStar.app' +} + +/** Custom protocol scheme for OAuth callbacks. */ +export const APP_PROTOCOL = (import.meta.env.VITE_APP_PROTOCOL ?? 'dyingstar').trim() || 'dyingstar' + +/** User-Agent sent when downloading game archives. */ +export const DOWNLOAD_USER_AGENT = + (import.meta.env.VITE_DOWNLOAD_USER_AGENT ?? 'DyingStar-Launcher/1.0').trim() || + 'DyingStar-Launcher/1.0' + +/** Download progress phase weights (0–100 scale). */ +export const DOWNLOAD_PROGRESS = { + zipWeight: 70, + unknownChunkBytes: 2 * 1024 * 1024, + unknownSizeCapBytes: 80 * 1024 * 1024 +} as const diff --git a/src/main/icon.ts b/src/main/icon.ts new file mode 100644 index 0000000..753d2aa --- /dev/null +++ b/src/main/icon.ts @@ -0,0 +1,61 @@ +import { app, nativeImage } from 'electron' +import { existsSync } from 'fs' +import { join } from 'path' +import { is } from '@electron-toolkit/utils' + +/** Icon file name for the current platform. */ +function iconFileName(): string { + if (process.platform === 'win32') return 'icon.ico' + if (process.platform === 'darwin') return 'icon.icns' + return 'icon.png' +} + +/** Candidate icon paths (dev, preview, packaged build). */ +function candidateIconPaths(): string[] { + const name = iconFileName() + const paths: string[] = [] + + paths.push(join(__dirname, '../../resources', name)) + + try { + paths.push(join(app.getAppPath(), 'resources', name)) + } catch { + /* app not ready yet */ + } + + if (process.resourcesPath) { + paths.push(join(process.resourcesPath, name)) + } + + return paths +} + +/** Absolute path to the launcher icon, or null when not found. */ +export function resolveAppIconPath(): string | null { + for (const p of candidateIconPaths()) { + if (existsSync(p)) return p + } + return null +} + +/** Loads the native image for BrowserWindow / tray use. */ +export function loadAppIcon(): Electron.NativeImage | undefined { + const iconPath = resolveAppIconPath() + if (!iconPath) { + if (is.dev) { + console.warn('[Icon] Icon file not found — using default Electron taskbar icon.') + } + return undefined + } + const image = nativeImage.createFromPath(iconPath) + return image.isEmpty() ? undefined : image +} + +/** Applies the icon to the macOS dock when available. */ +export function applyAppIcon(): void { + const image = loadAppIcon() + if (!image) return + if (process.platform === 'darwin' && app.dock) { + app.dock.setIcon(image) + } +} diff --git a/src/main/index.ts b/src/main/index.ts index 4333634..f58ce8b 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,98 +1,43 @@ import { app, shell, BrowserWindow, ipcMain } from 'electron' import { join } from 'path' import path from 'path' -import fs from 'fs' -import { execSync } from 'child_process' import { electronApp, optimizer, is } from '@electron-toolkit/utils' -import icon from '../../resources/icon.png?asset' +import { applyAppIcon, loadAppIcon } from './icon' import { registerFilesHandlers } from './services/game' import { registerVersionHandlers } from './services/version' import { registerGameStatusHandlers } from './services/gameStatus' import { registerAuthHandlers, handleOAuthCallback } from './services/auth' import { registerWindowHandlers, MIN_WIDTH, MIN_HEIGHT } from './services/window' +import { APP_PROTOCOL, parsePositiveInt } from './config/constants' +import { registerLinuxProtocolHandler } from './protocol/linuxDesktop' import log from 'electron-log' -// ─── Manage log (import.meta.env = valeurs figées au build, comme les autres VITE_*) ─── -if (import.meta.env.VITE_ELECTRON_ENABLE_LOGGING === 'true') log.transports.file.level = 'debug' - -function parsePositiveInt(raw: string | undefined, fallback: number): number { - const n = Number(raw) - return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback +if (import.meta.env.VITE_ELECTRON_ENABLE_LOGGING === 'true') { + log.transports.file.level = 'debug' } -// ─── Custom protocol (must be set before app is ready) ──────────────────────── -// In development, Electron is launched as `electron /path/to/main.js`; the -// protocol client must include the script path so the OS routes the callback -// back to this instance via a second-instance launch. - +/** Register custom protocol before app ready (dev needs script path in argv). */ if (process.defaultApp && process.argv.length >= 2) { - app.setAsDefaultProtocolClient('dyingstar', process.execPath, [path.resolve(process.argv[1])]) + app.setAsDefaultProtocolClient(APP_PROTOCOL, process.execPath, [path.resolve(process.argv[1])]) } else { - app.setAsDefaultProtocolClient('dyingstar') -} - -// ─── Linux: ensure xdg protocol handler is registered ──────────────────────── -// Electron's setAsDefaultProtocolClient does not create the .desktop file on -// Linux in dev mode. We do it manually so the OS can route dyingstar:// back. - -function registerLinuxProtocol(): void { - if (process.platform !== 'linux') return - - const desktopDir = path.join(app.getPath('home'), '.local', 'share', 'applications') - const desktopFile = path.join(desktopDir, 'dyingstar-launcher.desktop') - - const execLine = process.defaultApp && process.argv.length >= 2 - ? `${process.execPath} ${path.resolve(process.argv[1])} %U` - : `${process.execPath} %U` - - const contents = [ - '[Desktop Entry]', - 'Type=Application', - 'Name=DyingStar Launcher', - `Exec=${execLine}`, - 'MimeType=x-scheme-handler/dyingstar;', - 'NoDisplay=true', - ].join('\n') + '\n' - - try { - fs.mkdirSync(desktopDir, { recursive: true }) - fs.writeFileSync(desktopFile, contents, 'utf-8') - - try { - execSync(`xdg-mime default dyingstar-launcher.desktop x-scheme-handler/dyingstar`) - } catch { - console.warn('[Protocol] xdg-mime not available, skipping mime association') - } - - try { - execSync(`update-desktop-database ${desktopDir}`) - } catch { - console.warn('[Protocol] update-desktop-database not available, skipping db update') - } - - console.log('[Protocol] dyingstar:// registered via xdg') - } catch (err) { - console.error('[Protocol] Failed to register dyingstar:// handler:', err) - } + app.setAsDefaultProtocolClient(APP_PROTOCOL) } -// ─── macOS / Linux: app already running, URL opened externally ──────────────── - +/** macOS: OAuth callback URL opened while app is running. */ app.on('open-url', (_event, url) => { - handleOAuthCallback(url) + void handleOAuthCallback(url) }) -// ─── Windows: second instance spawned with the URL as argv ─────────────────── - let mainWindow: BrowserWindow | null = null const gotLock = app.requestSingleInstanceLock() if (!gotLock) { app.quit() } else { + /** Windows: second instance receives OAuth URL in argv. */ app.on('second-instance', (_event, argv) => { - const url = argv.find((a) => a.startsWith('dyingstar://')) - if (url) handleOAuthCallback(url) + const url = argv.find((a) => a.startsWith(`${APP_PROTOCOL}://`)) + if (url) void handleOAuthCallback(url) if (mainWindow) { if (mainWindow.isMinimized()) mainWindow.restore() mainWindow.focus() @@ -100,18 +45,21 @@ if (!gotLock) { }) } +/** Creates the main application window and registers IPC handlers bound to it. */ function createWindow(): void { + const appIcon = loadAppIcon() + mainWindow = new BrowserWindow({ - width: parsePositiveInt(import.meta.env.VITE_WINDOW_WIDTH, 1200), + width: parsePositiveInt(import.meta.env.VITE_WINDOW_WIDTH, 1200), height: parsePositiveInt(import.meta.env.VITE_WINDOW_HEIGHT, 800), - minWidth: MIN_WIDTH, + minWidth: MIN_WIDTH, minHeight: MIN_HEIGHT, frame: false, backgroundColor: '#0d0d14', title: app.getName(), show: false, autoHideMenuBar: true, - ...(process.platform === 'linux' ? { icon } : {}), + ...(appIcon ? { icon: appIcon } : {}), webPreferences: { preload: join(__dirname, '../preload/index.js'), sandbox: false @@ -119,14 +67,14 @@ function createWindow(): void { }) registerWindowHandlers(() => mainWindow) - - // Enregistrement des handlers IPC registerFilesHandlers(mainWindow) registerAuthHandlers(mainWindow) mainWindow.on('ready-to-show', () => { mainWindow!.show() - if (import.meta.env.VITE_ENABLE_DEVTOOLS === 'true') mainWindow!.webContents.openDevTools() + if (import.meta.env.VITE_ENABLE_DEVTOOLS === 'true') { + mainWindow!.webContents.openDevTools() + } }) mainWindow.webContents.setWindowOpenHandler((details) => { @@ -142,28 +90,25 @@ function createWindow(): void { } app.whenReady().then(() => { - electronApp.setAppUserModelId('com.electron') + electronApp.setAppUserModelId('com.dyingstar.launcher') - registerLinuxProtocol() + applyAppIcon() + registerLinuxProtocolHandler() app.on('browser-window-created', (_, window) => { optimizer.watchWindowShortcuts(window) }) - ipcMain.on('ping', () => console.log('pong')) - ipcMain.removeHandler('app:quit') ipcMain.handle('app:quit', () => { app.quit() }) - // Handlers indépendants de la fenêtre registerVersionHandlers() registerGameStatusHandlers() - createWindow() - app.on('activate', function () { + app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) }) @@ -172,4 +117,4 @@ app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } -}) \ No newline at end of file +}) diff --git a/src/main/l10n/dialogs.ts b/src/main/l10n/dialogs.ts new file mode 100644 index 0000000..0b4b43d --- /dev/null +++ b/src/main/l10n/dialogs.ts @@ -0,0 +1,27 @@ +import { app } from 'electron' + +type InstallDialogStrings = { + selectDirectoryTitle: string + selectDirectoryButton: string +} + +const DIALOGS: Record<'en' | 'fr', InstallDialogStrings> = { + en: { + selectDirectoryTitle: 'Installation directory', + selectDirectoryButton: 'Select folder' + }, + fr: { + selectDirectoryTitle: "Répertoire d'installation", + selectDirectoryButton: 'Choisir le dossier' + } +} + +function resolveLocale(): 'en' | 'fr' { + const locale = app.getLocale().toLowerCase() + return locale.startsWith('fr') ? 'fr' : 'en' +} + +/** Native open-dialog strings aligned with the OS locale (fr/en). */ +export function getInstallDialogStrings(): InstallDialogStrings { + return DIALOGS[resolveLocale()] +} diff --git a/src/main/protocol/linuxDesktop.ts b/src/main/protocol/linuxDesktop.ts new file mode 100644 index 0000000..6c08341 --- /dev/null +++ b/src/main/protocol/linuxDesktop.ts @@ -0,0 +1,49 @@ +import { app } from 'electron' +import { execSync } from 'child_process' +import fs from 'fs' +import path from 'path' +import { APP_PROTOCOL } from '../config/constants' + +/** Registers a `.desktop` file so Linux can route custom protocol URLs to this app. */ +export function registerLinuxProtocolHandler(): void { + if (process.platform !== 'linux') return + + const desktopDir = path.join(app.getPath('home'), '.local', 'share', 'applications') + const desktopFile = path.join(desktopDir, 'dyingstar-launcher.desktop') + + const execLine = + process.defaultApp && process.argv.length >= 2 + ? `${process.execPath} ${path.resolve(process.argv[1])} %U` + : `${process.execPath} %U` + + const contents = + [ + '[Desktop Entry]', + 'Type=Application', + 'Name=DyingStar Launcher', + `Exec=${execLine}`, + `MimeType=x-scheme-handler/${APP_PROTOCOL};`, + 'NoDisplay=true' + ].join('\n') + '\n' + + try { + fs.mkdirSync(desktopDir, { recursive: true }) + fs.writeFileSync(desktopFile, contents, 'utf-8') + + try { + execSync(`xdg-mime default dyingstar-launcher.desktop x-scheme-handler/${APP_PROTOCOL}`) + } catch { + console.warn('[Protocol] xdg-mime not available, skipping mime association') + } + + try { + execSync(`update-desktop-database ${desktopDir}`) + } catch { + console.warn('[Protocol] update-desktop-database not available, skipping db update') + } + + console.log(`[Protocol] ${APP_PROTOCOL}:// registered via xdg`) + } catch (err) { + console.error('[Protocol] Failed to register custom protocol handler:', err) + } +} diff --git a/src/main/services/auth.ts b/src/main/services/auth.ts deleted file mode 100644 index b4ce8da..0000000 --- a/src/main/services/auth.ts +++ /dev/null @@ -1,359 +0,0 @@ -import { app, ipcMain, shell, safeStorage, BrowserWindow } from 'electron' -import crypto from 'crypto' -import fs from 'fs' -import path from 'path' -import { URL } from 'url' -import { getApiBase, ENDPOINTS } from '../config/env' -import type { Env } from '../../renderer/store/env' - -// ─── Types ──────────────────────────────────────────────────────────────────── - -interface TokenSet { - access_token: string - refresh_token: string - id_token: string - expires_in: number - token_type: string -} - -export interface UserInfo { - sub: string - username: string - email: string -} - -interface PKCESession { - env: Env - verifier: string - state: string -} - -// ─── State ──────────────────────────────────────────────────────────────────── - -const REDIRECT_URI = 'dyingstar://auth/callback' -const CLIENT_ID = 'dyingstar-launcher' -const REALM = 'dyingstar' - -let pkceSession: PKCESession | null = null -let mainWindow: BrowserWindow | null = null - -// ─── Auth base dérivé de l'API base ─────────────────────────────────────────── - -function getKeycloakBase(env: Env): string | null { - const base = getApiBase(env) - if (!base) return null - return ENDPOINTS.authBase(base) -} - -// ─── Token Storage ──────────────────────────────────────────────────────────── - -function getTokenPath(env: Env): string { - const filename = env === 'universe' ? 'tokens.enc' : `tokens-${env}.enc` - return path.join(app.getPath('userData'), filename) -} - -function storeTokens(env: Env, tokens: TokenSet): void { - const json = JSON.stringify(tokens) - if (safeStorage.isEncryptionAvailable()) { - fs.writeFileSync(getTokenPath(env), safeStorage.encryptString(json)) - } else { - console.warn('[Auth] safeStorage unavailable, plain JSON fallback') - fs.writeFileSync(getTokenPath(env), json, 'utf-8') - } -} - -function loadTokens(env: Env): TokenSet | null { - const p = getTokenPath(env) - if (!fs.existsSync(p)) return null - try { - const buf = fs.readFileSync(p) - if (safeStorage.isEncryptionAvailable()) { - return JSON.parse(safeStorage.decryptString(buf)) as TokenSet - } - return JSON.parse(buf.toString('utf-8')) as TokenSet - } catch { return null } -} - -function clearStoredTokens(env: Env): void { - const p = getTokenPath(env) - if (fs.existsSync(p)) fs.unlinkSync(p) -} - -// ─── PKCE ───────────────────────────────────────────────────────────────────── - -function generatePKCE(): { verifier: string; challenge: string } { - const verifier = crypto.randomBytes(32).toString('base64url') - const challenge = crypto.createHash('sha256').update(verifier).digest('base64url') - return { verifier, challenge } -} - -function generateState(): string { - return crypto.randomBytes(16).toString('base64url') -} - -// ─── JWT ────────────────────────────────────────────────────────────────────── - -function decodeJwtPayload(token: string): Record { - const parts = token.split('.') - if (parts.length !== 3) throw new Error('Invalid JWT') - return JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8')) -} - -const UUID_RE = - /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i - -function getJwtSub(token: string): string | null { - try { - const sub = decodeJwtPayload(token)['sub'] - return typeof sub === 'string' && sub.length > 0 ? sub : null - } catch { - return null - } -} - -function isValidPlayerSub(sub: string): boolean { - return UUID_RE.test(sub) -} - -function isJwtNotExpired(token: string): boolean { - try { - const exp = decodeJwtPayload(token)['exp'] - if (typeof exp !== 'number') return false - return exp > Math.floor(Date.now() / 1000) - } catch { - return false - } -} - -function getJwtPreferredUsername(token: string): string | null { - try { - const username = decodeJwtPayload(token)['preferred_username'] - return typeof username === 'string' && username.length > 0 ? username : null - } catch { - return null - } -} - -function isValidGameLaunchToken(token: string): boolean { - const sub = getJwtSub(token) - return ( - sub !== null && - isValidPlayerSub(sub) && - getJwtPreferredUsername(token) !== null && - isJwtNotExpired(token) - ) -} - -/** Choisit l'id_token pour le client jeu (claims identité requis côté serveur). */ -function pickGameLaunchToken(tokens: TokenSet): string | null { - const token = tokens.id_token - if (!token || !isValidGameLaunchToken(token)) return null - return token -} - -function extractUser(tokens: TokenSet): UserInfo { - const p = decodeJwtPayload(tokens.id_token) - return { - sub: p['sub'] as string, - username: ((p['preferred_username'] ?? p['name']) as string | undefined) ?? 'Unknown', - email: (p['email'] as string | undefined) ?? '' - } -} - -// ─── Auth Flow ──────────────────────────────────────────────────────────────── - -export async function startLogin(env: Env): Promise { - const kcBase = getKeycloakBase(env) - if (!kcBase) throw new Error(`Auth non disponible pour l'env: ${env}`) - - const { verifier, challenge } = generatePKCE() - const state = generateState() - pkceSession = { env, verifier, state } - - const params = new URLSearchParams({ - client_id: CLIENT_ID, - redirect_uri: REDIRECT_URI, - response_type: 'code', - scope: 'openid email profile', - kc_idp_hint: 'discord', - code_challenge: challenge, - code_challenge_method: 'S256', - state - }) - - await shell.openExternal( - `${kcBase}/realms/${REALM}/protocol/openid-connect/auth?${params}` - ) -} - -export async function handleOAuthCallback(rawUrl: string): Promise { - let url: URL - try { url = new URL(rawUrl) } catch { return } - if (url.protocol !== 'dyingstar:' || url.host !== 'auth' || url.pathname !== '/callback') return - - const code = url.searchParams.get('code') - const state = url.searchParams.get('state') - const error = url.searchParams.get('error') - - if (!code && !error) return // post-logout - - const envForEvent = pkceSession?.env ?? 'universe-testing' - - if (error) { - mainWindow?.webContents.send('auth:state-changed', { env: envForEvent, status: 'error', error }) - return - } - - if (!code || !state || !pkceSession || state !== pkceSession.state) { - mainWindow?.webContents.send('auth:state-changed', { - env: envForEvent, status: 'error', error: 'invalid_callback' - }) - return - } - - const { env, verifier } = pkceSession - pkceSession = null - - const kcBase = getKeycloakBase(env) - if (!kcBase) return - - try { - const tokens = await exchangeCode(kcBase, code, verifier) - storeTokens(env, tokens) - mainWindow?.webContents.send('auth:state-changed', { - env, status: 'connected', user: extractUser(tokens) - }) - } catch (err) { - console.error('[Auth] Token exchange failed:', err) - mainWindow?.webContents.send('auth:state-changed', { - env, status: 'error', error: 'token_exchange_failed' - }) - } -} - -async function exchangeCode(kcBase: string, code: string, verifier: string): Promise { - const res = await fetch( - `${kcBase}/realms/${REALM}/protocol/openid-connect/token`, - { - method: 'POST', - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - body: new URLSearchParams({ - grant_type: 'authorization_code', - client_id: CLIENT_ID, - code, - redirect_uri: REDIRECT_URI, - code_verifier: verifier - }).toString() - } - ) - if (!res.ok) throw new Error(`Token exchange failed (${res.status}): ${await res.text()}`) - return res.json() as Promise -} - -async function refreshToken(kcBase: string, token: string): Promise { - const res = await fetch( - `${kcBase}/realms/${REALM}/protocol/openid-connect/token`, - { - method: 'POST', - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - body: new URLSearchParams({ - grant_type: 'refresh_token', - client_id: CLIENT_ID, - refresh_token: token, - scope: 'openid email profile' - }).toString() - } - ) - if (!res.ok) return null - return res.json() as Promise -} - -function mergeTokenSet(previous: TokenSet, refreshed: TokenSet): TokenSet { - const idCandidates = [refreshed.id_token, previous.id_token].filter(Boolean) - const id_token = - idCandidates.find((t) => isValidGameLaunchToken(t)) ?? - refreshed.id_token ?? - previous.id_token - - return { ...previous, ...refreshed, id_token } -} - -/** JWT valide pour le client jeu (rafraîchit si besoin, sub UUID requis). */ -export async function loadFreshGameToken(env: Env): Promise { - const kcBase = getKeycloakBase(env) - const tokens = loadTokens(env) - if (!kcBase || !tokens) return null - - const refreshed = await refreshToken(kcBase, tokens.refresh_token) - if (!refreshed) { - clearStoredTokens(env) - return null - } - - const merged = mergeTokenSet(tokens, refreshed) - storeTokens(env, merged) - const launchToken = pickGameLaunchToken(merged) - if (!launchToken) { - console.error('[Auth] Jeton jeu invalide:', describeGameTokenIssue(merged)) - } - return launchToken -} - -function describeGameTokenIssue(tokens: TokenSet): string { - const token = tokens.id_token - if (!token) return 'id_token absent — reconnectez-vous' - if (!isJwtNotExpired(token)) return 'id_token expiré — reconnectez-vous' - const sub = getJwtSub(token) - if (!sub || !isValidPlayerSub(sub)) return `sub UUID invalide (${sub ?? 'vide'})` - if (!getJwtPreferredUsername(token)) { - return 'preferred_username absent de l\'id_token (vérifier Keycloak / scope profile)' - } - return 'raison inconnue' -} - -// ─── IPC Handlers ───────────────────────────────────────────────────────────── - -export function registerAuthHandlers(win: BrowserWindow): void { - mainWindow = win - - ipcMain.handle('auth:login', async (_event, env: Env) => { - try { - await startLogin(env) - } catch (err) { - console.error('[Auth] Failed to open browser:', err) - mainWindow?.webContents.send('auth:state-changed', { - env, status: 'error', error: 'browser_open_failed' - }) - } - }) - - ipcMain.handle('auth:logout', (_event, env: Env) => { - const kcBase = getKeycloakBase(env) - const tokens = loadTokens(env) - clearStoredTokens(env) - - if (kcBase && tokens?.id_token) { - const params = new URLSearchParams({ - client_id: CLIENT_ID, - post_logout_redirect_uri: REDIRECT_URI, - id_token_hint: tokens.id_token - }) - shell.openExternal( - `${kcBase}/realms/${REALM}/protocol/openid-connect/logout?${params}` - ) - } - }) - - ipcMain.handle('auth:load-user', async (_event, env: Env): Promise => { - const kcBase = getKeycloakBase(env) - const tokens = loadTokens(env) - if (!kcBase || !tokens) return null - - const refreshed = await refreshToken(kcBase, tokens.refresh_token) - if (!refreshed) { clearStoredTokens(env); return null } - - const merged = mergeTokenSet(tokens, refreshed) - storeTokens(env, merged) - return extractUser(merged) - }) -} \ No newline at end of file diff --git a/src/main/services/auth/flow.ts b/src/main/services/auth/flow.ts new file mode 100644 index 0000000..44d0383 --- /dev/null +++ b/src/main/services/auth/flow.ts @@ -0,0 +1,168 @@ +import { shell } from 'electron' +import { URL, URLSearchParams } from 'url' +import { + AUTH_CLIENT_ID, + AUTH_IDP_HINT, + AUTH_REALM, + AUTH_REDIRECT_URI, + AUTH_SCOPES +} from '../../config/auth' +import { APP_PROTOCOL } from '../../config/constants' +import type { Env } from '@shared/types/env' +import type { UserInfo } from '@shared/types/auth' +import type { PKCESession } from './types' +import { generatePKCE, generateState } from './pkce' +import { describeGameTokenIssue, extractUser, pickGameLaunchToken } from './jwt' +import { exchangeCode, getKeycloakBase, mergeTokenSet, refreshToken } from './keycloakClient' +import { clearStoredTokens, loadTokens, storeTokens } from './tokenStorage' + +let pkceSession: PKCESession | null = null + +type AuthEventSender = { + send(channel: 'auth:state-changed', payload: unknown): void +} + +let eventSender: AuthEventSender | null = null + +/** Registers the object used to push auth state events to the renderer. */ +export function setAuthEventSender(sender: AuthEventSender): void { + eventSender = sender +} + +/** Opens the system browser on the Keycloak authorization URL (PKCE). */ +export async function startLogin(env: Env): Promise { + const kcBase = getKeycloakBase(env) + if (!kcBase) throw new Error(`Auth unavailable for env: ${env}`) + + const { verifier, challenge } = generatePKCE() + const state = generateState() + pkceSession = { env, verifier, state } + + const params = new URLSearchParams({ + client_id: AUTH_CLIENT_ID, + redirect_uri: AUTH_REDIRECT_URI, + response_type: 'code', + scope: AUTH_SCOPES, + kc_idp_hint: AUTH_IDP_HINT, + code_challenge: challenge, + code_challenge_method: 'S256', + state + }) + + await shell.openExternal(`${kcBase}/realms/${AUTH_REALM}/protocol/openid-connect/auth?${params}`) +} + +/** Handles `dyingstar://auth/callback` deep links after OAuth redirect. */ +export async function handleOAuthCallback(rawUrl: string): Promise { + let url: URL + try { + url = new URL(rawUrl) + } catch { + return + } + + if (url.protocol !== `${APP_PROTOCOL}:` || url.host !== 'auth' || url.pathname !== '/callback') { + return + } + + const code = url.searchParams.get('code') + const state = url.searchParams.get('state') + const error = url.searchParams.get('error') + + if (!code && !error) return + + const envForEvent = pkceSession?.env ?? 'universe-testing' + + if (error) { + eventSender?.send('auth:state-changed', { env: envForEvent, status: 'error', error }) + return + } + + if (!code || !state || !pkceSession || state !== pkceSession.state) { + eventSender?.send('auth:state-changed', { + env: envForEvent, + status: 'error', + error: 'invalid_callback' + }) + return + } + + const { env, verifier } = pkceSession + pkceSession = null + + const kcBase = getKeycloakBase(env) + if (!kcBase) return + + try { + const tokens = await exchangeCode(kcBase, code, verifier) + storeTokens(env, tokens) + eventSender?.send('auth:state-changed', { + env, + status: 'connected', + user: extractUser(tokens) + }) + } catch (err) { + console.error('[Auth] Token exchange failed:', err) + eventSender?.send('auth:state-changed', { + env, + status: 'error', + error: 'token_exchange_failed' + }) + } +} + +/** Returns a fresh id_token suitable for game launch, refreshing if needed. */ +export async function loadFreshGameToken(env: Env): Promise { + const kcBase = getKeycloakBase(env) + const tokens = loadTokens(env) + if (!kcBase || !tokens) return null + + const refreshed = await refreshToken(kcBase, tokens.refresh_token) + if (!refreshed) { + clearStoredTokens(env) + return null + } + + const merged = mergeTokenSet(tokens, refreshed) + storeTokens(env, merged) + const launchToken = pickGameLaunchToken(merged) + if (!launchToken) { + console.error('[Auth] Invalid game token:', describeGameTokenIssue(merged)) + } + return launchToken +} + +/** Refreshes tokens and returns the user profile, or null when session is invalid. */ +export async function loadUserProfile(env: Env): Promise { + const kcBase = getKeycloakBase(env) + const tokens = loadTokens(env) + if (!kcBase || !tokens) return null + + const refreshed = await refreshToken(kcBase, tokens.refresh_token) + if (!refreshed) { + clearStoredTokens(env) + return null + } + + const merged = mergeTokenSet(tokens, refreshed) + storeTokens(env, merged) + return extractUser(merged) +} + +/** Clears local tokens and opens Keycloak logout in the browser. */ +export function logout(env: Env): void { + const kcBase = getKeycloakBase(env) + const tokens = loadTokens(env) + clearStoredTokens(env) + + if (kcBase && tokens?.id_token) { + const params = new URLSearchParams({ + client_id: AUTH_CLIENT_ID, + post_logout_redirect_uri: AUTH_REDIRECT_URI, + id_token_hint: tokens.id_token + }) + void shell.openExternal( + `${kcBase}/realms/${AUTH_REALM}/protocol/openid-connect/logout?${params}` + ) + } +} diff --git a/src/main/services/auth/handlers.ts b/src/main/services/auth/handlers.ts new file mode 100644 index 0000000..5573262 --- /dev/null +++ b/src/main/services/auth/handlers.ts @@ -0,0 +1,30 @@ +import { ipcMain, type BrowserWindow } from 'electron' +import type { Env } from '@shared/types/env' +import type { UserInfo } from '@shared/types/auth' +import { loadUserProfile, logout, setAuthEventSender, startLogin } from './flow' + +/** Registers IPC handlers for authentication (login, logout, load user). */ +export function registerAuthHandlers(win: BrowserWindow): void { + setAuthEventSender(win.webContents) + + ipcMain.handle('auth:login', async (_event, env: Env) => { + try { + await startLogin(env) + } catch (err) { + console.error('[Auth] Failed to open browser:', err) + win.webContents.send('auth:state-changed', { + env, + status: 'error', + error: 'browser_open_failed' + }) + } + }) + + ipcMain.handle('auth:logout', (_event, env: Env) => { + logout(env) + }) + + ipcMain.handle('auth:load-user', async (_event, env: Env): Promise => { + return loadUserProfile(env) + }) +} diff --git a/src/main/services/auth/index.ts b/src/main/services/auth/index.ts new file mode 100644 index 0000000..347962a --- /dev/null +++ b/src/main/services/auth/index.ts @@ -0,0 +1,3 @@ +export type { UserInfo } from '@shared/types/auth' +export { registerAuthHandlers } from './handlers' +export { handleOAuthCallback, loadFreshGameToken } from './flow' diff --git a/src/main/services/auth/jwt.ts b/src/main/services/auth/jwt.ts new file mode 100644 index 0000000..0ba957a --- /dev/null +++ b/src/main/services/auth/jwt.ts @@ -0,0 +1,88 @@ +import type { UserInfo } from '@shared/types/auth' +import type { TokenSet } from './types' + +const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i + +/** Decodes the payload segment of a JWT without verifying the signature. */ +export function decodeJwtPayload(token: string): Record { + const parts = token.split('.') + if (parts.length !== 3) throw new Error('Invalid JWT') + return JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8')) +} + +/** Returns the JWT `sub` claim or null. */ +export function getJwtSub(token: string): string | null { + try { + const sub = decodeJwtPayload(token)['sub'] + return typeof sub === 'string' && sub.length > 0 ? sub : null + } catch { + return null + } +} + +/** Returns true when `sub` is a valid player UUID. */ +export function isValidPlayerSub(sub: string): boolean { + return UUID_RE.test(sub) +} + +/** Returns true when the JWT is not expired. */ +export function isJwtNotExpired(token: string): boolean { + try { + const exp = decodeJwtPayload(token)['exp'] + if (typeof exp !== 'number') return false + return exp > Math.floor(Date.now() / 1000) + } catch { + return false + } +} + +/** Returns the JWT `preferred_username` claim or null. */ +export function getJwtPreferredUsername(token: string): string | null { + try { + const username = decodeJwtPayload(token)['preferred_username'] + return typeof username === 'string' && username.length > 0 ? username : null + } catch { + return null + } +} + +/** Returns true when the token satisfies game-launch requirements. */ +export function isValidGameLaunchToken(token: string): boolean { + const sub = getJwtSub(token) + return ( + sub !== null && + isValidPlayerSub(sub) && + getJwtPreferredUsername(token) !== null && + isJwtNotExpired(token) + ) +} + +/** Picks the id_token used to launch the game client. */ +export function pickGameLaunchToken(tokens: TokenSet): string | null { + const token = tokens.id_token + if (!token || !isValidGameLaunchToken(token)) return null + return token +} + +/** Maps token claims to the renderer user profile. */ +export function extractUser(tokens: TokenSet): UserInfo { + const p = decodeJwtPayload(tokens.id_token) + return { + sub: p['sub'] as string, + username: ((p['preferred_username'] ?? p['name']) as string | undefined) ?? 'Unknown', + email: (p['email'] as string | undefined) ?? '' + } +} + +/** Human-readable reason when a game token is rejected. */ +export function describeGameTokenIssue(tokens: TokenSet): string { + const token = tokens.id_token + if (!token) return 'id_token missing — sign in again' + if (!isJwtNotExpired(token)) return 'id_token expired — sign in again' + const sub = getJwtSub(token) + if (!sub || !isValidPlayerSub(sub)) return `invalid sub UUID (${sub ?? 'empty'})` + if (!getJwtPreferredUsername(token)) { + return 'preferred_username missing from id_token (check Keycloak / profile scope)' + } + return 'unknown reason' +} diff --git a/src/main/services/auth/keycloakClient.ts b/src/main/services/auth/keycloakClient.ts new file mode 100644 index 0000000..350ae37 --- /dev/null +++ b/src/main/services/auth/keycloakClient.ts @@ -0,0 +1,58 @@ +import { getApiBase, ENDPOINTS } from '../../config/api' +import { AUTH_CLIENT_ID, AUTH_REALM, AUTH_REDIRECT_URI, AUTH_SCOPES } from '../../config/auth' +import type { Env } from '@shared/types/env' +import type { TokenSet } from './types' +import { isValidGameLaunchToken } from './jwt' + +/** Resolves the Keycloak base URL for an environment, or null if API base is unset. */ +export function getKeycloakBase(env: Env): string | null { + const base = getApiBase(env) + if (!base) return null + return ENDPOINTS.authBase(base) +} + +/** Exchanges an authorization code for tokens (PKCE). */ +export async function exchangeCode( + kcBase: string, + code: string, + verifier: string +): Promise { + const res = await fetch(`${kcBase}/realms/${AUTH_REALM}/protocol/openid-connect/token`, { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: new URLSearchParams({ + grant_type: 'authorization_code', + client_id: AUTH_CLIENT_ID, + code, + redirect_uri: AUTH_REDIRECT_URI, + code_verifier: verifier + }).toString() + }) + if (!res.ok) throw new Error(`Token exchange failed (${res.status}): ${await res.text()}`) + return res.json() as Promise +} + +/** Refreshes tokens using a refresh_token grant. */ +export async function refreshToken(kcBase: string, token: string): Promise { + const res = await fetch(`${kcBase}/realms/${AUTH_REALM}/protocol/openid-connect/token`, { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: new URLSearchParams({ + grant_type: 'refresh_token', + client_id: AUTH_CLIENT_ID, + refresh_token: token, + scope: AUTH_SCOPES + }).toString() + }) + if (!res.ok) return null + return res.json() as Promise +} + +/** Merges refreshed tokens while preserving a valid id_token for game launch. */ +export function mergeTokenSet(previous: TokenSet, refreshed: TokenSet): TokenSet { + const idCandidates = [refreshed.id_token, previous.id_token].filter(Boolean) + const id_token = + idCandidates.find((t) => isValidGameLaunchToken(t)) ?? refreshed.id_token ?? previous.id_token + + return { ...previous, ...refreshed, id_token } +} diff --git a/src/main/services/auth/pkce.ts b/src/main/services/auth/pkce.ts new file mode 100644 index 0000000..102c844 --- /dev/null +++ b/src/main/services/auth/pkce.ts @@ -0,0 +1,13 @@ +import crypto from 'crypto' + +/** Generates a PKCE code verifier and S256 challenge pair. */ +export function generatePKCE(): { verifier: string; challenge: string } { + const verifier = crypto.randomBytes(32).toString('base64url') + const challenge = crypto.createHash('sha256').update(verifier).digest('base64url') + return { verifier, challenge } +} + +/** Generates a random OAuth state parameter. */ +export function generateState(): string { + return crypto.randomBytes(16).toString('base64url') +} diff --git a/src/main/services/auth/tokenStorage.ts b/src/main/services/auth/tokenStorage.ts new file mode 100644 index 0000000..c75371c --- /dev/null +++ b/src/main/services/auth/tokenStorage.ts @@ -0,0 +1,55 @@ +import { app, safeStorage } from 'electron' +import fs from 'fs' +import path from 'path' +import log from 'electron-log' +import type { Env } from '@shared/types/env' +import type { TokenSet } from './types' + +let loggedPlainFallback = false + +/** Returns the encrypted token file path for the given environment. */ +function getTokenPath(env: Env): string { + const filename = env === 'universe' ? 'tokens.enc' : `tokens-${env}.enc` + return path.join(app.getPath('userData'), filename) +} + +function logPlainFallbackOnce(): void { + if (loggedPlainFallback) return + loggedPlainFallback = true + log.info( + '[Auth] Token encryption unavailable on this system (common on Linux/WSL without a keyring). ' + + 'Tokens are stored as JSON in userData — use a supported OS keyring for encrypted storage.' + ) +} + +/** Encrypts and writes the token set to disk. */ +export function storeTokens(env: Env, tokens: TokenSet): void { + const json = JSON.stringify(tokens) + if (safeStorage.isEncryptionAvailable()) { + fs.writeFileSync(getTokenPath(env), safeStorage.encryptString(json)) + } else { + logPlainFallbackOnce() + fs.writeFileSync(getTokenPath(env), json, 'utf-8') + } +} + +/** Loads and decrypts the token set, or null if missing / corrupt. */ +export function loadTokens(env: Env): TokenSet | null { + const p = getTokenPath(env) + if (!fs.existsSync(p)) return null + try { + const buf = fs.readFileSync(p) + if (safeStorage.isEncryptionAvailable()) { + return JSON.parse(safeStorage.decryptString(buf)) as TokenSet + } + return JSON.parse(buf.toString('utf-8')) as TokenSet + } catch { + return null + } +} + +/** Deletes stored tokens for the environment. */ +export function clearStoredTokens(env: Env): void { + const p = getTokenPath(env) + if (fs.existsSync(p)) fs.unlinkSync(p) +} diff --git a/src/main/services/auth/types.ts b/src/main/services/auth/types.ts new file mode 100644 index 0000000..d0560a0 --- /dev/null +++ b/src/main/services/auth/types.ts @@ -0,0 +1,17 @@ +import type { Env } from '@shared/types/env' + +/** Token set persisted after OAuth code exchange or refresh. */ +export interface TokenSet { + access_token: string + refresh_token: string + id_token: string + expires_in: number + token_type: string +} + +/** In-memory PKCE session while the user completes login in the browser. */ +export interface PKCESession { + env: Env + verifier: string + state: string +} diff --git a/src/main/services/download/extract.ts b/src/main/services/download/extract.ts new file mode 100644 index 0000000..40b6789 --- /dev/null +++ b/src/main/services/download/extract.ts @@ -0,0 +1,26 @@ +import extract from 'extract-zip' +import type { BrowserWindow } from 'electron' +import { sendProgress } from './progress' + +/** Extracts the ZIP into `destPath` and reports extraction progress. */ +export async function extractZip( + zipFilePath: string, + destPath: string, + win: BrowserWindow +): Promise { + sendProgress(win, 70, { key: 'extracting', current: 0, total: 0 }) + + await extract(zipFilePath, { + dir: destPath, + onEntry: (_entry, zipFile) => { + if (zipFile.entryCount > 0) { + const pct = 70 + (zipFile.entriesRead / zipFile.entryCount) * 28 + sendProgress(win, pct, { + key: 'extracting', + current: zipFile.entriesRead, + total: zipFile.entryCount + }) + } + } + }) +} diff --git a/src/main/services/download/index.ts b/src/main/services/download/index.ts new file mode 100644 index 0000000..b23108c --- /dev/null +++ b/src/main/services/download/index.ts @@ -0,0 +1,2 @@ +export { downloadAndInstall } from './install' +export { resolveInstalledVersion } from './manifest' diff --git a/src/main/services/download/install.ts b/src/main/services/download/install.ts new file mode 100644 index 0000000..b62b232 --- /dev/null +++ b/src/main/services/download/install.ts @@ -0,0 +1,46 @@ +import * as fs from 'fs' +import * as path from 'path' +import type { BrowserWindow } from 'electron' +import { GAME_INSTALL_SUBDIR } from '../../config/constants' +import type { Env } from '@shared/types/env' +import type { InstallResult } from '@shared/types/install' +import { downloadZip } from './zipFetch' +import { extractZip } from './extract' +import { resolveInstalledVersion } from './manifest' +import { sendProgress } from './progress' + +/** Downloads the game ZIP, extracts it, and returns the installed version info. */ +export async function downloadAndInstall( + env: Env, + installPath: string, + win: BrowserWindow +): Promise { + if (!fs.existsSync(installPath)) { + fs.mkdirSync(installPath, { recursive: true }) + } + + let zipFilePath: string | null = null + try { + zipFilePath = await downloadZip(env, installPath, win) + + const gameRoot = path.join(installPath, GAME_INSTALL_SUBDIR) + sendProgress(win, 68, { key: 'preparing' }) + if (fs.existsSync(gameRoot)) { + fs.rmSync(gameRoot, { recursive: true, force: true }) + } + fs.mkdirSync(gameRoot, { recursive: true }) + + await extractZip(zipFilePath, gameRoot, win) + sendProgress(win, 99, { key: 'cleaning' }) + fs.unlinkSync(zipFilePath) + const manifest = await resolveInstalledVersion(env, gameRoot) + if (!manifest) { + throw new Error('Installation finished but version.json was not found in the game folder.') + } + sendProgress(win, 100, { key: 'completeInstall', version: manifest.version }) + return manifest + } catch (err) { + if (zipFilePath && fs.existsSync(zipFilePath)) fs.unlinkSync(zipFilePath) + throw err + } +} diff --git a/src/main/services/download/manifest.ts b/src/main/services/download/manifest.ts new file mode 100644 index 0000000..65fd184 --- /dev/null +++ b/src/main/services/download/manifest.ts @@ -0,0 +1,71 @@ +import * as fs from 'fs' +import * as path from 'path' +import { fetchRemoteGameVersion } from '../version' +import type { Env } from '@shared/types/env' +import type { InstallResult } from '@shared/types/install' + +/** Locates `version.json` at the game root or one subdirectory deep. */ +function findVersionManifestPath(gameRoot: string): string | null { + const direct = path.join(gameRoot, 'version.json') + try { + if (fs.existsSync(direct) && fs.statSync(direct).isFile()) return direct + } catch { + /* try nested */ + } + + try { + for (const entry of fs.readdirSync(gameRoot, { withFileTypes: true })) { + if (!entry.isDirectory()) continue + const nested = path.join(gameRoot, entry.name, 'version.json') + try { + if (fs.existsSync(nested) && fs.statSync(nested).isFile()) return nested + } catch { + /* continue */ + } + } + } catch { + return null + } + + return null +} + +/** Reads version metadata from the local `version.json` manifest, or null if missing. */ +function readVersionManifest(gameRoot: string): InstallResult | null { + const manifestPath = findVersionManifestPath(gameRoot) + if (!manifestPath) { + return null + } + try { + const json = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as { + version?: string + releaseDate?: string + } + return { + version: json.version ?? 'unknown', + releaseDate: json.releaseDate ?? new Date().toISOString().split('T')[0] + } + } catch { + return null + } +} + +/** + * Returns installed version aligned with remote `/version` when available. + * Returns null when no local `version.json` is found. + */ +export async function resolveInstalledVersion( + env: Env, + gameRoot: string +): Promise { + const fromFile = readVersionManifest(gameRoot) + if (!fromFile) return null + const fromApi = await fetchRemoteGameVersion(env) + if (fromApi?.version) { + return { + version: fromApi.version, + releaseDate: fromApi.releaseDate ?? fromFile.releaseDate + } + } + return fromFile +} diff --git a/src/main/services/download/progress.ts b/src/main/services/download/progress.ts new file mode 100644 index 0000000..c181961 --- /dev/null +++ b/src/main/services/download/progress.ts @@ -0,0 +1,12 @@ +import type { BrowserWindow } from 'electron' +import type { InstallProgressLabel } from '@shared/types/installProgress' + +/** Sends install/download progress to the renderer (0–100 and structured label key). */ +export function sendProgress( + win: BrowserWindow, + progress: number, + label: InstallProgressLabel +): void { + if (win.isDestroyed()) return + win.webContents.send('files:progress', Math.min(100, Math.round(progress)), label) +} diff --git a/src/main/services/download/zipFetch.ts b/src/main/services/download/zipFetch.ts new file mode 100644 index 0000000..45c19d0 --- /dev/null +++ b/src/main/services/download/zipFetch.ts @@ -0,0 +1,115 @@ +import axios from 'axios' +import * as fs from 'fs' +import * as path from 'path' +import type { BrowserWindow } from 'electron' +import { + DOWNLOAD_PROGRESS, + DOWNLOAD_USER_AGENT, + GAME_DOWNLOAD_ZIP_NAME, + HTTP_TIMEOUT_MS +} from '../../config/constants' +import type { Env } from '@shared/types/env' +import { getZipUrl } from './zipUrl' +import { sendProgress } from './progress' + +const ZIP_MAGIC = Buffer.from([0x50, 0x4b, 0x03, 0x04]) + +/** Verifies the downloaded file starts with a ZIP local file header. */ +export function assertIsZipFile(filePath: string, sourceUrl: string): void { + let fd: number + try { + fd = fs.openSync(filePath, 'r') + } catch { + throw new Error(`Cannot read downloaded file — ${sourceUrl}`) + } + try { + const head = Buffer.alloc(4) + const read = fs.readSync(fd, head, 0, 4, 0) + if (read < 4 || !head.subarray(0, 4).equals(ZIP_MAGIC)) { + throw new Error( + `Received file is not a ZIP archive (often an HTML error page, e.g. HTTP 404). Check URL: ${sourceUrl}` + ) + } + } finally { + try { + fs.closeSync(fd) + } catch { + /* ignore */ + } + } +} + +/** Streams the game ZIP to disk and reports progress to the renderer. */ +export async function downloadZip(env: Env, destPath: string, win: BrowserWindow): Promise { + sendProgress(win, 0, { key: 'connecting' }) + + const url = getZipUrl(env) + + let response: Awaited>> + try { + response = await axios.get(url, { + responseType: 'stream', + timeout: HTTP_TIMEOUT_MS.download, + headers: { + 'User-Agent': DOWNLOAD_USER_AGENT, + Accept: 'application/zip, application/octet-stream, */*' + }, + validateStatus: (s) => s >= 200 && s < 300 + }) + } catch (err) { + if (axios.isAxiosError(err)) { + const code = err.response?.status + const hint = + code === 404 + ? ' — archive not found (404). Set VITE_GAME_DOWNLOAD_BASE_* if ZIPs are hosted elsewhere.' + : '' + throw new Error(`Download failed${code ? ` (HTTP ${code})` : ''}${hint}\n${url}`) + } + throw err + } + + if (response.status !== 200) { + throw new Error(`Download rejected (HTTP ${response.status})\n${url}`) + } + + const totalLength = Number(response.headers['content-length'] ?? 0) + let downloaded = 0 + let lastProgressReport = 0 + + const zipFilePath = path.join(destPath, GAME_DOWNLOAD_ZIP_NAME) + const writer = fs.createWriteStream(zipFilePath) + + await new Promise((resolve, reject) => { + const stream = response.data + stream.on('error', reject) + writer.on('error', reject) + writer.on('finish', () => resolve()) + + stream.on('data', (chunk: Buffer) => { + downloaded += chunk.length + if (!writer.write(chunk)) { + stream.pause() + writer.once('drain', () => stream.resume()) + } + if (totalLength > 0) { + sendProgress(win, (downloaded / totalLength) * DOWNLOAD_PROGRESS.zipWeight, { + key: 'downloading', + downloaded, + total: totalLength + }) + } else if (downloaded - lastProgressReport >= DOWNLOAD_PROGRESS.unknownChunkBytes) { + lastProgressReport = downloaded + sendProgress( + win, + Math.min(65, 15 + (downloaded / DOWNLOAD_PROGRESS.unknownSizeCapBytes) * 50), + { key: 'downloadingIndeterminate', downloaded } + ) + } + }) + + stream.on('end', () => writer.end()) + }) + + assertIsZipFile(zipFilePath, url) + return zipFilePath +} diff --git a/src/main/services/download/zipUrl.ts b/src/main/services/download/zipUrl.ts new file mode 100644 index 0000000..da6242e --- /dev/null +++ b/src/main/services/download/zipUrl.ts @@ -0,0 +1,30 @@ +import { + ENDPOINTS, + getDownloadBase, + getTestingZipUrlForPlatform, + getUniverseZipUrlForPlatform +} from '../../config/api' +import type { Env } from '@shared/types/env' + +/** Resolves the ZIP download URL for the current platform and environment. */ +export function getZipUrl(env: Env): string { + const platform = process.platform + + if (env === 'universe') { + const direct = getUniverseZipUrlForPlatform(platform) + if (direct) return direct + } + + if (env === 'universe-testing') { + const direct = getTestingZipUrlForPlatform(platform) + if (direct) return direct + } + + const base = getDownloadBase(env) + if (!base) throw new Error(`Env "${env}" is not configured — missing base URL.`) + + if (platform === 'win32') return ENDPOINTS.zipWin32(base) + if (platform === 'linux') return ENDPOINTS.zipLinux(base) + if (platform === 'darwin') return ENDPOINTS.zipDarwin(base) + throw new Error(`Unsupported platform: ${platform}`) +} diff --git a/src/main/services/downloader.ts b/src/main/services/downloader.ts deleted file mode 100644 index 34348ea..0000000 --- a/src/main/services/downloader.ts +++ /dev/null @@ -1,269 +0,0 @@ -import { BrowserWindow } from 'electron' -import axios from 'axios' -import * as fs from 'fs' -import * as path from 'path' -import extract from 'extract-zip' -import { - getDownloadBase, - getUniverseZipUrlForPlatform, - getTestingZipUrlForPlatform, - ENDPOINTS -} from '../config/env' -import { fetchRemoteGameVersion } from './version' -import type { Env } from '../../renderer/store/env' - -/** Sous-dossier d’installation du payload du jeu (ZIP extrait ici, pas à la racine du chemin choisi). */ -export const GAME_INSTALL_SUBDIR = 'DyingStar' - -// ─── Types ──────────────────────────────────────────────────────────────────── - -export interface InstallResult { - version: string - releaseDate: string -} - -// ─── Helpers ────────────────────────────────────────────────────────────────── - -function getZipUrl(env: Env): string { - const platform = process.platform - - if (env === 'universe') { - const direct = getUniverseZipUrlForPlatform(platform) - if (direct) return direct - } - - if (env === 'universe-testing') { - const direct = getTestingZipUrlForPlatform(platform) - if (direct) return direct - } - - const base = getDownloadBase(env) - if (!base) throw new Error(`Env "${env}" non configuré — URL de base manquante.`) - - if (platform === 'win32') return ENDPOINTS.zipWin32(base) - if (platform === 'linux') return ENDPOINTS.zipLinux(base) - if (platform === 'darwin') return ENDPOINTS.zipDarwin(base) - throw new Error(`Plateforme non supportée : ${platform}`) -} - -const ZIP_MAGIC = Buffer.from([0x50, 0x4b, 0x03, 0x04]) - -function assertIsZipFile(filePath: string, sourceUrl: string): void { - let fd: number - try { - fd = fs.openSync(filePath, 'r') - } catch { - throw new Error(`Impossible de lire le fichier téléchargé — ${sourceUrl}`) - } - try { - const head = Buffer.alloc(4) - const read = fs.readSync(fd, head, 0, 4, 0) - if (read < 4 || !head.subarray(0, 4).equals(ZIP_MAGIC)) { - throw new Error( - `Le fichier reçu n’est pas une archive ZIP (souvent une page d’erreur HTML, ex. HTTP 404). Vérifiez l’URL : ${sourceUrl}` - ) - } - } finally { - try { - fs.closeSync(fd) - } catch { - /* ignore */ - } - } -} - -function sendProgress(win: BrowserWindow, progress: number, label: string): void { - if (win.isDestroyed()) return - win.webContents.send('files:progress', Math.min(100, Math.round(progress)), label) -} - -// ─── Téléchargement ─────────────────────────────────────────────────────────── - -async function downloadZip(env: Env, destPath: string, win: BrowserWindow): Promise { - sendProgress(win, 0, 'Connexion au serveur...') - - const url = getZipUrl(env) - - let response: Awaited>> - try { - response = await axios.get(url, { - responseType: 'stream', - timeout: 600_000, - headers: { - 'User-Agent': 'DyingStar-Launcher/1.0', - Accept: 'application/zip, application/octet-stream, */*' - }, - validateStatus: (s) => s >= 200 && s < 300 - }) - } catch (err) { - if (axios.isAxiosError(err)) { - const code = err.response?.status - const hint = - code === 404 - ? ` — l’archive n’existe pas à cet emplacement (404). Définissez VITE_GAME_DOWNLOAD_BASE_* si les ZIP sont sur un autre hôte.` - : '' - throw new Error(`Téléchargement impossible${code ? ` (HTTP ${code})` : ''}${hint}\n${url}`) - } - throw err - } - - if (response.status !== 200) { - throw new Error(`Téléchargement refusé (HTTP ${response.status})\n${url}`) - } - - const totalLength = Number(response.headers['content-length'] ?? 0) - let downloaded = 0 - let lastProgressReport = 0 - - const zipFilePath = path.join(destPath, '__game_download.zip') - const writer = fs.createWriteStream(zipFilePath) - - await new Promise((resolve, reject) => { - const stream = response.data - stream.on('error', reject) - writer.on('error', reject) - writer.on('finish', () => resolve()) - - stream.on('data', (chunk: Buffer) => { - downloaded += chunk.length - if (!writer.write(chunk)) { - stream.pause() - writer.once('drain', () => stream.resume()) - } - if (totalLength > 0) { - sendProgress( - win, - (downloaded / totalLength) * 70, - `Téléchargement... (${formatBytes(downloaded)} / ${formatBytes(totalLength)})` - ) - } else if (downloaded - lastProgressReport >= 2 * 1024 * 1024) { - lastProgressReport = downloaded - sendProgress(win, Math.min(65, 15 + downloaded / (80 * 1024 * 1024) * 50), - `Téléchargement... (${formatBytes(downloaded)})`) - } - }) - - stream.on('end', () => writer.end()) - }) - - assertIsZipFile(zipFilePath, url) - - return zipFilePath -} - -// ─── Extraction ─────────────────────────────────────────────────────────────── - -async function extractZip(zipFilePath: string, destPath: string, win: BrowserWindow): Promise { - sendProgress(win, 70, 'Extraction des fichiers...') - - await extract(zipFilePath, { - dir: destPath, - onEntry: (_entry, zipFile) => { - if (zipFile.entryCount > 0) { - const pct = 70 + (zipFile.entriesRead / zipFile.entryCount) * 28 - sendProgress(win, pct, `Extraction... (${zipFile.entriesRead} / ${zipFile.entryCount} fichiers)`) - } - } - }) -} - -// ─── Lecture version.json ───────────────────────────────────────────────────── - -function findVersionManifestPath(gameRoot: string): string | null { - const direct = path.join(gameRoot, 'version.json') - try { - if (fs.existsSync(direct) && fs.statSync(direct).isFile()) return direct - } catch { - /* continue */ - } - - try { - for (const entry of fs.readdirSync(gameRoot, { withFileTypes: true })) { - if (!entry.isDirectory()) continue - const nested = path.join(gameRoot, entry.name, 'version.json') - try { - if (fs.existsSync(nested) && fs.statSync(nested).isFile()) return nested - } catch { - /* continue */ - } - } - } catch { - return null - } - - return null -} - -function readVersionManifest(gameRoot: string): InstallResult { - const manifestPath = findVersionManifestPath(gameRoot) - if (!manifestPath) { - console.warn('[Downloader] version.json introuvable sous', gameRoot) - return { version: 'unknown', releaseDate: new Date().toISOString().split('T')[0] } - } - try { - const json = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as { - version?: string; releaseDate?: string - } - return { - version: json.version ?? 'unknown', - releaseDate: json.releaseDate ?? new Date().toISOString().split('T')[0] - } - } catch { - return { version: 'unknown', releaseDate: new Date().toISOString().split('T')[0] } - } -} - -/** Version locale alignée sur l’API /version (référence du bandeau « mise à jour »). */ -export async function resolveInstalledVersion(env: Env, gameRoot: string): Promise { - const fromFile = readVersionManifest(gameRoot) - const fromApi = await fetchRemoteGameVersion(env) - if (fromApi?.version) { - return { - version: fromApi.version, - releaseDate: fromApi.releaseDate ?? fromFile.releaseDate - } - } - return fromFile -} - -// ─── Point d'entrée ─────────────────────────────────────────────────────────── - -export async function downloadAndInstall( - env: Env, - installPath: string, - win: BrowserWindow -): Promise { - if (!fs.existsSync(installPath)) { - fs.mkdirSync(installPath, { recursive: true }) - } - - let zipFilePath: string | null = null - try { - zipFilePath = await downloadZip(env, installPath, win) - - const gameRoot = path.join(installPath, GAME_INSTALL_SUBDIR) - sendProgress(win, 68, 'Préparation du dossier du jeu...') - if (fs.existsSync(gameRoot)) { - fs.rmSync(gameRoot, { recursive: true, force: true }) - } - fs.mkdirSync(gameRoot, { recursive: true }) - - await extractZip(zipFilePath, gameRoot, win) - sendProgress(win, 99, 'Nettoyage...') - fs.unlinkSync(zipFilePath) - const manifest = await resolveInstalledVersion(env, gameRoot) - sendProgress(win, 100, `Installation terminée — v${manifest.version}`) - return manifest - } catch (err) { - if (zipFilePath && fs.existsSync(zipFilePath)) fs.unlinkSync(zipFilePath) - throw err - } -} - -// ─── Utilitaires ────────────────────────────────────────────────────────────── - -function formatBytes(bytes: number): string { - if (bytes < 1024) return `${bytes} o` - if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} Ko` - return `${(bytes / (1024 * 1024)).toFixed(1)} Mo` -} \ No newline at end of file diff --git a/src/main/services/game.ts b/src/main/services/game.ts deleted file mode 100644 index e53fd4d..0000000 --- a/src/main/services/game.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { ipcMain, dialog, BrowserWindow } from 'electron' -import { spawn, type ChildProcess } from 'child_process' -import * as path from 'path' -import * as fs from 'fs' -import { downloadAndInstall, GAME_INSTALL_SUBDIR, resolveInstalledVersion } from './downloader' -import { loadFreshGameToken } from './auth' -import { clearDyingStarGodotCaches } from './godotUserdataCache' -import type { Env } from '../../renderer/store/env' - -// ─── Types ──────────────────────────────────────────────────────────────────── - -interface GameState { - installedVersion: string | null - availableVersion: string | null - releaseDate: string | null - status: 'not-installed' | 'up-to-date' | 'update-available' | 'checking' -} - -// ─── Exécutables par OS ─────────────────────────────────────────────────────── - -const GAME_EXECUTABLES: Partial> = { - win32: 'DyingStar.exe', - linux: 'DyingStar.x86_64', - darwin: 'DyingStar.app' -} - -function getGameRoot(installPath: string): string { - return path.join(installPath, GAME_INSTALL_SUBDIR) -} - -function getExecutablePath(installPath: string): string { - const exe = GAME_EXECUTABLES[process.platform] - if (!exe) throw new Error(`Plateforme non supportée : ${process.platform}`) - const inPayload = path.join(getGameRoot(installPath), exe) - if (fs.existsSync(inPayload)) return inPayload - const legacy = path.join(installPath, exe) - if (fs.existsSync(legacy)) return legacy - return inPayload -} - -/** Cherche CHANGELOG.md à la racine de `root` ou dans un seul niveau de sous-dossier (ZIP avec dossier racine). */ -function findChangelogUnderRoot(root: string): string | null { - const direct = path.join(root, 'CHANGELOG.md') - try { - if (fs.existsSync(direct) && fs.statSync(direct).isFile()) return direct - } catch { - /* continue */ - } - try { - const entries = fs.readdirSync(root, { withFileTypes: true }) - for (const e of entries) { - if (!e.isDirectory()) continue - const nested = path.join(root, e.name, 'CHANGELOG.md') - try { - if (fs.existsSync(nested) && fs.statSync(nested).isFile()) return nested - } catch { - /* continue */ - } - } - } catch { - return null - } - return null -} - -/** - * CHANGELOG : si le jeu est sous `…/DyingStar/`, on ne lit que là (pas un ancien fichier à la racine install). - * Sinon installation legacy → racine `installPath`. - */ -function findChangelogPath(installPath: string): string | null { - const resolved = path.resolve(installPath) - const gameRoot = getGameRoot(resolved) - try { - if (fs.existsSync(gameRoot) && fs.statSync(gameRoot).isDirectory()) { - return findChangelogUnderRoot(gameRoot) - } - } catch { - /* fallback legacy */ - } - return findChangelogUnderRoot(resolved) -} - -// ─── Suivi du processus jeu ─────────────────────────────────────────────────── - -let launcherWindow: BrowserWindow | null = null -let trackedGamePid: number | null = null -let gamePollTimer: ReturnType | null = null - -function isPidAlive(pid: number): boolean { - try { - process.kill(pid, 0) - return true - } catch { - return false - } -} - -function notifyGameRunning(running: boolean): void { - if (!launcherWindow || launcherWindow.isDestroyed()) return - launcherWindow.webContents.send('game:running-changed', { running }) -} - -function clearGameWatch(): void { - if (gamePollTimer) { - clearInterval(gamePollTimer) - gamePollTimer = null - } - trackedGamePid = null -} - -function stopGameWatchIfExited(): void { - if (trackedGamePid === null) return - if (!isPidAlive(trackedGamePid)) { - clearGameWatch() - notifyGameRunning(false) - } -} - -function watchGameProcess(child: ChildProcess): void { - clearGameWatch() - const pid = child.pid - if (!pid) return - - trackedGamePid = pid - notifyGameRunning(true) - - const onDone = (): void => { - if (trackedGamePid !== pid) return - clearGameWatch() - notifyGameRunning(false) - } - - child.once('exit', onDone) - child.once('error', onDone) - - gamePollTimer = setInterval(stopGameWatchIfExited, 2000) -} - -function isGameRunning(): boolean { - return trackedGamePid !== null && isPidAlive(trackedGamePid) -} - -// ─── Handlers IPC ───────────────────────────────────────────────────────────── - -export function registerFilesHandlers(win: BrowserWindow): void { - launcherWindow = win - - // ── Sélection du répertoire d'installation ───────────────────────────────── - ipcMain.removeHandler('files:select-directory') - ipcMain.handle('files:select-directory', async () => { - const result = await dialog.showOpenDialog(win, { - title: "Répertoire d'installation", - buttonLabel: 'Choisir ce dossier', - properties: ['openDirectory', 'createDirectory'] - }) - if (result.canceled || result.filePaths.length === 0) return null - return result.filePaths[0] - }) - - // ── Téléchargement + installation → retourne { version, releaseDate } ────── - ipcMain.removeHandler('files:install') - ipcMain.handle('files:install', async (_event, env: Env, installPath: string) => { - if (!installPath || typeof installPath !== 'string') { - throw new Error("Chemin d'installation invalide.") - } - // Le résultat InstallResult est sérialisé et renvoyé au renderer - return await downloadAndInstall(env, installPath, win) - }) - - // ── Lancement du jeu ─────────────────────────────────────────────────────── - ipcMain.removeHandler('game:launch') - ipcMain.removeHandler('game:is-running') - ipcMain.removeHandler('files:clear-godot-cache') - ipcMain.handle('files:clear-godot-cache', async () => clearDyingStarGodotCaches()) - - ipcMain.removeHandler('files:read-changelog') - ipcMain.removeHandler('files:resolve-installed-version') - ipcMain.handle('files:read-changelog', async (_event, installPath: string): Promise => { - if (!installPath || typeof installPath !== 'string') return null - const root = path.resolve(installPath) - const changelogFile = findChangelogPath(root) - if (!changelogFile) return null - try { - return fs.readFileSync(changelogFile, 'utf-8') - } catch { - return null - } - }) - - ipcMain.handle( - 'files:resolve-installed-version', - async (_event, env: Env, installPath: string): Promise<{ version: string; releaseDate: string } | null> => { - if (!installPath || typeof installPath !== 'string') return null - const gameRoot = getGameRoot(path.resolve(installPath)) - if (!fs.existsSync(gameRoot)) return null - return resolveInstalledVersion(env, gameRoot) - } - ) - - ipcMain.handle('game:launch', async (_event, env: Env, installPath: string) => { - if (isGameRunning()) { - throw new Error('Le jeu est déjà en cours d\'exécution.') - } - - const token = await loadFreshGameToken(env) - if (!token) { - throw new Error( - 'Session invalide ou jeton incomplet (identifiant ou pseudo manquant). Reconnectez-vous puis réessayez.' - ) - } - - const exePath = getExecutablePath(installPath) - if (!fs.existsSync(exePath)) { - throw new Error(`Exécutable introuvable : ${exePath}`) - } - if (process.platform === 'linux') fs.chmodSync(exePath, 0o755) - - const gameRoot = getGameRoot(installPath) - const cwd = fs.existsSync(gameRoot) ? gameRoot : installPath - - // Le client Godot ne lit que `--token=` (un seul argument avec '='). - // Voir DyingStar/server/client.gd (branche develop). - const child = spawn(exePath, [`--token=${token}`], { - detached: true, - stdio: 'ignore', - cwd - }) - watchGameProcess(child) - child.unref() - }) - - ipcMain.handle('game:is-running', () => isGameRunning()) - - // ── État du jeu ──────────────────────────────────────────────────────────── - ipcMain.removeHandler('game:get-state') - ipcMain.handle('game:get-state', async (_event, _env: Env): Promise => { - // TODO: lire version locale + interroger serveur - return { - installedVersion: null, - availableVersion: '1.0.0', - releaseDate: '2026-01-01', - status: 'not-installed' - } - }) -} \ No newline at end of file diff --git a/src/main/services/game/handlers.ts b/src/main/services/game/handlers.ts new file mode 100644 index 0000000..cca01f5 --- /dev/null +++ b/src/main/services/game/handlers.ts @@ -0,0 +1,80 @@ +import { dialog, ipcMain, type BrowserWindow } from 'electron' +import * as fs from 'fs' +import * as path from 'path' +import { downloadAndInstall } from '../download' +import { resolveInstalledVersion } from '../download/manifest' +import { clearDyingStarGodotCaches } from '../godotUserdataCache' +import type { Env } from '@shared/types/env' +import { findChangelogPath, getGameRoot, isGameInstalledAtPath } from './paths' +import { launchGame } from './launch' +import { isGameRunning, setLauncherWindow } from './processWatch' +import { getInstallDialogStrings } from '../../l10n/dialogs' + +/** Registers IPC handlers for install paths, changelog, cache, and game launch. */ +export function registerFilesHandlers(win: BrowserWindow): void { + setLauncherWindow(win) + + ipcMain.removeHandler('files:select-directory') + ipcMain.handle('files:select-directory', async () => { + const dialogStrings = getInstallDialogStrings() + const result = await dialog.showOpenDialog(win, { + title: dialogStrings.selectDirectoryTitle, + buttonLabel: dialogStrings.selectDirectoryButton, + properties: ['openDirectory', 'createDirectory'] + }) + if (result.canceled || result.filePaths.length === 0) return null + return result.filePaths[0] + }) + + ipcMain.removeHandler('files:install') + ipcMain.handle('files:install', async (_event, env: Env, installPath: string) => { + if (!installPath || typeof installPath !== 'string') { + throw new Error('Invalid installation path.') + } + return downloadAndInstall(env, installPath, win) + }) + + ipcMain.removeHandler('game:launch') + ipcMain.removeHandler('game:is-running') + ipcMain.removeHandler('files:clear-godot-cache') + ipcMain.handle('files:clear-godot-cache', async () => clearDyingStarGodotCaches()) + + ipcMain.removeHandler('files:read-changelog') + ipcMain.removeHandler('files:resolve-installed-version') + + ipcMain.handle( + 'files:read-changelog', + async (_event, installPath: string): Promise => { + if (!installPath || typeof installPath !== 'string') return null + const changelogFile = findChangelogPath(path.resolve(installPath)) + if (!changelogFile) return null + try { + return fs.readFileSync(changelogFile, 'utf-8') + } catch { + return null + } + } + ) + + ipcMain.handle( + 'files:resolve-installed-version', + async ( + _event, + env: Env, + installPath: string + ): Promise<{ version: string; releaseDate: string } | null> => { + if (!installPath || typeof installPath !== 'string') return null + const resolvedPath = path.resolve(installPath) + if (!isGameInstalledAtPath(resolvedPath)) return null + const gameRoot = getGameRoot(resolvedPath) + if (!fs.existsSync(gameRoot)) return null + return resolveInstalledVersion(env, gameRoot) + } + ) + + ipcMain.handle('game:launch', async (_event, env: Env, installPath: string) => { + await launchGame(installPath, env) + }) + + ipcMain.handle('game:is-running', () => isGameRunning()) +} diff --git a/src/main/services/game/index.ts b/src/main/services/game/index.ts new file mode 100644 index 0000000..ecfb20c --- /dev/null +++ b/src/main/services/game/index.ts @@ -0,0 +1,2 @@ +export { registerFilesHandlers } from './handlers' +export { GAME_INSTALL_SUBDIR } from './paths' diff --git a/src/main/services/game/launch.ts b/src/main/services/game/launch.ts new file mode 100644 index 0000000..0d3fe99 --- /dev/null +++ b/src/main/services/game/launch.ts @@ -0,0 +1,39 @@ +import { spawn } from 'child_process' +import * as fs from 'fs' +import { loadFreshGameToken } from '../auth' +import { getExecutablePath, getGameRoot } from './paths' +import { isGameRunning, watchGameProcess } from './processWatch' + +/** Spawns the game executable with a fresh JWT (`--token=`). */ +export async function launchGame( + installPath: string, + env: Parameters[0] +): Promise { + if (isGameRunning()) { + throw new Error('Game is already running.') + } + + const token = await loadFreshGameToken(env) + if (!token) { + throw new Error( + 'Invalid session or incomplete token (missing id or username). Sign in again and retry.' + ) + } + + const exePath = getExecutablePath(installPath) + if (!fs.existsSync(exePath)) { + throw new Error(`Executable not found: ${exePath}`) + } + if (process.platform === 'linux') fs.chmodSync(exePath, 0o755) + + const gameRoot = getGameRoot(installPath) + const cwd = fs.existsSync(gameRoot) ? gameRoot : installPath + + const child = spawn(exePath, [`--token=${token}`], { + detached: true, + stdio: 'ignore', + cwd + }) + watchGameProcess(child) + child.unref() +} diff --git a/src/main/services/game/paths.ts b/src/main/services/game/paths.ts new file mode 100644 index 0000000..20c71d8 --- /dev/null +++ b/src/main/services/game/paths.ts @@ -0,0 +1,71 @@ +import * as fs from 'fs' +import * as path from 'path' +import { GAME_EXECUTABLES, GAME_INSTALL_SUBDIR } from '../../config/constants' + +export { GAME_INSTALL_SUBDIR } + +/** Returns the game payload directory inside the user install path. */ +export function getGameRoot(installPath: string): string { + return path.join(installPath, GAME_INSTALL_SUBDIR) +} + +/** True when the platform executable (or legacy layout) is present on disk. */ +export function isGameInstalledAtPath(installPath: string): boolean { + if (!installPath?.trim()) return false + try { + return fs.existsSync(getExecutablePath(path.resolve(installPath))) + } catch { + return false + } +} + +/** Resolves the platform game executable (payload dir first, then legacy install root). */ +export function getExecutablePath(installPath: string): string { + const exe = GAME_EXECUTABLES[process.platform] + if (!exe) throw new Error(`Unsupported platform: ${process.platform}`) + const inPayload = path.join(getGameRoot(installPath), exe) + if (fs.existsSync(inPayload)) return inPayload + const legacy = path.join(installPath, exe) + if (fs.existsSync(legacy)) return legacy + return inPayload +} + +/** Finds CHANGELOG.md at the root or one level below `root`. */ +function findChangelogUnderRoot(root: string): string | null { + const direct = path.join(root, 'CHANGELOG.md') + try { + if (fs.existsSync(direct) && fs.statSync(direct).isFile()) return direct + } catch { + /* try subdirectories */ + } + try { + for (const e of fs.readdirSync(root, { withFileTypes: true })) { + if (!e.isDirectory()) continue + const nested = path.join(root, e.name, 'CHANGELOG.md') + try { + if (fs.existsSync(nested) && fs.statSync(nested).isFile()) return nested + } catch { + /* continue */ + } + } + } catch { + return null + } + return null +} + +/** + * Resolves CHANGELOG path: prefers `installPath/DyingStar/`, falls back to legacy layout. + */ +export function findChangelogPath(installPath: string): string | null { + const resolved = path.resolve(installPath) + const gameRoot = getGameRoot(resolved) + try { + if (fs.existsSync(gameRoot) && fs.statSync(gameRoot).isDirectory()) { + return findChangelogUnderRoot(gameRoot) + } + } catch { + /* legacy layout */ + } + return findChangelogUnderRoot(resolved) +} diff --git a/src/main/services/game/processWatch.ts b/src/main/services/game/processWatch.ts new file mode 100644 index 0000000..502e209 --- /dev/null +++ b/src/main/services/game/processWatch.ts @@ -0,0 +1,71 @@ +import type { BrowserWindow } from 'electron' +import type { ChildProcess } from 'child_process' +import { GAME_PROCESS_POLL_MS } from '../../config/constants' + +let launcherWindow: BrowserWindow | null = null +let trackedGamePid: number | null = null +let gamePollTimer: ReturnType | null = null + +/** Binds the window that receives `game:running-changed` events. */ +export function setLauncherWindow(win: BrowserWindow): void { + launcherWindow = win +} + +/** Returns true when a game process launched by the launcher is still alive. */ +export function isGameRunning(): boolean { + return trackedGamePid !== null && isPidAlive(trackedGamePid) +} + +/** Sends running state to the renderer. */ +function notifyGameRunning(running: boolean): void { + if (!launcherWindow || launcherWindow.isDestroyed()) return + launcherWindow.webContents.send('game:running-changed', { running }) +} + +/** Returns true if sending signal 0 to the pid does not throw (process exists). */ +function isPidAlive(pid: number): boolean { + try { + process.kill(pid, 0) + return true + } catch { + return false + } +} + +/** Stops polling and clears the tracked game PID. */ +function clearGameWatch(): void { + if (gamePollTimer) { + clearInterval(gamePollTimer) + gamePollTimer = null + } + trackedGamePid = null +} + +/** Poll callback: clears watch and notifies renderer when the game process exited. */ +function stopGameWatchIfExited(): void { + if (trackedGamePid === null) return + if (!isPidAlive(trackedGamePid)) { + clearGameWatch() + notifyGameRunning(false) + } +} + +/** Tracks a detached game child process until it exits. */ +export function watchGameProcess(child: ChildProcess): void { + clearGameWatch() + const pid = child.pid + if (!pid) return + + trackedGamePid = pid + notifyGameRunning(true) + + const onDone = (): void => { + if (trackedGamePid !== pid) return + clearGameWatch() + notifyGameRunning(false) + } + + child.once('exit', onDone) + child.once('error', onDone) + gamePollTimer = setInterval(stopGameWatchIfExited, GAME_PROCESS_POLL_MS) +} diff --git a/src/main/services/gameStatus.ts b/src/main/services/gameStatus.ts index 4eaa342..2a8e5ba 100644 --- a/src/main/services/gameStatus.ts +++ b/src/main/services/gameStatus.ts @@ -1,21 +1,11 @@ import { ipcMain } from 'electron' -import { getApiBase, ENDPOINTS, getStatusComponentId, getStatusMetricId } from '../config/env' -import type { Env } from '../../renderer/store/env' +import { getApiBase, ENDPOINTS, getStatusComponentId, getStatusMetricId } from '../config/api' +import { HTTP_TIMEOUT_MS } from '../config/constants' +import type { Env } from '@shared/types/env' +import type { GameStatusResult, ServerStatusValue } from '@shared/types/game' -// ─── Types ──────────────────────────────────────────────────────────────────── +export type { GameStatusResult, ServerStatusValue } from '@shared/types/game' -export type ServerStatusValue = 'online' | 'degraded' | 'offline' | 'maintenance' | 'unknown' | 'unavailable' - -export interface GameStatusResult { - status: ServerStatusValue - statusLabel: string // label brut de l'API (pour debug/log) - players: number - available: boolean // false si l'env n'est pas configuré -} - -// Mapping value → type interne -// 1: Operational, 2: Performance Issues, 3: Partial Outage, -// 4: Major Outage, 5: Unknown, 6: Under Maintenance const STATUS_MAP: Record = { 1: 'online', 2: 'degraded', @@ -25,15 +15,15 @@ const STATUS_MAP: Record = { 6: 'maintenance' } -// ─── Fetch helpers ──────────────────────────────────────────────────────────── - -async function fetchWithTimeout(url: string, timeoutMs = 8_000): Promise { +/** Performs a fetch with an abort timeout. */ +async function fetchWithTimeout(url: string, timeoutMs = HTTP_TIMEOUT_MS.api): Promise { return fetch(url, { signal: AbortSignal.timeout(timeoutMs), - headers: { 'Cache-Control': 'no-cache', 'Accept': 'application/json' } + headers: { 'Cache-Control': 'no-cache', Accept: 'application/json' } }) } +/** Parses Cachet component status JSON into a numeric value and label. */ function parseCachetComponentStatus(json: unknown): { value: number | undefined; label: string } { if (!json || typeof json !== 'object') return { value: undefined, label: 'invalid_json' } const root = json as Record @@ -50,6 +40,7 @@ function parseCachetComponentStatus(json: unknown): { value: number | undefined; } } +/** Fetches server operational status from the status API. */ async function fetchStatus( apiBase: string, componentId: number @@ -63,22 +54,23 @@ async function fetchStatus( const { value, label } = parseCachetComponentStatus(json) if (value === undefined) { - console.warn('[GameStatus] Statut composant illisible', { url, label }) + console.warn('[GameStatus] Unreadable component status', { url, label }) return { status: 'unknown', label: label || 'parse_error' } } const mapped = STATUS_MAP[value] if (!mapped) { - console.warn('[GameStatus] Valeur status inconnue', { url, value, label }) + console.warn('[GameStatus] Unknown status value', { url, value, label }) return { status: 'unknown', label } } return { status: mapped, label } } catch (err) { - console.warn('[GameStatus] fetch status échoué', err) + console.warn('[GameStatus] Status fetch failed', err) return { status: 'unknown', label: 'fetch_error' } } } +/** Parses connected player count from Cachet metrics API response. */ function parseMetricPoints(json: unknown): number { if (!json || typeof json !== 'object') return 0 const root = json as { data?: unknown } @@ -91,6 +83,7 @@ function parseMetricPoints(json: unknown): number { return Number.isFinite(n) ? n : 0 } +/** Fetches the current player count metric. */ async function fetchPlayers(apiBase: string, metricId: number): Promise { try { const url = ENDPOINTS.metrics(apiBase, metricId) @@ -100,27 +93,23 @@ async function fetchPlayers(apiBase: string, metricId: number): Promise const json: unknown = await res.json() return parseMetricPoints(json) } catch (err) { - console.warn('[GameStatus] fetch metrics échoué', err) + console.warn('[GameStatus] Metrics fetch failed', err) return 0 } } -// ─── Disponibilité : ping /version ─────────────────────────────────────────── - +/** Returns true when the `/version` endpoint responds successfully. */ async function pingAvailability(apiBase: string): Promise { try { - const res = await fetchWithTimeout(ENDPOINTS.version(apiBase), 5_000) + const res = await fetchWithTimeout(ENDPOINTS.version(apiBase), HTTP_TIMEOUT_MS.versionPing) return res.ok } catch { return false } } -// ─── IPC Handlers ───────────────────────────────────────────────────────────── - +/** Registers IPC handlers for env availability and server status. */ export function registerGameStatusHandlers(): void { - - // ── Vérification de disponibilité au démarrage ───────────────────────────── ipcMain.removeHandler('env:check-availability') ipcMain.handle('env:check-availability', async (): Promise> => { const envs: Env[] = ['universe', 'universe-testing'] @@ -128,18 +117,17 @@ export function registerGameStatusHandlers(): void { const results = await Promise.all( envs.map(async (env) => { const base = getApiBase(env) - if (!base) return false // var vide → indisponible immédiatement + if (!base) return false return pingAvailability(base) }) ) return { - 'universe': results[0], + universe: results[0], 'universe-testing': results[1] } }) - // ── Statut serveur + joueurs pour un env ─────────────────────────────────── ipcMain.removeHandler('game:get-server-status') ipcMain.handle('game:get-server-status', async (_event, env: Env): Promise => { const base = getApiBase(env) @@ -151,7 +139,6 @@ export function registerGameStatusHandlers(): void { const componentId = getStatusComponentId(env) const metricId = getStatusMetricId(env) - // Fetch status + players en parallèle const [{ status, label }, players] = await Promise.all([ fetchStatus(base, componentId), fetchPlayers(base, metricId) @@ -159,4 +146,4 @@ export function registerGameStatusHandlers(): void { return { status, statusLabel: label, players, available: true } }) -} \ No newline at end of file +} diff --git a/src/main/services/godotUserdataCache.ts b/src/main/services/godotUserdataCache.ts index ca6fd9f..bac132e 100644 --- a/src/main/services/godotUserdataCache.ts +++ b/src/main/services/godotUserdataCache.ts @@ -5,10 +5,10 @@ import * as path from 'path' const CACHE_DIR_NAMES = ['shader_cache', 'chunk_cache'] as const /** - * Dossier userdata Godot pour le projet « DyingStar » (même logique que le jeu). - * - Linux : ~/.local/share/godot/app_userdata/DyingStar - * - Windows : %AppData%/Godot/app_userdata/DyingStar (Roaming) - * - macOS : ~/Library/Application Support/Godot/app_userdata/DyingStar + * Godot userdata root for the DyingStar project (same layout as the game). + * - Linux: ~/.local/share/godot/app_userdata/DyingStar + * - Windows: %AppData%/Godot/app_userdata/DyingStar + * - macOS: ~/Library/Application Support/Godot/app_userdata/DyingStar */ export function getDyingStarGodotUserdataRoot(): string { if (process.platform === 'linux') { @@ -17,19 +17,20 @@ export function getDyingStarGodotUserdataRoot(): string { if (process.platform === 'win32' || process.platform === 'darwin') { return path.join(app.getPath('appData'), 'Godot', 'app_userdata', 'DyingStar') } - throw new Error(`Plateforme non supportée pour le cache Godot : ${process.platform}`) + throw new Error(`Unsupported platform for Godot cache: ${process.platform}`) } export type ClearGodotCacheResult = { - root: string - /** Chemins de dossiers effectivement supprimés */ - removed: string[] - /** Dossiers de cache absents (rien à faire) */ - skipped: string[] - /** Erreurs par chemin */ - errors: { path: string; message: string }[] + root: string + /** Directories that were removed */ + removed: string[] + /** Cache directories that were already absent */ + skipped: string[] + /** Per-path errors */ + errors: { path: string; message: string }[] } +/** Returns true when the path exists and is a directory. */ function isExistingDirectory(p: string): boolean { try { if (!fs.existsSync(p)) return false @@ -40,8 +41,8 @@ function isExistingDirectory(p: string): boolean { } /** - * Supprime uniquement `shader_cache` et `chunk_cache` sous le userdata DyingStar. - * Ne supprime que si le chemin existe et est un dossier (sinon ignoré, sans erreur bloquante). + * Removes only `shader_cache` and `chunk_cache` under DyingStar userdata. + * Missing paths are skipped without throwing. */ export function clearDyingStarGodotCaches(): ClearGodotCacheResult { const root = getDyingStarGodotUserdataRoot() @@ -49,30 +50,24 @@ export function clearDyingStarGodotCaches(): ClearGodotCacheResult { const skipped: string[] = [] const errors: { path: string; message: string }[] = [] - if (!isExistingDirectory(root)) { - for (const name of CACHE_DIR_NAMES) { - skipped.push(path.join(root, name)) + for (const dirName of CACHE_DIR_NAMES) { + const target = path.join(root, dirName) + if (!isExistingDirectory(target)) { + skipped.push(target) + continue } - return { root, removed, skipped, errors } - } - - for (const name of CACHE_DIR_NAMES) { - const dir = path.join(root, name) try { - if (!isExistingDirectory(dir)) { - skipped.push(dir) - continue - } - // Dernière vérif avant suppression (évite rm sur chemin disparu / concurrent) - if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) { - skipped.push(dir) + if (!isExistingDirectory(target)) { + skipped.push(target) continue } - fs.rmSync(dir, { recursive: true, force: true }) - removed.push(dir) - } catch (e) { - const message = e instanceof Error ? e.message : String(e) - errors.push({ path: dir, message }) + fs.rmSync(target, { recursive: true, force: true }) + removed.push(target) + } catch (err) { + errors.push({ + path: target, + message: err instanceof Error ? err.message : String(err) + }) } } diff --git a/src/main/services/version.ts b/src/main/services/version.ts index b7c6145..7842b33 100644 --- a/src/main/services/version.ts +++ b/src/main/services/version.ts @@ -1,67 +1,51 @@ import { ipcMain, app } from 'electron' -import { getApiBase, ENDPOINTS } from '../config/env' -import type { Env } from '../../renderer/store/env' - -// ─── Types ──────────────────────────────────────────────────────────────────── +import { getApiBase, ENDPOINTS } from '../config/api' +import { HTTP_TIMEOUT_MS } from '../config/constants' +import type { Env } from '@shared/types/env' +import type { GameVersionInfo, VersionCheckResult } from '@shared/types/version' interface RemoteVersionPayload { - version: string // YYYYMMDDHHMMSS ex: "20260510092919" - releaseDate: string // YYYY-MM-DD ex: "2026-05-10" + version: string + releaseDate: string } interface GitHubLatestReleasePayload { - tag_name: string + tag_name: string published_at?: string } -interface GameVersionInfo { - version: string | null - releaseDate: string | null -} - interface LauncherReleaseInfo { - version: string + version: string releaseDate: string | null } -interface VersionCheckResult { - currentLauncherVersion: string - latestLauncherVersion: string | null - latestLauncherReleaseDate: string | null - launcherUpdateAvailable: boolean - latestGameVersions: Record -} - -// ─── Helpers ────────────────────────────────────────────────────────────────── - -/** Compare semver / tags du launcher (ex. 0.2.0 vs 0.10.1). */ +/** Returns true when the remote launcher semver is newer than the local one. */ function isNewerLauncherVersion(remote: string, local: string): boolean { return remote.localeCompare(local, undefined, { numeric: true, sensitivity: 'base' }) > 0 } +/** Fetches remote game version metadata for an environment. */ export async function fetchRemoteGameVersion(env: Env): Promise { const base = getApiBase(env) if (!base) return null return fetchGameVersion(ENDPOINTS.version(base)) } +/** Fetches game version JSON from a URL. */ async function fetchGameVersion(url: string): Promise { try { const res = await fetch(url, { - signal: AbortSignal.timeout(8_000), + signal: AbortSignal.timeout(HTTP_TIMEOUT_MS.api), headers: { 'Cache-Control': 'no-cache' } }) if (!res.ok) return null - return await res.json() as RemoteVersionPayload + return (await res.json()) as RemoteVersionPayload } catch { return null } } -/** - * Déduit owner/repo depuis une URL de dépôt GitHub publique. - * Ex. https://github.com/DyingStar-game/launcher → DyingStar-game/launcher - */ +/** Parses `owner/repo` from a public GitHub repository page URL. */ function parseGithubRepoUrl(repoPageUrl: string): { owner: string; repo: string } | null { try { const u = new URL(repoPageUrl.trim()) @@ -75,6 +59,7 @@ function parseGithubRepoUrl(repoPageUrl: string): { owner: string; repo: string } } +/** Fetches the latest GitHub release for the launcher repository. */ async function fetchLatestLauncherReleaseFromGithub( repoPageUrl: string ): Promise { @@ -86,24 +71,22 @@ async function fetchLatestLauncherReleaseFromGithub( try { const res = await fetch(apiUrl, { - signal: AbortSignal.timeout(10_000), + signal: AbortSignal.timeout(HTTP_TIMEOUT_MS.github), headers: { - Accept: 'application/vnd.github+json', + Accept: 'application/vnd.github+json', 'X-GitHub-Api-Version': '2022-11-28', - 'User-Agent': ua + 'User-Agent': ua } }) - // Aucune release publique → pas de bandeau if (res.status === 404) return null if (!res.ok) return null - const data = await res.json() as GitHubLatestReleasePayload + const data = (await res.json()) as GitHubLatestReleasePayload const rawTag = data.tag_name?.trim() ?? '' if (!rawTag) return null const version = rawTag.startsWith('v') || rawTag.startsWith('V') ? rawTag.slice(1) : rawTag - const releaseDate = - data.published_at?.match(/^(\d{4}-\d{2}-\d{2})/)?.[1] ?? null + const releaseDate = data.published_at?.match(/^(\d{4}-\d{2}-\d{2})/)?.[1] ?? null return { version, releaseDate } } catch { @@ -111,25 +94,21 @@ async function fetchLatestLauncherReleaseFromGithub( } } -// ─── Handler IPC ────────────────────────────────────────────────────────────── - +/** Registers the IPC handler that checks launcher and game versions. */ export function registerVersionHandlers(): void { - ipcMain.handle('version:check', async (): Promise => { const currentLauncherVersion = app.getVersion() const githubRepoUrl = (import.meta.env.VITE_LAUNCHER_GITHUB_REPO_URL ?? '').trim() const envs: Env[] = ['universe', 'universe-testing'] - const payloads = await Promise.all(envs.map((env) => fetchRemoteGameVersion(env))) const toInfo = (p: RemoteVersionPayload | null): GameVersionInfo => ({ - version: p?.version ?? null, + version: p?.version ?? null, releaseDate: p?.releaseDate ?? null }) - // ── Launcher : dernière release GitHub (pas /version du jeu) - let latestLauncherVersion: string | null = null + let latestLauncherVersion: string | null = null let latestLauncherReleaseDate: string | null = null let launcherUpdateAvailable = false @@ -148,7 +127,7 @@ export function registerVersionHandlers(): void { latestLauncherReleaseDate, launcherUpdateAvailable, latestGameVersions: { - 'universe': toInfo(payloads[0]), + universe: toInfo(payloads[0]), 'universe-testing': toInfo(payloads[1]) } } diff --git a/src/main/services/window.ts b/src/main/services/window.ts index 1d89d65..2b5ecdc 100644 --- a/src/main/services/window.ts +++ b/src/main/services/window.ts @@ -1,15 +1,12 @@ import { ipcMain, BrowserWindow } from 'electron' +import { parsePositiveInt } from '../config/constants' -function parsePositiveInt(raw: string | undefined, fallback: number): number { - const n = Number(raw) - return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback -} - -const MIN_WIDTH = parsePositiveInt(import.meta.env.VITE_WINDOW_WIDTH, 1200) +const MIN_WIDTH = parsePositiveInt(import.meta.env.VITE_WINDOW_WIDTH, 1200) const MIN_HEIGHT = parsePositiveInt(import.meta.env.VITE_WINDOW_HEIGHT, 800) -const MAX_WIDTH = 1920 -const MAX_HEIGHT = 1200 +const MAX_WIDTH = parsePositiveInt(import.meta.env.VITE_WINDOW_MAX_WIDTH, 1920) +const MAX_HEIGHT = parsePositiveInt(import.meta.env.VITE_WINDOW_MAX_HEIGHT, 1200) +/** Registers IPC handlers for frameless window controls and auto-resize. */ export function registerWindowHandlers(getWindow: () => BrowserWindow | null): void { ipcMain.removeHandler('window:minimize') ipcMain.removeHandler('window:close') diff --git a/src/main/vite-env.d.ts b/src/main/vite-env.d.ts deleted file mode 100644 index 6b04ab3..0000000 --- a/src/main/vite-env.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** Complète ImportMetaEnv pour les URLs API embarquées au build (voir electron-vite / Vite). */ -interface ImportMetaEnv { - readonly VITE_API_BASE_UNIVERSE: string - readonly VITE_API_BASE_TESTING: string - /** Base URL des archives jeu (ZIP). Si vide, identique à VITE_API_BASE_*. */ - readonly VITE_GAME_DOWNLOAD_BASE_UNIVERSE: string - readonly VITE_GAME_DOWNLOAD_BASE_TESTING: string - /** ZIP env prod (universe) — URLs complètes (prioritaires sur /game/latest-*.zip). */ - readonly VITE_GAME_ZIP_LINUX: string - readonly VITE_GAME_ZIP_WINDOWS: string - readonly VITE_GAME_ZIP_DARWIN: string - /** ZIP env test — URLs complètes (prioritaires sur /game/latest-*.zip). */ - readonly VITE_GAME_ZIP_TESTING_WINDOWS: string - readonly VITE_GAME_ZIP_TESTING_LINUX: string - readonly VITE_GAME_ZIP_TESTING_DARWIN: string - /** URL du dépôt GitHub du launcher (page releases), ex. https://github.com/org/launcher */ - readonly VITE_LAUNCHER_GITHUB_REPO_URL: string - /** Largeur fenêtre (px), défaut 1200 */ - readonly VITE_WINDOW_WIDTH: string - /** Hauteur fenêtre (px), défaut 800 */ - readonly VITE_WINDOW_HEIGHT: string - /** `"true"` pour ouvrir les DevTools au démarrage */ - readonly VITE_ENABLE_DEVTOOLS: string - /** `"true"` pour niveau de log fichier debug (electron-log) */ - readonly VITE_ELECTRON_ENABLE_LOGGING: string - /** ID Cachet `/api/components/:id` (universe). Entier > 0 ; défaut logique 3 dans env.ts si absent. */ - readonly VITE_STATUS_COMPONENT_ID_UNIVERSE: string - readonly VITE_STATUS_COMPONENT_ID_TESTING: string - /** ID Cachet `/api/metrics/:id/points` (joueurs). Défaut 2 dans env.ts si absent. */ - readonly VITE_STATUS_METRIC_ID_UNIVERSE: string - readonly VITE_STATUS_METRIC_ID_TESTING: string -} - -interface ImportMeta { - readonly env: ImportMetaEnv -} diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index 41f4e3f..b0807f2 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -1,118 +1,55 @@ import { ElectronAPI } from '@electron-toolkit/preload' -import type { Env } from '../renderer/store/env' - -type ServerStatusValue = 'online' | 'degraded' | 'offline' | 'maintenance' | 'unknown' | 'unavailable' - +import type { Env } from '@shared/types/env' +import type { UserInfo } from '@shared/types/auth' +import type { InstallResult } from '@shared/types/install' +import type { VersionCheckResult } from '@shared/types/version' +import type { ServerStatusValue } from '@shared/types/game' +import type { InstallProgressLabel } from '@shared/types/installProgress' + +/** Server status payload returned by `getServerStatus`. */ interface ServerStatusResult { - status: ServerStatusValue - players: number + status: ServerStatusValue + players: number available: boolean } -interface InstallResult { - version: string - releaseDate: string -} - -// Ajout du type manquant (référencé dans VersionCheckResult) -interface GameVersionInfo { - version: string | null - releaseDate: string | null -} - -interface VersionCheckResult { - currentLauncherVersion: string - latestLauncherVersion: string | null - latestLauncherReleaseDate: string | null - launcherUpdateAvailable: boolean - latestGameVersions: Record -} - -interface UserInfo { - sub: string - username: string - email: string -} - +/** Auth event pushed from main after OAuth callback or error. */ type AuthStateChangedPayload = | { env: Env; status: 'connected'; user: UserInfo } - | { env: Env; status: 'error'; error: string } + | { env: Env; status: 'error'; error: string } declare global { interface Window { electron: ElectronAPI + /** Typed bridge to main-process IPC handlers (see `preload/index.ts`). */ api: { - // ── Fichiers / Installation ────────────────────────────────────────── - - /** Ouvre un dialogue natif de sélection de répertoire. */ selectDirectory: () => Promise - - /** Lance le téléchargement et l'installation du jeu. */ installGame: (env: Env, installPath: string) => Promise - - /** S'abonne aux événements de progression de l'installation (0–100). */ - onInstallProgress: (callback: (progress: number, label: string) => void) => void - - /** Lit CHANGELOG.md dans le dossier d’installation (après extraction du ZIP). */ + onInstallProgress: (callback: (progress: number, label: InstallProgressLabel) => void) => void readChangelog: (installPath: string) => Promise - - /** Relit la version installée (API /version + version.json). */ - resolveInstalledVersion: ( - env: Env, - installPath: string - ) => Promise - - /** Supprime shader_cache et chunk_cache dans le userdata Godot DyingStar. */ + resolveInstalledVersion: (env: Env, installPath: string) => Promise clearGodotGameCache: () => Promise<{ root: string removed: string[] skipped: string[] errors: { path: string; message: string }[] }> - - // ── Jeu ───────────────────────────────────────────────────────────── - - /** Lance l'exécutable du jeu (détaché du launcher). */ launchGame: (env: Env, installPath: string) => Promise - - /** True si un processus jeu lancé par le launcher est encore actif. */ isGameRunning: () => Promise - - /** Écoute les changements d'état « jeu en cours ». */ onGameRunningChanged: (callback: (running: boolean) => void) => void - - /** Récupère le statut du serveur et le nombre de joueurs connectés. */ getServerStatus: (env: Env) => Promise - - // ── Disponibilité ───────────────────────────────────────────────────── - checkEnvAvailability: () => Promise> - - /** Ferme complètement le launcher. */ + checkEnvAvailability: () => Promise> quitApp: () => Promise - minimizeWindow: () => Promise - closeWindow: () => Promise - fitWindowToContent: (size: { width: number; height: number }) => Promise - - // ── Versions ───────────────────────────────────────────────────────── - checkVersions: () => Promise - - // ── Auth ───────────────────────────────────────────────────────────── - - /** Ouvre le navigateur sur la page Discord/Keycloak pour l'env donné. */ authLogin: (env: Env) => Promise - - /** Efface les tokens de l'env donné et ouvre la page de déconnexion Keycloak. */ authLogout: (env: Env) => Promise - - /** Recharge la session depuis le stockage chiffré pour l'env donné. */ authLoadUser: (env: Env) => Promise - - /** S'abonne aux changements d'état auth — payload inclut l'env concerné. */ onAuthStateChanged: (callback: (data: AuthStateChangedPayload) => void) => void } } -} \ No newline at end of file +} + +export {} diff --git a/src/preload/index.ts b/src/preload/index.ts index 51bbcd3..b29e429 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -1,34 +1,42 @@ import { contextBridge, ipcRenderer } from 'electron' import { electronAPI } from '@electron-toolkit/preload' -import type { Env } from '../renderer/store/env' -import type { UserInfo } from '../main/services/auth' -import type { ServerStatusValue } from '../main/services/gameStatus' - +import type { Env } from '@shared/types/env' +import type { InstallProgressLabel } from '@shared/types/installProgress' +import type { UserInfo } from '@shared/types/auth' +import type { ServerStatusValue } from '@shared/types/game' + +/** + * Renderer-facing API exposed as `window.api`. + * Each method maps to an `ipcMain.handle` in the main process. + */ const api = { - // ── Fichiers / Installation ──────────────────────────────────────────────── - - selectDirectory: (): Promise => - ipcRenderer.invoke('files:select-directory'), + /** Opens a native folder picker; returns the chosen path or null if cancelled. */ + selectDirectory: (): Promise => ipcRenderer.invoke('files:select-directory'), + /** Downloads and extracts the game ZIP; returns installed version metadata. */ installGame: (env: Env, installPath: string): Promise<{ version: string; releaseDate: string }> => ipcRenderer.invoke('files:install', env, installPath), - onInstallProgress: (callback: (progress: number, label: string) => void): void => { + /** Subscribes to install/download progress events (0–100 and structured label). */ + onInstallProgress: (callback: (progress: number, label: InstallProgressLabel) => void): void => { ipcRenderer.removeAllListeners('files:progress') - ipcRenderer.on('files:progress', (_event, progress: number, label: string) => { + ipcRenderer.on('files:progress', (_event, progress: number, label: InstallProgressLabel) => { callback(progress, label) }) }, + /** Reads CHANGELOG.md from the install directory, if present. */ readChangelog: (installPath: string): Promise => ipcRenderer.invoke('files:read-changelog', installPath), + /** Re-resolves installed version from disk and remote API after install or on demand. */ resolveInstalledVersion: ( env: Env, installPath: string ): Promise<{ version: string; releaseDate: string } | null> => ipcRenderer.invoke('files:resolve-installed-version', env, installPath), + /** Clears Godot shader/chunk caches under the DyingStar userdata folder. */ clearGodotGameCache: (): Promise<{ root: string removed: string[] @@ -36,14 +44,14 @@ const api = { errors: { path: string; message: string }[] }> => ipcRenderer.invoke('files:clear-godot-cache'), - // ── Jeu ─────────────────────────────────────────────────────────────────── - + /** Spawns the game executable with a fresh JWT (`--token=`). */ launchGame: (env: Env, installPath: string): Promise => ipcRenderer.invoke('game:launch', env, installPath), - isGameRunning: (): Promise => - ipcRenderer.invoke('game:is-running'), + /** Returns whether a game process launched by the launcher is still running. */ + isGameRunning: (): Promise => ipcRenderer.invoke('game:is-running'), + /** Subscribes to changes in game running state (launch / exit). */ onGameRunningChanged: (callback: (running: boolean) => void): void => { ipcRenderer.removeAllListeners('game:running-changed') ipcRenderer.on('game:running-changed', (_event, payload: { running: boolean }) => { @@ -51,49 +59,53 @@ const api = { }) }, - getServerStatus: (env: Env): Promise<{ status: ServerStatusValue; players: number; available: boolean }> => + /** Fetches server status and connected player count for an environment. */ + getServerStatus: ( + env: Env + ): Promise<{ status: ServerStatusValue; players: number; available: boolean }> => ipcRenderer.invoke('game:get-server-status', env), - // ── Disponibilité des envs (ping au démarrage) ──────────────────────────── - + /** Pings each env API `/version` to determine runtime availability at startup. */ checkEnvAvailability: (): Promise> => ipcRenderer.invoke('env:check-availability'), + /** Quits the entire application. */ quitApp: (): Promise => ipcRenderer.invoke('app:quit'), + /** Minimizes the main window (frameless chrome). */ minimizeWindow: (): Promise => ipcRenderer.invoke('window:minimize'), + /** Closes the main window. */ closeWindow: (): Promise => ipcRenderer.invoke('window:close'), + /** Resizes the window to fit renderer content within min/max bounds. */ fitWindowToContent: (size: { width: number; height: number }): Promise => ipcRenderer.invoke('window:fit-content', size), - // ── Versions ────────────────────────────────────────────────────────────── - + /** Compares launcher and game versions against remote sources. */ checkVersions: (): Promise<{ - currentLauncherVersion: string - latestLauncherVersion: string | null + currentLauncherVersion: string + latestLauncherVersion: string | null latestLauncherReleaseDate: string | null - launcherUpdateAvailable: boolean - latestGameVersions: Record - }> => - ipcRenderer.invoke('version:check'), - - // ── Auth ────────────────────────────────────────────────────────────────── + launcherUpdateAvailable: boolean + latestGameVersions: Record + }> => ipcRenderer.invoke('version:check'), - authLogin: (env: Env): Promise => - ipcRenderer.invoke('auth:login', env), + /** Opens the system browser on the Keycloak Discord login page. */ + authLogin: (env: Env): Promise => ipcRenderer.invoke('auth:login', env), - authLogout: (env: Env): Promise => - ipcRenderer.invoke('auth:logout', env), + /** Clears stored tokens and opens Keycloak logout. */ + authLogout: (env: Env): Promise => ipcRenderer.invoke('auth:logout', env), - authLoadUser: (env: Env): Promise => - ipcRenderer.invoke('auth:load-user', env), + /** Refreshes the session and returns the user profile, or null if logged out. */ + authLoadUser: (env: Env): Promise => ipcRenderer.invoke('auth:load-user', env), + /** Subscribes to auth state changes after login, logout, or OAuth callback. */ onAuthStateChanged: ( - callback: (data: - | { env: Env; status: 'connected'; user: UserInfo } - | { env: Env; status: 'error'; error: string } + callback: ( + data: + | { env: Env; status: 'connected'; user: UserInfo } + | { env: Env; status: 'error'; error: string } ) => void ): void => { ipcRenderer.removeAllListeners('auth:state-changed') @@ -101,6 +113,7 @@ const api = { } } +/** Exposes safe APIs to the renderer (isolated context) or assigns to window in dev. */ if (process.contextIsolated) { try { contextBridge.exposeInMainWorld('electron', electronAPI) @@ -109,8 +122,8 @@ if (process.contextIsolated) { console.error('[Preload]', error) } } else { - // @ts-ignore + // @ts-expect-error non-isolated fallback assigns globals on window for debugging window.electron = electronAPI - // @ts-ignore + // @ts-expect-error non-isolated fallback assigns globals on window for debugging window.api = api -} \ No newline at end of file +} diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx new file mode 100644 index 0000000..61bbe75 --- /dev/null +++ b/src/renderer/App.tsx @@ -0,0 +1,25 @@ +import Shell from '@components/layout/Shell' +import { useEffect } from 'react' +import { useVersionStore } from '@stores/version' +import { useAvailabilityStore } from '@stores/availability' + +/** + * Runs one-time startup checks: API availability and version comparison. + */ +function useAppStartup(): void { + const { checkVersions, checked: versionChecked } = useVersionStore() + const { checkAvailability, checked: availChecked } = useAvailabilityStore() + + useEffect(() => { + if (!availChecked) void checkAvailability() + if (!versionChecked) void checkVersions() + }, [availChecked, versionChecked, checkAvailability, checkVersions]) +} + +/** Root React tree: shell layout and startup side effects. */ +function App(): React.JSX.Element { + useAppStartup() + return +} + +export default App diff --git a/src/renderer/src/assets/fonts/Poppins-Bold.ttf b/src/renderer/assets/fonts/Poppins-Bold.ttf similarity index 100% rename from src/renderer/src/assets/fonts/Poppins-Bold.ttf rename to src/renderer/assets/fonts/Poppins-Bold.ttf diff --git a/src/renderer/src/assets/fonts/Poppins-BoldItalic.ttf b/src/renderer/assets/fonts/Poppins-BoldItalic.ttf similarity index 100% rename from src/renderer/src/assets/fonts/Poppins-BoldItalic.ttf rename to src/renderer/assets/fonts/Poppins-BoldItalic.ttf diff --git a/src/renderer/src/assets/fonts/Poppins-Italic.ttf b/src/renderer/assets/fonts/Poppins-Italic.ttf similarity index 100% rename from src/renderer/src/assets/fonts/Poppins-Italic.ttf rename to src/renderer/assets/fonts/Poppins-Italic.ttf diff --git a/src/renderer/src/assets/fonts/Poppins-Regular.ttf b/src/renderer/assets/fonts/Poppins-Regular.ttf similarity index 100% rename from src/renderer/src/assets/fonts/Poppins-Regular.ttf rename to src/renderer/assets/fonts/Poppins-Regular.ttf diff --git a/src/renderer/src/assets/icons/dyingstar-logo.png b/src/renderer/assets/icons/dyingstar-logo.png similarity index 100% rename from src/renderer/src/assets/icons/dyingstar-logo.png rename to src/renderer/assets/icons/dyingstar-logo.png diff --git a/src/renderer/assets/main.css b/src/renderer/assets/main.css new file mode 100644 index 0000000..ac73dab --- /dev/null +++ b/src/renderer/assets/main.css @@ -0,0 +1,232 @@ +@import 'tailwindcss'; + +@font-face { + font-family: 'Poppins'; + src: url('./fonts/Poppins-Regular.ttf') format('truetype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Poppins'; + src: url('./fonts/Poppins-Italic.ttf') format('truetype'); + font-weight: 400; + font-style: italic; + font-display: swap; +} + +@font-face { + font-family: 'Poppins'; + src: url('./fonts/Poppins-Bold.ttf') format('truetype'); + font-weight: 700; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Poppins'; + src: url('./fonts/Poppins-BoldItalic.ttf') format('truetype'); + font-weight: 700; + font-style: italic; + font-display: swap; +} + +@theme { + --font-sans: 'Poppins', system-ui, sans-serif; + + --color-ds-bg: #0d0d14; + --color-ds-surface: #16161f; + --color-ds-surface-hover: rgba(255, 255, 255, 0.05); + --color-ds-surface-elevated: rgba(255, 255, 255, 0.03); + --color-ds-border: #2a2a3a; + --color-ds-accent: rgb(255, 186, 8, 0.8); + --color-ds-text: rgb(255, 186, 8); + --color-ds-muted: #6b6b80; + --color-ds-success: #22c55e; + --color-ds-warning: #f59e0b; + --color-ds-danger: #ef4444; + + --shadow-ds-panel: 0 12px 32px rgba(0, 0, 0, 0.35); + --shadow-ds-card: 0 8px 24px rgba(0, 0, 0, 0.3); + --shadow-ds-modal: 0 24px 64px rgba(0, 0, 0, 0.55); + --radius-ds-panel: 0.75rem; +} + +html, +body { + height: 100%; + min-height: 100%; + width: 100%; + background-color: var(--color-ds-bg); + color: var(--color-ds-text); + font-family: var(--font-sans); + overflow: hidden; +} + +#root { + height: 100%; + min-height: 100%; + width: 100%; + display: flex; + flex-direction: column; +} + +.app-drag { + -webkit-app-region: drag; +} + +.app-no-drag { + -webkit-app-region: no-drag; +} + +@layer components { + .ds-panel { + background-color: var(--color-ds-surface); + border: 1px solid var(--color-ds-border); + border-radius: var(--radius-ds-panel); + box-shadow: var(--shadow-ds-panel); + transition: border-color 0.15s ease; + } + + .ds-panel:hover { + border-color: color-mix(in srgb, var(--color-ds-accent) 40%, transparent); + } + + /** Top bar: same surface as panels but no accent border on hover (avoids yellow outline when hovering child buttons). */ + .ds-panel-bar { + background-color: var(--color-ds-surface); + border-bottom: 1px solid var(--color-ds-border); + border-radius: 0; + box-shadow: none; + } + + .ds-panel-padded { + padding: 1.75rem; + } + + .ds-panel-padded-sm { + padding: 1.5rem; + } + + .ds-card { + background-color: var(--color-ds-surface); + border: 1px solid var(--color-ds-border); + border-radius: var(--radius-ds-panel); + box-shadow: var(--shadow-ds-card); + } + + .ds-modal { + background-color: var(--color-ds-surface); + border: 1px solid var(--color-ds-border); + border-radius: var(--radius-ds-panel); + box-shadow: var(--shadow-ds-modal); + } + + .ds-section-label { + font-size: 11px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.24em; + color: var(--color-ds-muted); + } + + .ds-sidebar { + width: 15rem; + flex-shrink: 0; + align-self: stretch; + min-height: 100%; + height: 100%; + border-right: 1px solid var(--color-ds-border); + background-color: color-mix(in srgb, var(--color-ds-surface) 30%, transparent); + backdrop-filter: blur(8px); + padding: 1rem 0.75rem; + display: flex; + flex-direction: column; + gap: 0.5rem; + } + + /** Full-height page shell (universe, social, lore). */ + .ds-page { + display: flex; + flex: 1 1 auto; + min-height: 0; + height: 100%; + width: 100%; + background-color: var(--color-ds-bg); + } +} + +.lore-markdown { + color: var(--color-ds-text); + font-size: 15px; + line-height: 1.75; + max-width: 850px; + margin: 0 auto; +} + +.lore-markdown h1 { + font-size: 2.4rem; + font-weight: 800; + margin: 2rem 0 1rem; + letter-spacing: -0.02em; +} + +.lore-markdown h2 { + font-size: 1.6rem; + font-weight: 700; + margin: 2rem 0 0.8rem; + color: var(--color-ds-text); +} + +.lore-markdown h3 { + font-size: 1.2rem; + font-weight: 600; + margin: 1.5rem 0 0.6rem; + color: var(--color-ds-muted); +} + +.lore-markdown p { + margin: 0.8rem 0; + color: var(--color-ds-text); +} + +.lore-markdown blockquote { + border-left: 3px solid var(--color-ds-accent); + padding: 0.8rem 1rem; + margin: 1.5rem 0; + background: var(--color-ds-surface-elevated); + border-radius: 8px; + font-style: italic; + color: var(--color-ds-muted); +} + +.lore-markdown ul { + padding-left: 1.5rem; + margin: 1rem 0; +} + +.lore-markdown li { + margin: 0.4rem 0; +} + +.lore-markdown img { + width: 100%; + border-radius: 12px; + margin: 1.5rem 0; + box-shadow: var(--shadow-ds-panel); +} + +.lore-markdown code { + background: var(--color-ds-surface-hover); + padding: 2px 6px; + border-radius: 6px; + font-size: 0.9em; +} + +.lore-markdown pre { + background: rgba(0, 0, 0, 0.4); + padding: 1rem; + border-radius: 12px; + overflow-x: auto; +} diff --git a/src/renderer/components/layout/Navbar.tsx b/src/renderer/components/layout/Navbar.tsx new file mode 100644 index 0000000..62e66a3 --- /dev/null +++ b/src/renderer/components/layout/Navbar.tsx @@ -0,0 +1,384 @@ +import type React from 'react' +import { useId } from 'react' +import i18n from '@i18n' +import { useEnvStore } from '@stores/env' +import { useNavigationStore } from '@stores/navigation' +import type { View } from '@stores/navigation' +import { useTranslation } from 'react-i18next' +import Button from '@components/ui/primitives/Button' +import DiscordIcon from '@components/ui/primitives/icons/DiscordIcon' +import { navUrls } from '@lib/env' +import type { ReactNode } from 'react' + +/** Wrapper for navbar icon buttons with hover border styling. */ +function Icon({ + children, + className = '' +}: { + children: ReactNode + className?: string +}): React.JSX.Element { + return ( + + {children} + + ) +} + +/** Accessible inline SVG with title for screen readers. */ +function Svg({ children, title }: { children: ReactNode; title: string }): React.JSX.Element { + return ( + + ) +} + +function FlagFR(): React.JSX.Element { + const { t } = useTranslation() + return ( + + ) +} + +function FlagEN(): React.JSX.Element { + const { t } = useTranslation() + return ( + + ) +} + +function HeartDonateIcon(): React.JSX.Element { + const gradId = `navHeartFill-${useId().replace(/:/g, '')}` + return ( + + ) +} + +/** Top bar: env switcher, navigation, external links, language, and window controls. */ +export default function Navbar(): React.JSX.Element { + const { activeEnv, setEnv } = useEnvStore() + const { currentView, navigate } = useNavigationStore() + const { t } = useTranslation() + + const { website: navWebsite, discord: navDiscord, wiki: navWiki, donate: navDonate } = navUrls() + + /** Switches active env in the store and navigates to the matching universe view. */ + const handleEnvSwitch = (env: 'universe' | 'universe-testing'): void => { + setEnv(env) + navigate(env) + } + + const navLinks: { label: string; view: View }[] = [ + { label: t('navbar.social'), view: 'social' }, + { label: t('navbar.lore'), view: 'lore' } + ] + + return ( + + ) +} diff --git a/src/renderer/components/layout/Shell.tsx b/src/renderer/components/layout/Shell.tsx new file mode 100644 index 0000000..3114573 --- /dev/null +++ b/src/renderer/components/layout/Shell.tsx @@ -0,0 +1,35 @@ +import Navbar from './Navbar' +import { useNavigationStore } from '@stores/navigation' +import { useFitWindowToContent } from '@hooks/useFitWindowToContent' +import UniverseView from '@views/UniverseView' +import Social from '@views/Social' +import Lore from '@views/Lore' + +/** Application shell: navbar, routed main content, and window auto-resize. */ +export default function Shell(): React.JSX.Element { + const { currentView } = useNavigationStore() + useFitWindowToContent() + + /** Maps navigation store view id to the corresponding page component. */ + const renderView = (): React.JSX.Element => { + switch (currentView) { + case 'universe': + return + case 'universe-testing': + return + case 'social': + return + case 'lore': + return + default: + return + } + } + + return ( +
+ +
{renderView()}
+
+ ) +} diff --git a/src/renderer/components/layout/navbar.tsx b/src/renderer/components/layout/navbar.tsx deleted file mode 100644 index 2502ea2..0000000 --- a/src/renderer/components/layout/navbar.tsx +++ /dev/null @@ -1,386 +0,0 @@ -import type React from 'react' -import { useId } from 'react' -import i18n from '@renderer/i18n' -import { useEnvStore } from '@store/env' -import { useNavigationStore } from '@store/navigation' -import type { View } from '@store/navigation' -import { useTranslation } from 'react-i18next' -import Button from '@components/ui/button' -import DiscordIcon from '@components/ui/discordIcon' -import type { ReactNode } from 'react' - -function Icon({ - children, - className = '' -}: { - children: ReactNode - className?: string -}): React.JSX.Element { - return ( - - {children} - - ) -} - -function Svg({ - children, - title -}: { - children: ReactNode - title: string -}): React.JSX.Element { - return ( - - ) -} - -function FlagFR(): React.JSX.Element { - return ( - - ) -} - -function FlagEN(): React.JSX.Element { - return ( - - ) -} - -function HeartDonateIcon(): React.JSX.Element { - const gradId = `navHeartFill-${useId().replace(/:/g, '')}` - return ( - - ) -} - -export default function Navbar(): React.JSX.Element { - const { activeEnv, setEnv } = useEnvStore() - const { currentView, navigate } = useNavigationStore() - const { t } = useTranslation() - - const navWebsite = (import.meta.env.VITE_NAV_WEBSITE_URL ?? '').trim() - const navDiscord = (import.meta.env.VITE_NAV_DISCORD_URL ?? '').trim() - const navWiki = (import.meta.env.VITE_NAV_WIKI_URL ?? '').trim() - const navDonate = (import.meta.env.VITE_NAV_DONATE_URL ?? '').trim() - - const handleEnvSwitch = (env: 'universe' | 'universe-testing'): void => { - setEnv(env) - navigate(env) - } - - const navLinks: { label: string; view: View }[] = [ - { label: t("navbar.social"), view: 'social' }, - { label: t("navbar.lore"), view: 'lore' } - ] - - return ( - - ) -} \ No newline at end of file diff --git a/src/renderer/components/layout/shell.tsx b/src/renderer/components/layout/shell.tsx deleted file mode 100644 index c4e19f3..0000000 --- a/src/renderer/components/layout/shell.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import Navbar from './navbar' -import { useNavigationStore } from '@store/navigation' -import { useFitWindowToContent } from '@renderer/hooks/useFitWindowToContent' -import Universe from '@views/universe' -import UniverseTesting from '@views/universeTesting' -import Social from '@views/social' -import Lore from '@views/lore' - -export default function Shell(): React.JSX.Element { - const { currentView } = useNavigationStore() - useFitWindowToContent() - - const renderView = (): React.JSX.Element => { - switch (currentView) { - case 'universe': return - case 'universe-testing': return - case 'social': return - case 'lore': return - default: return - } - } - - return ( -
- -
- {renderView()} -
-
- ) -} diff --git a/src/renderer/components/panel/accountPanel.tsx b/src/renderer/components/panel/AccountPanel.tsx similarity index 63% rename from src/renderer/components/panel/accountPanel.tsx rename to src/renderer/components/panel/AccountPanel.tsx index beb69f6..f8dbfe4 100644 --- a/src/renderer/components/panel/accountPanel.tsx +++ b/src/renderer/components/panel/AccountPanel.tsx @@ -1,10 +1,11 @@ -import { useAccountStore } from '@store/account' -import { useEnvStore } from '@store/env' -import { useAvailabilityStore } from '@store/availability' +import { useAccountStore } from '@stores/account' +import { useEnvStore } from '@stores/env' +import { useAvailabilityStore } from '@stores/availability' import { useTranslation } from 'react-i18next' -import Button from '@components/ui/button' -import DiscordIcon from '@components/ui/discordIcon' +import Button from '@components/ui/primitives/Button' +import DiscordIcon from '@components/ui/primitives/icons/DiscordIcon' +/** Account panel: Discord login/logout and session display per environment. */ export default function AccountPanel(): React.JSX.Element { const { activeEnv } = useEnvStore() const { data, login, logout, cancelLogin } = useAccountStore() @@ -15,31 +16,22 @@ export default function AccountPanel(): React.JSX.Element { const { t } = useTranslation() return ( -
- +
-

- {t('universe.account.title')} -

+

{t('universe.account.title')}

{!isAvailable && ( -

- {t('universe.account.unavailable')} -

+

{t('universe.account.unavailable')}

)} {isAvailable && status === 'disconnected' && ( -

- {t('universe.account.disconnected')} -

+

{t('universe.account.disconnected')}

)} {isAvailable && status === 'loading' && ( -

- {t('universe.account.loading')} -

+

{t('universe.account.loading')}

)} {isAvailable && status === 'connected' && ( @@ -49,7 +41,6 @@ export default function AccountPanel(): React.JSX.Element { )}
- {!isAvailable && ( )} - {/* {isAvailable && installed && !gameUpdateAvailable && ( - - )} */} + )} {isAvailable && installed && ( - )} @@ -212,4 +218,4 @@ export default function FilesPanel(): React.JSX.Element { />
) -} \ No newline at end of file +} diff --git a/src/renderer/components/panel/gamePanel.tsx b/src/renderer/components/panel/GamePanel.tsx similarity index 52% rename from src/renderer/components/panel/gamePanel.tsx rename to src/renderer/components/panel/GamePanel.tsx index 9965158..5a49921 100644 --- a/src/renderer/components/panel/gamePanel.tsx +++ b/src/renderer/components/panel/GamePanel.tsx @@ -1,37 +1,22 @@ import { useEffect } from 'react' -import { useGameStore } from '@store/game' -import { useFilesStore } from '@store/files' -import { useVersionStore } from '@store/version' -import { useEnvStore, type Env } from '@store/env' -import { isGameUpdateAvailable } from '@renderer/lib/isGameUpdateAvailable' -import { useAvailabilityStore } from '@store/availability' -import { useAccountStore } from '@store/account' +import { useGameStore } from '@stores/game' +import { useFilesStore } from '@stores/files' +import { useVersionStore } from '@stores/version' +import { useEnvStore } from '@stores/env' +import { isGameUpdateAvailable } from '@lib/isGameUpdateAvailable' +import { pollIntervalMinutes, statusPageUrlForEnv } from '@lib/env' +import { useAvailabilityStore } from '@stores/availability' +import { useAccountStore } from '@stores/account' import { useTranslation } from 'react-i18next' -import ServerStatus from '@components/ui/serverStatus' -import Button from '@components/ui/button' -import PanelMessage from '@components/ui/panelMessage' - -function statusPageUrlForEnv(env: Env): string { - const raw = - env === 'universe' - ? import.meta.env.VITE_STATUS_PAGE_UNIVERSE - : import.meta.env.VITE_STATUS_PAGE_TESTING - return (raw ?? '').trim() -} - -/** Minutes entre deux appels statut + joueurs ; borne pour éviter valeurs absurdes. */ -function pollIntervalMinutes(): number { - const raw = import.meta.env.VITE_SERVER_STATUS_POLL_MINUTES ?? '5' - let n = Number.parseFloat(String(raw).trim()) - if (!Number.isFinite(n) || n < 1) n = 5 - if (n > 24 * 60) n = 24 * 60 - return n -} +import ServerStatus from '@components/ui/feedback/ServerStatus' +import Button from '@components/ui/primitives/Button' +import PanelMessage from '@components/ui/feedback/PanelMessage' +/** Game panel: server status, player count, play button, and status page link. */ export default function GamePanel(): React.JSX.Element { const { activeEnv } = useEnvStore() const { data: gameData, fetchServerStatus, play, gameRunning } = useGameStore() - const { data: filesData } = useFilesStore() + const { data: filesData, syncInstalledVersions } = useFilesStore() const latestGameInfo = useVersionStore((s) => s.latestGameVersions[activeEnv]) const { available } = useAvailabilityStore() @@ -48,6 +33,10 @@ export default function GamePanel(): React.JSX.Element { const { t } = useTranslation() + useEffect(() => { + void syncInstalledVersions() + }, [activeEnv, syncInstalledVersions]) + useEffect(() => { if (!isAvailable) return @@ -61,7 +50,7 @@ export default function GamePanel(): React.JSX.Element { return () => window.clearInterval(id) }, [activeEnv, isAvailable, fetchServerStatus]) - /** Opérationnel, à jour, connecté — sinon bouton désactivé. */ + /** Play is enabled when server is up, game installed, authenticated, and not already running. */ const canPlay = installed && isAvailable && @@ -74,16 +63,13 @@ export default function GamePanel(): React.JSX.Element { const canOpenStatusPage = Boolean(statusPageUrl) return ( -
- +
-

- {t('universe.game.title')} -

+

{t('universe.game.title')}

- {/* Statut serveur */} + {/* Server status */}
@@ -91,19 +77,15 @@ export default function GamePanel(): React.JSX.Element {
- {/* Joueurs connectés */} + {/* Connected players */} {isAvailable && (

{t('universe.game.players', { count: players })}

)} - {/* Jeu non installé */} - {!installed && ( - - {t('universe.game.notInstalled')} - - )} + {/* Game not installed */} + {!installed && {t('universe.game.notInstalled')}} {/* Actions */}
@@ -114,35 +96,22 @@ export default function GamePanel(): React.JSX.Element { )} {installed && gameUpdateAvailable && ( - - {t('universe.game.playDisabledUpdate')} - + {t('universe.game.playDisabledUpdate')} )} {installed && gameRunning && ( - - {t('universe.game.playDisabledRunning')} - + {t('universe.game.playDisabledRunning')} )} {installed && isAvailable && accountStatus === 'loading' && ( - - {t('universe.game.playDisabledAuthLoading')} - + {t('universe.game.playDisabledAuthLoading')} )} {installed && isAvailable && accountStatus === 'disconnected' && ( - - {t('universe.game.playDisabledAuth')} - + {t('universe.game.playDisabledAuth')} )} - @@ -150,13 +119,11 @@ export default function GamePanel(): React.JSX.Element { variant="secondary" className="w-full" disabled={!canOpenStatusPage} - onClick={() => - canOpenStatusPage ? window.open(statusPageUrl, '_blank') : undefined - } + onClick={() => (canOpenStatusPage ? window.open(statusPageUrl, '_blank') : undefined)} > {t('universe.game.viewStatus')}
) -} \ No newline at end of file +} diff --git a/src/renderer/components/panel/socialPanel.tsx b/src/renderer/components/panel/SocialPanel.tsx similarity index 62% rename from src/renderer/components/panel/socialPanel.tsx rename to src/renderer/components/panel/SocialPanel.tsx index db9558a..7bdbb58 100644 --- a/src/renderer/components/panel/socialPanel.tsx +++ b/src/renderer/components/panel/SocialPanel.tsx @@ -1,13 +1,12 @@ -// src/renderer/components/panel/socialPanel.tsx - import { useEffect } from 'react' -import { useSocialStore } from '@store/social' -import { useEnvStore } from '@store/env' -import { useNavigationStore } from '@store/navigation' +import { useSocialStore } from '@stores/social' +import { useEnvStore } from '@stores/env' +import { useNavigationStore } from '@stores/navigation' import { useTranslation } from 'react-i18next' -import FriendItem from '@components/ui/friendItem' -import Button from '@components/ui/button' +import FriendItem from '@components/ui/social/FriendItem' +import Button from '@components/ui/primitives/Button' +/** Compact social preview on the universe grid (friends + request badge). */ export default function SocialPanel(): React.JSX.Element { const { activeEnv } = useEnvStore() const { data, fetchAll } = useSocialStore() @@ -20,11 +19,10 @@ export default function SocialPanel(): React.JSX.Element { useEffect(() => { fetchAll() - }, [activeEnv]) // Recharge les amis à chaque changement d'env + }, [activeEnv, fetchAll]) return ( -
- +
{notifications > 0 && (
@@ -35,18 +33,14 @@ export default function SocialPanel(): React.JSX.Element { {/* Header */}
-

- {t('universe.social.title')} -

+

{t('universe.social.title')}

{/* Friend list */}
{friends.length === 0 && ( -

- {t('universe.social.noFriends')} -

+

{t('universe.social.noFriends')}

)} {visibleFriends.map((friend) => ( @@ -64,4 +58,4 @@ export default function SocialPanel(): React.JSX.Element {
) -} \ No newline at end of file +} diff --git a/src/renderer/components/ui/panelMessage.tsx b/src/renderer/components/ui/feedback/PanelMessage.tsx similarity index 77% rename from src/renderer/components/ui/panelMessage.tsx rename to src/renderer/components/ui/feedback/PanelMessage.tsx index 369a4e0..f44a94b 100644 --- a/src/renderer/components/ui/panelMessage.tsx +++ b/src/renderer/components/ui/feedback/PanelMessage.tsx @@ -9,11 +9,12 @@ type Props = { } const STYLES: Record = { - info: 'border-sky-500/35 bg-sky-500/12 text-sky-100', + info: 'border-sky-500/35 bg-sky-500/12 text-sky-100', warning: 'border-amber-500/35 bg-amber-500/12 text-amber-100', - error: 'border-red-500/35 bg-red-500/12 text-red-200' + error: 'border-red-500/35 bg-red-500/12 text-red-200' } +/** Inline info/warning/error message box used inside universe panels. */ export default function PanelMessage({ variant, children, diff --git a/src/renderer/components/ui/feedback/ServerStatus.tsx b/src/renderer/components/ui/feedback/ServerStatus.tsx new file mode 100644 index 0000000..ddcd6ee --- /dev/null +++ b/src/renderer/components/ui/feedback/ServerStatus.tsx @@ -0,0 +1,28 @@ +import type { ServerStatusValue } from '@stores/game' + +type Props = { status: ServerStatusValue } + +const STATUS_CONFIG: Record = { + online: { color: 'bg-emerald-400', pulse: true }, + degraded: { color: 'bg-amber-400', pulse: true }, + offline: { color: 'bg-red-500', pulse: false }, + maintenance: { color: 'bg-sky-400', pulse: true }, + unknown: { color: 'bg-zinc-500', pulse: false }, + unavailable: { color: 'bg-zinc-600', pulse: false } +} + +/** Colored status dot with optional pulse animation for live server state. */ +export default function ServerStatus({ status }: Props): React.JSX.Element { + const { color, pulse } = STATUS_CONFIG[status] ?? STATUS_CONFIG.unknown + + return ( + + {pulse && ( + + )} + + + ) +} diff --git a/src/renderer/components/ui/updateAlert.tsx b/src/renderer/components/ui/feedback/UpdateAlert.tsx similarity index 64% rename from src/renderer/components/ui/updateAlert.tsx rename to src/renderer/components/ui/feedback/UpdateAlert.tsx index dcab7a0..49e69c1 100644 --- a/src/renderer/components/ui/updateAlert.tsx +++ b/src/renderer/components/ui/feedback/UpdateAlert.tsx @@ -3,17 +3,22 @@ import { useTranslation } from 'react-i18next' type Variant = 'launcher' | 'game' type Props = { - variant: Variant - currentVersion?: string - latestVersion: string + variant: Variant + currentVersion?: string + latestVersion: string latestReleaseDate?: string - onDismiss?: () => void + onDismiss?: () => void } const CONFIG = { launcher: { icon: ( - + @@ -22,7 +27,12 @@ const CONFIG = { }, game: { icon: ( - + @@ -34,25 +44,24 @@ const CONFIG = { const COLOR_CLASSES = { amber: { wrapper: 'border-amber-500/30 bg-amber-500/8', - icon: 'text-amber-400', - title: 'text-amber-300', - text: 'text-sky-200/70', - badge: 'border-amber-500/30 bg-amber-500/15 text-amber-300', + icon: 'text-amber-400', + title: 'text-amber-300', + text: 'text-sky-200/70', + badge: 'border-amber-500/30 bg-amber-500/15 text-amber-300', dismiss: 'text-amber-400/50 hover:text-amber-300' }, sky: { wrapper: 'border-sky-500/30 bg-sky-500/8', - icon: 'text-sky-400', - title: 'text-sky-300', - text: 'text-sky-200/70', - badge: 'border-sky-500/30 bg-sky-500/15 text-sky-300', + icon: 'text-sky-400', + title: 'text-sky-300', + text: 'text-sky-200/70', + badge: 'border-sky-500/30 bg-sky-500/15 text-sky-300', dismiss: 'text-sky-400/50 hover:text-sky-300' } } /** - * Formate un timestamp YYYYMMDDHHMMSS en "10/05/2026 09:29" - * Laisse passer les autres formats tels quels (semver, etc.) + * Formats YYYYMMDDHHMMSS build ids as "DD/MM/YYYY HH:mm"; passes through semver as-is. */ function formatVersion(v: string): string { if (v.length === 14 && /^\d+$/.test(v)) { @@ -63,6 +72,7 @@ function formatVersion(v: string): string { return v } +/** Banner when a newer launcher or game build is available remotely. */ export default function UpdateAlert({ variant, currentVersion, @@ -82,16 +92,15 @@ export default function UpdateAlert({ const discordLauncherUrl = (import.meta.env.VITE_LAUNCHER_RELEASE_DISCORD_URL ?? '').trim() return ( -
- +
{/* Icône */} {cfg.icon} {/* Texte */}
- - {title} - + {title}
@@ -99,11 +108,15 @@ export default function UpdateAlert({ {formatVersion(currentVersion)} )} {currentVersion && } - + {formatVersion(latestVersion)} {latestReleaseDate && ( - · {t('universe.updateAlert.releaseOn', { date: latestReleaseDate })} + + · {t('universe.updateAlert.releaseOn', { date: latestReleaseDate })} + )}
{variant === 'launcher' && discordLauncherUrl && ( @@ -126,14 +139,18 @@ export default function UpdateAlert({ {onDismiss && ( )}
) -} \ No newline at end of file +} diff --git a/src/renderer/components/ui/lore/LoreArticle.tsx b/src/renderer/components/ui/lore/LoreArticle.tsx new file mode 100644 index 0000000..f5aadf1 --- /dev/null +++ b/src/renderer/components/ui/lore/LoreArticle.tsx @@ -0,0 +1,64 @@ +import type React from 'react' +import { useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useLoreStore } from '@stores/lore' +import ReactMarkdown from 'react-markdown' +import remarkGfm from 'remark-gfm' +import rehypeRaw from 'rehype-raw' +import rehypeSanitize from 'rehype-sanitize' + +const loreMarkdownFiles = import.meta.glob('../../../content/lore/*.md', { + query: '?raw', + import: 'default' +}) as Record Promise> + +/** Loads and renders the selected lore markdown article via Vite glob imports. */ +export default function LoreArticle(): React.JSX.Element { + const { t } = useTranslation() + const { current } = useLoreStore() + const [content, setContent] = useState('') + + const articleKey = current ? `../../../content/lore/${current.file}` : null + const loader = articleKey ? loreMarkdownFiles[articleKey] : undefined + const missingFile = Boolean(current && articleKey && !loader) + + useEffect(() => { + if (!current || !loader) return + + let cancelled = false + void loader().then((markdown) => { + if (!cancelled) setContent(markdown) + }) + return () => { + cancelled = true + } + }, [current, loader]) + + if (!current) { + return ( +
+
+ {t('lore.selectArticle')} +
+
+ ) + } + + const title = t(`lore.articles.${current.id}`, { defaultValue: current.id }) + const body = missingFile ? t('lore.fileNotFound', { file: current.file }) : content + + return ( +
+
+
+
+

{title}

+ + {body} + +
+
+
+
+ ) +} diff --git a/src/renderer/components/ui/loreSidebar.tsx b/src/renderer/components/ui/lore/LoreSidebar.tsx similarity index 67% rename from src/renderer/components/ui/loreSidebar.tsx rename to src/renderer/components/ui/lore/LoreSidebar.tsx index d6c3bae..f1c2458 100644 --- a/src/renderer/components/ui/loreSidebar.tsx +++ b/src/renderer/components/ui/lore/LoreSidebar.tsx @@ -1,17 +1,19 @@ -import { useLoreStore } from '@store/lore' +import type React from 'react' +import { useTranslation } from 'react-i18next' +import { useLoreStore } from '@stores/lore' -export default function LoreSidebar() { +/** Sidebar list of lore articles from the lore store. */ +export default function LoreSidebar(): React.JSX.Element { + const { t } = useTranslation() const { articles, current, select } = useLoreStore() return ( -
+

- Lore -

-

- Articles, chroniques, archives. + {t('lore.sidebarTitle')}

+

{t('lore.sidebarSubtitle')}

{articles.map((a) => ( @@ -24,10 +26,9 @@ export default function LoreSidebar() { : 'text-[var(--color-ds-muted)] border-transparent hover:border-[var(--color-ds-border)] hover:bg-[var(--color-ds-surface-hover)] hover:text-[var(--color-ds-text)]' }`} > - {a.title} + {t(`lore.articles.${a.id}`, { defaultValue: a.id })} ))} -
) -} \ No newline at end of file +} diff --git a/src/renderer/components/ui/loreArticle.tsx b/src/renderer/components/ui/loreArticle.tsx deleted file mode 100644 index 6f81532..0000000 --- a/src/renderer/components/ui/loreArticle.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useEffect, useState } from 'react' -import { useLoreStore } from '@store/lore' -import ReactMarkdown from 'react-markdown' -import remarkGfm from 'remark-gfm' -import rehypeRaw from 'rehype-raw' -import rehypeSanitize from 'rehype-sanitize' - -const loreMarkdownFiles = import.meta.glob('../../src/content/lore/*.md', { - query: '?raw', - import: 'default' -}) as Record Promise> - -export default function LoreArticle() { - const { current } = useLoreStore() - const [content, setContent] = useState('') - - useEffect(() => { - if (!current) return - - const key = `../../src/content/lore/${current.file}` - const loader = loreMarkdownFiles[key] - - if (!loader) { - setContent(`⚠️ Fichier introuvable: ${current.file}`) - return - } - - loader().then(setContent) - }, [current]) - - if (!current) { - return ( -
-
- Sélectionne un article du lore -
-
- ) - } - - return ( -
-
-
-
- - {/* TITLE (optionnel override) */} -

{current.title}

- - - {content} - - -
-
-
-
- ) -} \ No newline at end of file diff --git a/src/renderer/components/ui/changelogModal.tsx b/src/renderer/components/ui/overlays/ChangelogModal.tsx similarity index 72% rename from src/renderer/components/ui/changelogModal.tsx rename to src/renderer/components/ui/overlays/ChangelogModal.tsx index 66530fc..5dc4159 100644 --- a/src/renderer/components/ui/changelogModal.tsx +++ b/src/renderer/components/ui/overlays/ChangelogModal.tsx @@ -1,18 +1,20 @@ import { useEffect } from 'react' +import { useTranslation } from 'react-i18next' import ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' import rehypeSanitize from 'rehype-sanitize' type Props = { - open: boolean - title: string - loading?: boolean + open: boolean + title: string + loading?: boolean loadingLabel: string - markdown: string | null - emptyLabel: string - onClose: () => void + markdown: string | null + emptyLabel: string + onClose: () => void } +/** Modal that displays CHANGELOG.md from the game install directory. */ export default function ChangelogModal({ open, title, @@ -22,6 +24,8 @@ export default function ChangelogModal({ emptyLabel, onClose }: Props): React.JSX.Element | null { + const { t } = useTranslation() + useEffect(() => { if (!open) return const onKey = (e: KeyboardEvent): void => { @@ -44,29 +48,34 @@ export default function ChangelogModal({ }} >
e.stopPropagation()} >
-

+

{title}

- {loading && ( -

{loadingLabel}

- )} + {loading &&

{loadingLabel}

} {!loading && (markdown === null || markdown === '') && (

{emptyLabel}

)} diff --git a/src/renderer/components/ui/button.tsx b/src/renderer/components/ui/primitives/Button.tsx similarity index 96% rename from src/renderer/components/ui/button.tsx rename to src/renderer/components/ui/primitives/Button.tsx index 890b372..2011719 100644 --- a/src/renderer/components/ui/button.tsx +++ b/src/renderer/components/ui/primitives/Button.tsx @@ -34,6 +34,7 @@ const variants: Record = { 'hover:bg-[var(--color-ds-surface-hover)] hover:border-[var(--color-ds-border)] hover:text-[var(--color-ds-text)]' } +/** Themed button with primary/secondary/danger/ghost variants. */ export default function Button({ variant = 'secondary', size = 'md', @@ -49,4 +50,3 @@ export default function Button({ /> ) } - diff --git a/src/renderer/components/ui/inputField.tsx b/src/renderer/components/ui/primitives/InputField.tsx similarity index 96% rename from src/renderer/components/ui/inputField.tsx rename to src/renderer/components/ui/primitives/InputField.tsx index afb5b4e..f7b2e95 100644 --- a/src/renderer/components/ui/inputField.tsx +++ b/src/renderer/components/ui/primitives/InputField.tsx @@ -15,6 +15,7 @@ type InputFieldProps = { readOnly?: boolean } +/** Labeled text input with optional action button (used in social forms). */ export default function InputField({ label, value, @@ -74,4 +75,4 @@ export default function InputField({
) -} \ No newline at end of file +} diff --git a/src/renderer/components/ui/discordIcon.tsx b/src/renderer/components/ui/primitives/icons/DiscordIcon.tsx similarity index 80% rename from src/renderer/components/ui/discordIcon.tsx rename to src/renderer/components/ui/primitives/icons/DiscordIcon.tsx index 2eaa9c6..76b5919 100644 --- a/src/renderer/components/ui/discordIcon.tsx +++ b/src/renderer/components/ui/primitives/icons/DiscordIcon.tsx @@ -3,7 +3,11 @@ type Props = { title?: string } -export default function DiscordIcon({ className = 'w-4.5 h-4.5', title = 'Discord' }: Props): React.JSX.Element { +/** Discord logo SVG for login and navbar links. */ +export default function DiscordIcon({ + className = 'w-4.5 h-4.5', + title = 'Discord' +}: Props): React.JSX.Element { return ( - {pulse && ( - - )} - - - ) -} \ No newline at end of file diff --git a/src/renderer/components/ui/friendItem.tsx b/src/renderer/components/ui/social/FriendItem.tsx similarity index 63% rename from src/renderer/components/ui/friendItem.tsx rename to src/renderer/components/ui/social/FriendItem.tsx index d75d1ac..30dcaa8 100644 --- a/src/renderer/components/ui/friendItem.tsx +++ b/src/renderer/components/ui/social/FriendItem.tsx @@ -1,56 +1,49 @@ -import { Friend } from '@store/social' +import { useTranslation } from 'react-i18next' +import { Friend } from '@stores/social' type Props = { friend: Friend } -export default function FriendItem({ friend }: Props) { +/** Compact friend row for the universe social preview panel. */ +export default function FriendItem({ friend }: Props): React.JSX.Element { + const { t } = useTranslation() + const statusColor = friend.status === 'online' ? 'bg-green-500' : friend.status === 'ingame' - ? 'bg-orange-400' - : 'bg-gray-500' + ? 'bg-orange-400' + : 'bg-gray-500' return (
- - {/* Avatar */}
{friend.name.charAt(0)}
- - {/* Status dot */}
- {/* Info */}
- - {friend.name} - + {friend.name} {friend.status === 'ingame' && ( - En jeu • {friend.game} + {t('friendStatus.ingameWithGame', { game: friend.game ?? '' })} )} {friend.status === 'online' && ( - - En ligne - + {t('friendStatus.online')} )} {friend.status === 'offline' && ( - - Hors ligne - + {t('friendStatus.offline')} )}
) -} \ No newline at end of file +} diff --git a/src/renderer/components/ui/friendRow.tsx b/src/renderer/components/ui/social/FriendRow.tsx similarity index 61% rename from src/renderer/components/ui/friendRow.tsx rename to src/renderer/components/ui/social/FriendRow.tsx index 78d1280..ae4529c 100644 --- a/src/renderer/components/ui/friendRow.tsx +++ b/src/renderer/components/ui/social/FriendRow.tsx @@ -1,10 +1,15 @@ +import { useTranslation } from 'react-i18next' + type FriendLike = { name: string status: string game?: string } +/** Friend list row with online/ingame/offline status indicator. */ export function FriendRow({ friend }: { friend: FriendLike }): React.JSX.Element { + const { t } = useTranslation() + const color = friend.status === 'online' ? 'bg-green-500' @@ -12,6 +17,15 @@ export function FriendRow({ friend }: { friend: FriendLike }): React.JSX.Element ? 'bg-orange-400' : 'bg-gray-500' + const statusLabel = + friend.status === 'ingame' && friend.game + ? t('friendStatus.ingameWithGame', { game: friend.game }) + : friend.status === 'online' + ? t('friendStatus.online') + : friend.status === 'offline' + ? t('friendStatus.offline') + : friend.status + return (
@@ -21,16 +35,11 @@ export function FriendRow({ friend }: { friend: FriendLike }): React.JSX.Element
-

{friend.name}

-

- {friend.status === 'ingame' && friend.game - ? `En jeu • ${friend.game}` - : friend.status} -

+

{statusLabel}

) -} \ No newline at end of file +} diff --git a/src/renderer/components/ui/orgaRow.tsx b/src/renderer/components/ui/social/OrgaRow.tsx similarity index 65% rename from src/renderer/components/ui/orgaRow.tsx rename to src/renderer/components/ui/social/OrgaRow.tsx index 5456511..5418ff0 100644 --- a/src/renderer/components/ui/orgaRow.tsx +++ b/src/renderer/components/ui/social/OrgaRow.tsx @@ -1,12 +1,16 @@ import { useState } from 'react' -import type { Orga } from '@store/social' +import { useTranslation } from 'react-i18next' +import type { Orga } from '@stores/social' +import { getSocialErrorMessage } from '@lib/socialErrors' type Props = { orga: Orga onJoin: () => Promise } +/** Organization row with member count and join button when not a member. */ export function OrgaRow({ orga, onJoin }: Props): React.JSX.Element { + const { t } = useTranslation() const [status, setStatus] = useState<'idle' | 'loading' | 'error'>('idle') const [errorMsg, setErrorMsg] = useState('') @@ -15,17 +19,15 @@ export function OrgaRow({ orga, onJoin }: Props): React.JSX.Element { setErrorMsg('') try { await onJoin() - // isMember sera passé à true via le store — pas de setStatus('done') nécessaire - // le composant sera re-rendu avec orga.isMember === true + // Store sets isMember to true — component re-renders with updated orga } catch (err) { setStatus('error') - setErrorMsg(err instanceof Error ? err.message : 'Erreur lors de la tentative.') + setErrorMsg(getSocialErrorMessage(err, t)) } } return (
- {/* Icône orga */}
@@ -37,32 +39,32 @@ export function OrgaRow({ orga, onJoin }: Props): React.JSX.Element { {orga.name} - {orga.members} membre{orga.members > 1 ? 's' : ''} + {t('universe.socialPage.orga.members', { count: orga.members })} - {status === 'error' && ( - {errorMsg} - )} + {status === 'error' && {errorMsg}}
{/* Badge membre ou bouton rejoindre */} {orga.isMember ? ( - + " + > - Membre + {t('universe.socialPage.orga.memberBadge')} ) : ( {/* Refuser */}
) } -// ─── Icônes SVG inline ──────────────────────────────────────────────────────── +// ─── Inline SVG icons ─────────────────────────────────────────────────────── function CheckIcon(): React.JSX.Element { return ( - + ) @@ -110,7 +108,12 @@ function CheckIcon(): React.JSX.Element { function XIcon(): React.JSX.Element { return ( - + ) @@ -118,9 +121,13 @@ function XIcon(): React.JSX.Element { function SpinnerIcon(): React.JSX.Element { return ( - + ) -} \ No newline at end of file +} diff --git a/src/renderer/components/ui/socialSidebar.tsx b/src/renderer/components/ui/social/SocialSidebar.tsx similarity index 69% rename from src/renderer/components/ui/socialSidebar.tsx rename to src/renderer/components/ui/social/SocialSidebar.tsx index 9f4353a..ed1379a 100644 --- a/src/renderer/components/ui/socialSidebar.tsx +++ b/src/renderer/components/ui/social/SocialSidebar.tsx @@ -1,28 +1,28 @@ +import { useTranslation } from 'react-i18next' + type Props = { current: string setCurrent: (v: string) => void } -export default function SocialSidebar({ - current, - setCurrent -}: Props) { - const items = ['friends', 'organizations', 'requests'] +const TAB_KEYS = ['friends', 'organizations', 'requests'] as const - return ( -
+/** Tab sidebar for the social page (friends / orgs / requests). */ +export default function SocialSidebar({ current, setCurrent }: Props): React.JSX.Element { + const { t } = useTranslation() + return ( +

- Social + {t('universe.socialPage.sidebarTitle')}

-

- Amis, organisations, demandes. + {t('universe.socialPage.sidebarSubtitle')}

- {items.map((item) => ( + {TAB_KEYS.map((item) => ( ))}
) -} \ No newline at end of file +} diff --git a/src/renderer/src/content/lore/origins.md b/src/renderer/content/lore/origins.md similarity index 82% rename from src/renderer/src/content/lore/origins.md rename to src/renderer/content/lore/origins.md index bbfd2e7..0611b15 100644 --- a/src/renderer/src/content/lore/origins.md +++ b/src/renderer/content/lore/origins.md @@ -12,4 +12,4 @@ Ils dominaient la réalité avant la fracture. ## La fracture -> Un événement qui a changé l’univers à jamais. \ No newline at end of file +> Un événement qui a changé l’univers à jamais. diff --git a/src/renderer/env.d.ts b/src/renderer/env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/renderer/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/src/renderer/src/hooks/useFitWindowToContent.ts b/src/renderer/hooks/useFitWindowToContent.ts similarity index 61% rename from src/renderer/src/hooks/useFitWindowToContent.ts rename to src/renderer/hooks/useFitWindowToContent.ts index 18b13f2..012c2e7 100644 --- a/src/renderer/src/hooks/useFitWindowToContent.ts +++ b/src/renderer/hooks/useFitWindowToContent.ts @@ -1,17 +1,21 @@ import { useEffect } from 'react' -/** Agrandit la fenêtre si le contenu dépasse la taille de base (min = variables d'env). */ +/** + * Observes layout changes and asks the main process to resize the frameless window + * so content is not clipped (respects min/max dimensions from env). + */ export function useFitWindowToContent(): void { useEffect(() => { let rafId = 0 + /** Measures `#root` and invokes IPC resize on the next animation frame. */ const report = (): void => { cancelAnimationFrame(rafId) rafId = requestAnimationFrame(() => { const root = document.getElementById('root') if (!root) return void window.api.fitWindowToContent({ - width: root.scrollWidth, + width: root.scrollWidth, height: root.scrollHeight }) }) @@ -21,7 +25,12 @@ export function useFitWindowToContent(): void { ro.observe(document.body) const mo = new MutationObserver(report) - mo.observe(document.body, { childList: true, subtree: true, attributes: true, characterData: true }) + mo.observe(document.body, { + childList: true, + subtree: true, + attributes: true, + characterData: true + }) report() diff --git a/src/renderer/i18n/en.json b/src/renderer/i18n/en.json index 499fbf4..a0e3636 100644 --- a/src/renderer/i18n/en.json +++ b/src/renderer/i18n/en.json @@ -1,102 +1,194 @@ -{ - "navbar": { - "home": "Home", - "social": "Social", - "lore": "Lore", - "support": "Donate", - "openWebsite": "Open official website", - "openDiscord": "Open Discord", - "openWiki": "Open wiki", - "donateUnavailable": "Support link not configured", - "quit": "Quit application", - "minimize": "Minimize", - "close": "Close" +{ + "installProgress": { + "connecting": "Connecting to server…", + "checkingUpdates": "Checking for updates…", + "downloading": "Downloading… ({{downloaded}} / {{total}})", + "downloadingIndeterminate": "Downloading… ({{downloaded}})", + "preparing": "Preparing game folder…", + "extracting": "Extracting… ({{current}} / {{total}} files)", + "cleaning": "Cleaning up…", + "completeInstall": "Installation complete — v{{version}}", + "completeUpdate": "Update complete — v{{version}}" + }, + "common": { + "cancel": "Cancel", + "loading": "...", + "close": "Close", + "send": "Send", + "create": "Create" + }, + "navbar": { + "home": "Home", + "social": "Social", + "lore": "Lore", + "support": "Donate", + "openWebsite": "Open official website", + "openDiscord": "Open Discord", + "openWiki": "Open wiki", + "donateUnavailable": "Support link not configured", + "quit": "Quit application", + "minimize": "Minimize", + "close": "Close", + "languageFr": "Français", + "languageEn": "English", + "switchToFrench": "Switch to French", + "switchToEnglish": "Switch to English", + "envUniverse": "Universe", + "envTesting": "Universe Testing", + "brandDiscord": "Discord", + "brandWiki": "Wiki" + }, + "universeTesting": { + "banner": "Testing environment — data is not from the live server" + }, + "lore": { + "sidebarTitle": "Lore", + "sidebarSubtitle": "Articles, chronicles, archives.", + "selectArticle": "Select a lore article", + "fileNotFound": "File not found: {{file}}", + "articles": { + "origins": "Origins" + } + }, + "friendStatus": { + "online": "Online", + "offline": "Offline", + "ingame": "In game", + "ingameWithGame": "In game • {{game}}" + }, + "universe": { + "title": "Universe", + "account": { + "title": "Account", + "disconnected": "Not connected", + "connectedAs": "Logged in as {{username}}", + "login": "Login with Discord", + "logout": "Logout", + "subscription": "Subscription", + "loading": "Connecting...", + "cancel": "Cancel", + "unavailable": "Authentication not available for this environment.", + "unavailableBtn": "Unavailable" }, - "universeTesting": { - "banner": "Testing environment — data is not from the live server" + "updateAlert": { + "dismiss": "Dismiss alert", + "launcher": { + "title": "Launcher update available", + "discordHint": "The new version is available here:", + "discordLink": "Discord" + }, + "game": { + "title": "New game version available" + }, + "releaseOn": "Released {{date}}" }, - "universe": { - "title": "Universe", - "account": { - "title": "Account", - "disconnected": "Not connected", - "connectedAs": "Logged in as {{username}}", - "login": "Login with Discord", - "logout": "Logout", - "subscription": "Subscription", - "loading": "Connecting...", - "cancel": "Cancel", - "unavailable": "Authentication not available for this environment.", - "unavailableBtn": "Unavailable" + "game": { + "title": "Game", + "play": "Play", + "playDisabledMaintenance": "The server is under maintenance — launching the game is disabled.", + "playDisabledUpdate": "A game update is available — install it before playing.", + "playDisabledAuth": "Sign in to launch the game.", + "playDisabledAuthLoading": "Checking your session…", + "playDisabledRunning": "The game is already running.", + "notInstalled": "Game not installed", + "players": "{{count}} players online", + "status": { + "online": "Available", + "degraded": "Issues ongoing", + "offline": "Offline", + "maintenance": "Under maintenance", + "unknown": "Unknown", + "unavailable": "Unavailable" }, - "updateAlert": { - "launcher": { - "title": "Launcher update available", - "discordHint": "The new version is available here:", - "discordLink": "Discord" + "viewStatus": "View status" + }, + "files": { + "title": "Game files", + "version": "Version: {{version}}", + "releaseDate": "Release: {{date}}", + "notInstalled": "Game not installed", + "install": "Install", + "update": "Update", + "verify": "Verify files", + "clearCache": "Clear cache", + "clearCacheToastOk": "Cache cleared.", + "clearCacheToastPartial": "Cache partially cleared (some folders could not be removed).", + "clearCacheToastError": "Could not clear the cache.", + "changelog": "View changelog", + "changelogModalTitle": "Changelog — v{{version}}", + "changelogLoading": "Loading changelog…", + "changelogMissing": "No CHANGELOG.md was found in the install folder (make sure it is included in the game archive).", + "installing": "Installing...", + "installPath": "Install folder", + "installPathPlaceholder": "/home/user/games/dyingstar", + "browse": "Browse", + "unavailable": "Installation not available for this environment.", + "unavailableBtn": "Unavailable" + }, + "social": { + "title": "Social", + "noFriends": "No friends", + "seeAll": "See all", + "notifications": "{{count}} notifications" + }, + "socialPage": { + "sidebarTitle": "Social", + "sidebarSubtitle": "Friends, organizations, requests.", + "friends": "Friends", + "organizations": "Organizations", + "requests": "Requests", + "addFriend": "Add friend", + "createOrga": "Create org", + "createOrgaLong": "Create organization", + "joinOrga": "Join", + "accept": "Accept", + "decline": "Decline", + "tabs": { + "friends": { + "label": "Friends", + "subtitle": "Manage your friends and status." }, - "game": { - "title": "New game version available" + "organizations": { + "label": "Organizations", + "subtitle": "Organizations, members, and invites." }, - "releaseOn": "Released {{date}}" + "requests": { + "label": "Requests", + "subtitle": "Pending friend requests." + } }, - "game": { - "title": "Game", - "play": "Play", - "playDisabledMaintenance": "The server is under maintenance — launching the game is disabled.", - "playDisabledUpdate": "A game update is available — install it before playing.", - "playDisabledAuth": "Sign in to launch the game.", - "playDisabledAuthLoading": "Checking your session…", - "playDisabledRunning": "The game is already running.", - "notInstalled": "Game not installed", - "players": "{{count}} players online", - "status": { - "online": "Available", - "degraded": "Issues ongoing", - "offline": "Offline", - "maintenance": "Under maintenance", - "unknown": "Unknown", - "unavailable": "Unavailable" - }, - "viewStatus": "View status" + "addFriendForm": { + "title": "Add a friend", + "usernameLabel": "Exact username", + "usernamePlaceholder": "Enter a username...", + "success": "Request sent!" + }, + "createOrgaForm": { + "title": "Create an organization", + "nameLabel": "Organization name", + "namePlaceholder": "Enter a unique name...", + "success": "Organization created!" }, - "files": { - "title": "Game files", - "version": "Version: {{version}}", - "releaseDate": "Release: {{date}}", - "notInstalled": "Game not installed", - "install": "Install", - "update": "Update", - "verify": "Verify files", - "clearCache": "Clear cache", - "clearCacheToastOk": "Cache cleared.", - "clearCacheToastPartial": "Cache partially cleared (some folders could not be removed).", - "clearCacheToastError": "Could not clear the cache.", - "changelog": "View changelog", - "changelogModalTitle": "Changelog — v{{version}}", - "changelogLoading": "Loading changelog…", - "changelogMissing": "No CHANGELOG.md was found in the install folder (make sure it is included in the game archive).", - "installing": "Installing...", - "installPath": "Install folder", - "browse": "Browse", - "unavailable": "Installation not available for this environment.", - "unavailableBtn": "Unavailable" + "pendingRequests_one": "{{count}} pending request", + "pendingRequests_other": "{{count}} pending requests", + "emptyFriends": "No friends yet.", + "emptyOrganizations": "No organizations.", + "emptyRequests": "No pending requests.", + "orga": { + "members_one": "{{count}} member", + "members_other": "{{count}} members", + "memberBadge": "Member", + "joinAria": "Join organization {{name}}" }, - "social": { - "title": "Social", - "noFriends": "No friends", - "seeAll": "See all", - "notifications": "{{count}} notifications" + "request": { + "acceptAria": "Accept request from {{name}}", + "declineAria": "Decline request from {{name}}" }, - "socialPage": { - "friends": "Friends", - "organizations": "Organizations", - "requests": "Requests", - "addFriend": "Add friend", - "createOrga": "Create organization", - "joinOrga": "Join organization", - "accept": "Accept", - "decline": "Decline" + "errors": { + "friendRequestFailed": "User not found or request already sent.", + "orgaNameTaken": "This organization name is already taken.", + "joinOrgaFailed": "Could not join this organization." } } - } \ No newline at end of file + } +} diff --git a/src/renderer/i18n/fr.json b/src/renderer/i18n/fr.json index 49d2a57..af40d76 100644 --- a/src/renderer/i18n/fr.json +++ b/src/renderer/i18n/fr.json @@ -1,102 +1,194 @@ { - "navbar": { - "home": "Accueil", - "social": "Social", - "lore": "Lore", - "support": "Faire un don", - "openWebsite": "Ouvrir le site officiel", - "openDiscord": "Ouvrir Discord", - "openWiki": "Ouvrir le wiki", - "donateUnavailable": "Lien de soutien non configuré", - "quit": "Quitter l'application", - "minimize": "Réduire", - "close": "Fermer" + "installProgress": { + "connecting": "Connexion au serveur…", + "checkingUpdates": "Recherche de mises à jour…", + "downloading": "Téléchargement… ({{downloaded}} / {{total}})", + "downloadingIndeterminate": "Téléchargement… ({{downloaded}})", + "preparing": "Préparation du dossier du jeu…", + "extracting": "Extraction… ({{current}} / {{total}} fichiers)", + "cleaning": "Nettoyage…", + "completeInstall": "Installation terminée — v{{version}}", + "completeUpdate": "Mise à jour terminée — v{{version}}" + }, + "common": { + "cancel": "Annuler", + "loading": "...", + "close": "Fermer", + "send": "Envoyer", + "create": "Créer" + }, + "navbar": { + "home": "Accueil", + "social": "Social", + "lore": "Lore", + "support": "Faire un don", + "openWebsite": "Ouvrir le site officiel", + "openDiscord": "Ouvrir Discord", + "openWiki": "Ouvrir le wiki", + "donateUnavailable": "Lien de soutien non configuré", + "quit": "Quitter l'application", + "minimize": "Réduire", + "close": "Fermer", + "languageFr": "Français", + "languageEn": "English", + "switchToFrench": "Passer en français", + "switchToEnglish": "Switch to English", + "envUniverse": "Universe", + "envTesting": "Universe Testing", + "brandDiscord": "Discord", + "brandWiki": "Wiki" + }, + "universeTesting": { + "banner": "Environnement de test — les données ne sont pas celles du serveur live" + }, + "lore": { + "sidebarTitle": "Lore", + "sidebarSubtitle": "Articles, chroniques, archives.", + "selectArticle": "Sélectionne un article du lore", + "fileNotFound": "Fichier introuvable : {{file}}", + "articles": { + "origins": "Origines" + } + }, + "friendStatus": { + "online": "En ligne", + "offline": "Hors ligne", + "ingame": "En jeu", + "ingameWithGame": "En jeu • {{game}}" + }, + "universe": { + "title": "Universe", + "account": { + "title": "Compte", + "disconnected": "Non connecté", + "connectedAs": "Connecté en tant que {{username}}", + "login": "Se connecter avec Discord", + "logout": "Se déconnecter", + "subscription": "Abonnement", + "loading": "Connexion en cours...", + "cancel": "Annuler", + "unavailable": "Authentification non disponible pour cet environnement.", + "unavailableBtn": "Indisponible" }, - "universeTesting": { - "banner": "Environnement de test — les données ne sont pas celles du serveur live" + "updateAlert": { + "dismiss": "Fermer l'alerte", + "launcher": { + "title": "Mise à jour du launcher disponible", + "discordHint": "La nouvelle version est disponible ici :", + "discordLink": "Discord" + }, + "game": { + "title": "Nouvelle version du jeu disponible" + }, + "releaseOn": "Sortie le {{date}}" }, - "universe": { - "title": "Universe", - "account": { - "title": "Compte", - "disconnected": "Non connecté", - "connectedAs": "Connecté en tant que {{username}}", - "login": "Se connecter avec Discord", - "logout": "Se déconnecter", - "subscription": "Abonnement", - "loading": "Connexion en cours...", - "cancel": "Annuler", - "unavailable": "Authentification non disponible pour cet environnement.", - "unavailableBtn": "Indisponible" + "game": { + "title": "Jeu", + "play": "Jouer", + "playDisabledMaintenance": "Le serveur est en maintenance — le lancement du jeu est désactivé.", + "playDisabledUpdate": "Une mise à jour du jeu est disponible — installez-la avant de jouer.", + "playDisabledAuth": "Connectez-vous pour lancer le jeu.", + "playDisabledAuthLoading": "Vérification de la session…", + "playDisabledRunning": "Le jeu est déjà lancé.", + "notInstalled": "Jeu non installé", + "players": "{{count}} joueurs en ligne", + "status": { + "online": "Opérationnel", + "degraded": "Dégradé", + "offline": "Hors ligne", + "maintenance": "En maintenance", + "unknown": "Inconnu", + "unavailable": "Non disponible" }, - "updateAlert": { - "launcher": { - "title": "Mise à jour du launcher disponible", - "discordHint": "La nouvelle version est disponible ici :", - "discordLink": "Discord" + "viewStatus": "Voir le statut" + }, + "files": { + "title": "Fichiers du jeu", + "version": "Version : {{version}}", + "releaseDate": "Release : {{date}}", + "notInstalled": "Jeu non installé", + "install": "Installer", + "update": "Mettre à jour", + "verify": "Vérifier les fichiers", + "clearCache": "Vider le cache", + "clearCacheToastOk": "Cache vidé.", + "clearCacheToastPartial": "Cache partiellement vidé (certains dossiers n'ont pas pu être supprimés).", + "clearCacheToastError": "Impossible de vider le cache.", + "changelog": "Voir le changelog", + "changelogModalTitle": "Changelog — v{{version}}", + "changelogLoading": "Chargement du changelog…", + "changelogMissing": "Aucun fichier CHANGELOG.md n'a été trouvé dans l'installation (vérifie qu'il est bien inclus dans l'archive du jeu).", + "installing": "Installation en cours...", + "installPath": "Répertoire d'installation", + "installPathPlaceholder": "/home/utilisateur/jeux/dyingstar", + "browse": "Parcourir", + "unavailable": "Installation non disponible pour cet environnement.", + "unavailableBtn": "Indisponible" + }, + "social": { + "title": "Social", + "noFriends": "Aucun ami", + "seeAll": "Voir tout", + "notifications": "{{count}} notifications" + }, + "socialPage": { + "sidebarTitle": "Social", + "sidebarSubtitle": "Amis, organisations, demandes.", + "friends": "Amis", + "organizations": "Organisations", + "requests": "Demandes", + "addFriend": "Ajouter un ami", + "createOrga": "Créer une orga", + "createOrgaLong": "Créer une organisation", + "joinOrga": "Rejoindre", + "accept": "Accepter", + "decline": "Refuser", + "tabs": { + "friends": { + "label": "Amis", + "subtitle": "Gère ta liste d'amis et ton statut." }, - "game": { - "title": "Nouvelle version du jeu disponible" + "organizations": { + "label": "Organisations", + "subtitle": "Organisations, membres et invitations." }, - "releaseOn": "Sortie le {{date}}" + "requests": { + "label": "Demandes", + "subtitle": "Demandes d'amis en attente." + } }, - "game": { - "title": "Jeu", - "play": "Jouer", - "playDisabledMaintenance": "Le serveur est en maintenance — le lancement du jeu est désactivé.", - "playDisabledUpdate": "Une mise à jour du jeu est disponible — installez-la avant de jouer.", - "playDisabledAuth": "Connectez-vous pour lancer le jeu.", - "playDisabledAuthLoading": "Vérification de la session…", - "playDisabledRunning": "Le jeu est déjà lancé.", - "notInstalled": "Jeu non installé", - "players": "{{count}} joueurs en ligne", - "status": { - "online": "Opérationnel", - "degraded": "Dégradé", - "offline": "Hors ligne", - "maintenance": "En maintenance", - "unknown": "Inconnu", - "unavailable": "Non disponible" - }, - "viewStatus": "Voir le statut" + "addFriendForm": { + "title": "Ajouter un ami", + "usernameLabel": "Pseudo exact", + "usernamePlaceholder": "Entrez un pseudo...", + "success": "Demande envoyée !" + }, + "createOrgaForm": { + "title": "Créer une organisation", + "nameLabel": "Nom de l'organisation", + "namePlaceholder": "Entrez un nom unique...", + "success": "Organisation créée !" }, - "files": { - "title": "Fichiers du jeu", - "version": "Version : {{version}}", - "releaseDate": "Release : {{date}}", - "notInstalled": "Jeu non installé", - "install": "Installer", - "update": "Mettre à jour", - "verify": "Vérifier les fichiers", - "clearCache": "Vider le cache", - "clearCacheToastOk": "Cache vidé.", - "clearCacheToastPartial": "Cache partiellement vidé (certains dossiers n’ont pas pu être supprimés).", - "clearCacheToastError": "Impossible de vider le cache.", - "changelog": "Voir le changelog", - "changelogModalTitle": "Changelog — v{{version}}", - "changelogLoading": "Chargement du changelog…", - "changelogMissing": "Aucun fichier CHANGELOG.md n’a été trouvé dans l’installation (vérifie qu’il est bien inclus dans l’archive du jeu).", - "installing": "Installation en cours...", - "installPath": "Répertoire d'installation", - "browse": "Parcourir", - "unavailable": "Installation non disponible pour cet environnement.", - "unavailableBtn": "Indisponible" + "pendingRequests_one": "{{count}} demande en attente", + "pendingRequests_other": "{{count}} demandes en attente", + "emptyFriends": "Aucun ami pour le moment.", + "emptyOrganizations": "Aucune organisation.", + "emptyRequests": "Aucune demande en attente.", + "orga": { + "members_one": "{{count}} membre", + "members_other": "{{count}} membres", + "memberBadge": "Membre", + "joinAria": "Rejoindre l'organisation {{name}}" }, - "social": { - "title": "Social", - "noFriends": "Aucun ami", - "seeAll": "Voir tout", - "notifications": "{{count}} notifications" + "request": { + "acceptAria": "Accepter la demande de {{name}}", + "declineAria": "Refuser la demande de {{name}}" }, - "socialPage": { - "friends": "Amis", - "organizations": "Organisations", - "requests": "Requêtes", - "addFriend": "Ajouter un ami", - "createOrga": "Créer une organisation", - "joinOrga": "Rejoindre", - "accept": "Accepter", - "decline": "Refuser" + "errors": { + "friendRequestFailed": "Utilisateur introuvable ou demande déjà envoyée.", + "orgaNameTaken": "Ce nom d'organisation est déjà pris.", + "joinOrgaFailed": "Erreur lors de la tentative." } } - } \ No newline at end of file + } +} diff --git a/src/renderer/i18n/index.ts b/src/renderer/i18n/index.ts new file mode 100644 index 0000000..e42865a --- /dev/null +++ b/src/renderer/i18n/index.ts @@ -0,0 +1,39 @@ +/** i18next instance: FR/EN translations for the renderer. */ +import i18n from 'i18next' +import { initReactI18next } from 'react-i18next' + +import en from '../i18n/en.json' +import fr from '../i18n/fr.json' + +const STORAGE_KEY = 'ds-language' + +function detectLanguage(): 'en' | 'fr' { + if (typeof localStorage !== 'undefined') { + const stored = localStorage.getItem(STORAGE_KEY) + if (stored === 'en' || stored === 'fr') return stored + } + if (typeof navigator !== 'undefined' && navigator.language.toLowerCase().startsWith('fr')) { + return 'fr' + } + return 'en' +} + +void i18n.use(initReactI18next).init({ + resources: { + en: { translation: en }, + fr: { translation: fr } + }, + lng: detectLanguage(), + fallbackLng: 'en', + interpolation: { + escapeValue: false + } +}) + +i18n.on('languageChanged', (lng) => { + if (typeof localStorage !== 'undefined') { + localStorage.setItem(STORAGE_KEY, lng) + } +}) + +export default i18n diff --git a/src/renderer/index.html b/src/renderer/index.html index 1a36909..1d065f0 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -12,6 +12,6 @@
- + diff --git a/src/renderer/lib/env.ts b/src/renderer/lib/env.ts new file mode 100644 index 0000000..a4e88b4 --- /dev/null +++ b/src/renderer/lib/env.ts @@ -0,0 +1,51 @@ +import type { Env } from '@shared/types/env' + +/** Returns a trimmed env string or empty when unset. */ +export function envString(value: string | undefined): string { + return (value ?? '').trim() +} + +/** Status page URL for the given game environment. */ +export function statusPageUrlForEnv(env: Env): string { + const raw = + env === 'universe' + ? import.meta.env.VITE_STATUS_PAGE_UNIVERSE + : import.meta.env.VITE_STATUS_PAGE_TESTING + return envString(raw) +} + +/** Server status poll interval in minutes (clamped 1 … 1440). */ +export function pollIntervalMinutes(): number { + const raw = import.meta.env.VITE_SERVER_STATUS_POLL_MINUTES ?? '5' + let n = Number.parseFloat(String(raw).trim()) + if (!Number.isFinite(n) || n < 1) n = 5 + if (n > 24 * 60) n = 24 * 60 + return n +} + +/** External navigation link URLs for the navbar. */ +export function navUrls(): { + website: string + discord: string + wiki: string + donate: string +} { + return { + website: envString(import.meta.env.VITE_NAV_WEBSITE_URL), + discord: envString(import.meta.env.VITE_NAV_DISCORD_URL), + wiki: envString(import.meta.env.VITE_NAV_WIKI_URL), + donate: envString(import.meta.env.VITE_NAV_DONATE_URL) + } +} + +/** Toast notification duration in milliseconds. */ +export function toastDurationMs(): number { + const n = Number(import.meta.env.VITE_UI_TOAST_DURATION_MS ?? '3800') + return Number.isFinite(n) && n > 0 ? n : 3800 +} + +/** Auto-close delay for the social side panel in milliseconds. */ +export function socialPanelAutoCloseMs(): number { + const n = Number(import.meta.env.VITE_UI_SOCIAL_PANEL_CLOSE_MS ?? '1200') + return Number.isFinite(n) && n > 0 ? n : 1200 +} diff --git a/src/renderer/lib/formatInstallProgress.ts b/src/renderer/lib/formatInstallProgress.ts new file mode 100644 index 0000000..25f32cc --- /dev/null +++ b/src/renderer/lib/formatInstallProgress.ts @@ -0,0 +1,44 @@ +import type { TFunction } from 'i18next' +import type { InstallProgressLabel } from '@shared/types/installProgress' + +function formatBytes(bytes: number): string { + if (bytes < 1024) return `${bytes} B` + if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB` + return `${(bytes / (1024 * 1024)).toFixed(1)} MB` +} + +/** Maps a structured install progress event to a localized label. */ +export function formatInstallProgress(t: TFunction, label: InstallProgressLabel | null): string { + if (!label) return '' + + switch (label.key) { + case 'connecting': + return t('installProgress.connecting') + case 'checkingUpdates': + return t('installProgress.checkingUpdates') + case 'downloading': + return t('installProgress.downloading', { + downloaded: formatBytes(label.downloaded), + total: formatBytes(label.total) + }) + case 'downloadingIndeterminate': + return t('installProgress.downloadingIndeterminate', { + downloaded: formatBytes(label.downloaded) + }) + case 'preparing': + return t('installProgress.preparing') + case 'extracting': + return t('installProgress.extracting', { + current: label.current, + total: label.total + }) + case 'cleaning': + return t('installProgress.cleaning') + case 'completeInstall': + return t('installProgress.completeInstall', { version: label.version }) + case 'completeUpdate': + return t('installProgress.completeUpdate', { version: label.version }) + default: + return '' + } +} diff --git a/src/renderer/src/lib/formatReleaseDate.ts b/src/renderer/lib/formatReleaseDate.ts similarity index 83% rename from src/renderer/src/lib/formatReleaseDate.ts rename to src/renderer/lib/formatReleaseDate.ts index 052c269..ee821fd 100644 --- a/src/renderer/src/lib/formatReleaseDate.ts +++ b/src/renderer/lib/formatReleaseDate.ts @@ -1,5 +1,6 @@ /** - * Affiche une date de release en jj/MM/aaaa (locale FR attendue dans l’UI). + * Formats a release date for display as DD/MM/YYYY (French UI locale). + * Accepts ISO dates, YYYYMMDDHHMMSS build ids, and parseable date strings. */ export function formatReleaseDateDisplay(raw: string | null | undefined): string { if (raw == null || raw === '') return '—' diff --git a/src/renderer/src/lib/isGameUpdateAvailable.ts b/src/renderer/lib/isGameUpdateAvailable.ts similarity index 65% rename from src/renderer/src/lib/isGameUpdateAvailable.ts rename to src/renderer/lib/isGameUpdateAvailable.ts index 7d57e9c..c66f6af 100644 --- a/src/renderer/src/lib/isGameUpdateAvailable.ts +++ b/src/renderer/lib/isGameUpdateAvailable.ts @@ -1,4 +1,6 @@ -/** True si une version distante du jeu est strictement plus récente que la locale. */ +/** + * Returns true when a remote game version is strictly newer than the locally installed one. + */ export function isGameUpdateAvailable( installed: boolean, localVersion: string | null, @@ -8,6 +10,9 @@ export function isGameUpdateAvailable( installed && latestRemoteVersion !== null && localVersion !== null && - latestRemoteVersion.localeCompare(localVersion, undefined, { numeric: true, sensitivity: 'base' }) > 0 + latestRemoteVersion.localeCompare(localVersion, undefined, { + numeric: true, + sensitivity: 'base' + }) > 0 ) } diff --git a/src/renderer/lib/socialErrors.ts b/src/renderer/lib/socialErrors.ts new file mode 100644 index 0000000..d0ac45d --- /dev/null +++ b/src/renderer/lib/socialErrors.ts @@ -0,0 +1,29 @@ +/** Error codes thrown by the social store for i18n lookup in the UI. */ +export const SOCIAL_ERROR = { + ORGA_NAME_TAKEN: 'orgaNameTaken', + FRIEND_REQUEST_FAILED: 'friendRequestFailed' +} as const + +export type SocialErrorCode = (typeof SOCIAL_ERROR)[keyof typeof SOCIAL_ERROR] + +export class SocialStoreError extends Error { + constructor(public readonly code: SocialErrorCode) { + super(code) + this.name = 'SocialStoreError' + } +} + +/** Maps a social store error to a translated message, or uses the fallback i18n key. */ +export function getSocialErrorMessage( + err: unknown, + translate: (key: string) => string, + fallbackKey = 'universe.socialPage.errors.joinOrgaFailed' +): string { + if (err instanceof SocialStoreError) { + return translate(`universe.socialPage.errors.${err.code}`) + } + if (err instanceof Error && err.message) { + return err.message + } + return translate(fallbackKey) +} diff --git a/src/renderer/src/main.tsx b/src/renderer/main.tsx similarity index 90% rename from src/renderer/src/main.tsx rename to src/renderer/main.tsx index 6afdb86..d94d025 100644 --- a/src/renderer/src/main.tsx +++ b/src/renderer/main.tsx @@ -3,7 +3,7 @@ import './i18n' import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' -import App from './app' +import App from './App' createRoot(document.getElementById('root')!).render( diff --git a/src/renderer/src/app.tsx b/src/renderer/src/app.tsx deleted file mode 100644 index 51bc16c..0000000 --- a/src/renderer/src/app.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Shell from '@components/layout/shell' -import { useEffect } from 'react' -import { useVersionStore } from '@store/version' -import { useAvailabilityStore } from '@store/availability' - -function useAppStartup(): void { - const { checkVersions, checked: versionChecked } = useVersionStore() - const { checkAvailability, checked: availChecked } = useAvailabilityStore() - - useEffect(() => { - if (!availChecked) checkAvailability() - if (!versionChecked) checkVersions() - }, []) -} - -function App(): React.JSX.Element { - useAppStartup() - return -} - -export default App \ No newline at end of file diff --git a/src/renderer/src/assets/electron.svg b/src/renderer/src/assets/electron.svg deleted file mode 100644 index 45ef09c..0000000 --- a/src/renderer/src/assets/electron.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/renderer/src/assets/main.css b/src/renderer/src/assets/main.css deleted file mode 100644 index 6612bb3..0000000 --- a/src/renderer/src/assets/main.css +++ /dev/null @@ -1,153 +0,0 @@ -@import "tailwindcss"; - -@font-face { - font-family: 'Poppins'; - src: url('./fonts/Poppins-Regular.ttf') format('truetype'); - font-weight: 400; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: 'Poppins'; - src: url('./fonts/Poppins-Italic.ttf') format('truetype'); - font-weight: 400; - font-style: italic; - font-display: swap; -} - -@font-face { - font-family: 'Poppins'; - src: url('./fonts/Poppins-Bold.ttf') format('truetype'); - font-weight: 700; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: 'Poppins'; - src: url('./fonts/Poppins-BoldItalic.ttf') format('truetype'); - font-weight: 700; - font-style: italic; - font-display: swap; -} - -/* Tokens couleurs DyingStar — à ajuster avec la vraie charte */ -@theme { - --font-sans: 'Poppins', system-ui, sans-serif; - --color-ds-bg: #0d0d14; - --color-ds-surface: #16161f; - --color-ds-surface-hover: rgba(255,255,255,0.05); - --color-ds-border: #2a2a3a; - --color-ds-accent: rgb(255, 186, 8,0.8); - --color-ds-text: rgb(255, 186, 8); - --color-ds-muted: #6b6b80; - --color-ds-success: #22c55e; - --color-ds-warning: #f59e0b; - --color-ds-danger: #ef4444; -} - -html, body { - min-height: 100%; - width: 100%; - background-color: var(--color-ds-bg); - color: var(--color-ds-text); - font-family: var(--font-sans); - overflow: hidden; -} - -#root { - min-height: 100%; - width: 100%; - display: flex; - flex-direction: column; -} - -/* Barre de titre custom (fenêtre sans cadre OS) */ -.app-drag { - -webkit-app-region: drag; -} - -.app-no-drag { - -webkit-app-region: no-drag; -} - -.lore-markdown { - color: var(--color-ds-text); - font-size: 15px; - line-height: 1.75; - max-width: 850px; - margin: 0 auto; -} - -/* TITRES */ -.lore-markdown h1 { - font-size: 2.4rem; - font-weight: 800; - margin: 2rem 0 1rem; - letter-spacing: -0.02em; -} - -.lore-markdown h2 { - font-size: 1.6rem; - font-weight: 700; - margin: 2rem 0 0.8rem; - color: var(--color-ds-text); -} - -.lore-markdown h3 { - font-size: 1.2rem; - font-weight: 600; - margin: 1.5rem 0 0.6rem; - color: var(--color-ds-muted); -} - -/* PARAGRAPHES */ -.lore-markdown p { - margin: 0.8rem 0; - color: var(--color-ds-text); -} - -/* BLOCKQUOTE (style Medium) */ -.lore-markdown blockquote { - border-left: 3px solid var(--color-ds-accent); - padding: 0.8rem 1rem; - margin: 1.5rem 0; - background: rgba(255,255,255,0.03); - border-radius: 8px; - font-style: italic; - color: var(--color-ds-muted); -} - -/* LISTES */ -.lore-markdown ul { - padding-left: 1.5rem; - margin: 1rem 0; -} - -.lore-markdown li { - margin: 0.4rem 0; -} - -/* IMAGES */ -.lore-markdown img { - width: 100%; - border-radius: 12px; - margin: 1.5rem 0; - box-shadow: 0 10px 30px rgba(0,0,0,0.3); -} - -/* CODE BLOCK */ -.lore-markdown code { - background: rgba(255,255,255,0.06); - padding: 2px 6px; - border-radius: 6px; - font-size: 0.9em; -} - -.lore-markdown pre { - background: rgba(0,0,0,0.4); - padding: 1rem; - border-radius: 12px; - overflow-x: auto; -} \ No newline at end of file diff --git a/src/renderer/src/assets/wavy-lines.svg b/src/renderer/src/assets/wavy-lines.svg deleted file mode 100644 index d08c611..0000000 --- a/src/renderer/src/assets/wavy-lines.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/renderer/src/components/Versions.tsx b/src/renderer/src/components/Versions.tsx deleted file mode 100644 index 37a9ff0..0000000 --- a/src/renderer/src/components/Versions.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { useState } from 'react' - -function Versions(): React.JSX.Element { - const [versions] = useState(window.electron.process.versions) - - return ( -
    -
  • Electron v{versions.electron}
  • -
  • Chromium v{versions.chrome}
  • -
  • Node v{versions.node}
  • -
- ) -} - -export default Versions diff --git a/src/renderer/src/env.d.ts b/src/renderer/src/env.d.ts deleted file mode 100644 index 77cda03..0000000 --- a/src/renderer/src/env.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -/// - -interface ImportMetaEnv { - /** Page de statut (prod). Vide tant que non défini → bouton désactivé. */ - readonly VITE_STATUS_PAGE_UNIVERSE: string - /** Page de statut (test / preprod). */ - readonly VITE_STATUS_PAGE_TESTING: string - /** Intervalle de rafraîchissement statut serveur + joueurs (minutes). Défaut 5. */ - readonly VITE_SERVER_STATUS_POLL_MINUTES: string - /** Lien Discord où récupérer la nouvelle version du launcher (bandeau mise à jour). */ - readonly VITE_LAUNCHER_RELEASE_DISCORD_URL: string - /** Liens barre de navigation (vide → bouton désactivé). */ - readonly VITE_NAV_WEBSITE_URL: string - readonly VITE_NAV_DISCORD_URL: string - readonly VITE_NAV_WIKI_URL: string - readonly VITE_NAV_DONATE_URL: string - /** ID Cachet composant statut (prod). Défaut 3 si absent ou invalide. */ - readonly VITE_STATUS_COMPONENT_ID_UNIVERSE: string - /** ID Cachet composant statut (testing). Défaut 3 si absent ou invalide. */ - readonly VITE_STATUS_COMPONENT_ID_TESTING: string - /** ID Cachet métrique joueurs (prod). Défaut 2 si absent ou invalide. */ - readonly VITE_STATUS_METRIC_ID_UNIVERSE: string - /** ID Cachet métrique joueurs (testing). Défaut 2 si absent ou invalide. */ - readonly VITE_STATUS_METRIC_ID_TESTING: string -} - -interface ImportMeta { - readonly env: ImportMetaEnv -} \ No newline at end of file diff --git a/src/renderer/src/i18n.ts b/src/renderer/src/i18n.ts deleted file mode 100644 index 6f3cec9..0000000 --- a/src/renderer/src/i18n.ts +++ /dev/null @@ -1,21 +0,0 @@ -import i18n from "i18next" -import { initReactI18next } from "react-i18next" - -import en from "../i18n/en.json" -import fr from "../i18n/fr.json" - -i18n - .use(initReactI18next) - .init({ - resources: { - en: { translation: en }, - fr: { translation: fr } - }, - lng: "en", // default language - fallbackLng: "fr", // fallback language - interpolation: { - escapeValue: false - } - }) - -export default i18n \ No newline at end of file diff --git a/src/renderer/store/env.ts b/src/renderer/store/env.ts deleted file mode 100644 index f8b2c3d..0000000 --- a/src/renderer/store/env.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { create } from 'zustand' - -export type Env = 'universe' | 'universe-testing' - -interface EnvState { - activeEnv: Env - setEnv: (env: Env) => void -} - -export const useEnvStore = create((set) => ({ - activeEnv: 'universe', - setEnv: (env) => set({ activeEnv: env }) -})) \ No newline at end of file diff --git a/src/renderer/store/social.ts b/src/renderer/store/social.ts deleted file mode 100644 index b209258..0000000 --- a/src/renderer/store/social.ts +++ /dev/null @@ -1,235 +0,0 @@ -import { create } from 'zustand' -import { useEnvStore, type Env } from './env' - -// ─── Types ──────────────────────────────────────────────────────────────────── - -export type FriendStatus = 'online' | 'offline' | 'ingame' - -export type Friend = { - id: string - name: string - status: FriendStatus - game?: string - avatar?: string -} - -export type Orga = { - id: string - name: string - members: number - isMember: boolean // ← l'API indique si l'utilisateur est déjà membre -} - -export type FriendRequest = { - id: string - name: string -} - -type EnvSocialData = { - friends: Friend[] - orgas: Orga[] - requests: FriendRequest[] - loaded: boolean -} - -type SocialState = { - data: Record - - fetchAll: () => Promise - - // Amis - addFriend: (username: string) => Promise - removeFriend: (id: string) => void - - // Demandes - acceptRequest: (id: string) => Promise - declineRequest: (id: string) => Promise - - // Organisations - joinOrga: (id: string) => Promise - createOrga: (name: string) => Promise -} - -// ─── Valeurs par défaut ─────────────────────────────────────────────────────── - -const defaultEnvData: EnvSocialData = { - friends: [], - orgas: [], - requests: [], - loaded: false -} - -const defaultData: Record = { - 'universe': { ...defaultEnvData }, - 'universe-testing': { ...defaultEnvData } -} - -// ─── Helper ─────────────────────────────────────────────────────────────────── - -type SetFn = (fn: (s: SocialState) => Partial) => void - -function patchEnv(set: SetFn, env: Env, patch: Partial): void { - set((s) => ({ - data: { ...s.data, [env]: { ...s.data[env], ...patch } } - })) -} - -// ─── Store ──────────────────────────────────────────────────────────────────── - -export const useSocialStore = create((set, get) => ({ - data: defaultData, - - // ── Chargement ───────────────────────────────────────────────────────────── - - fetchAll: async () => { - const env = useEnvStore.getState().activeEnv - - // TODO: vrais appels API selon l'env - // const [friends, orgas, requests] = await Promise.all([ - // fetch(`${API_BASE[env]}/friends`).then(r => r.json()), - // fetch(`${API_BASE[env]}/organizations`).then(r => r.json()), // isMember inclus - // fetch(`${API_BASE[env]}/friend-requests`).then(r => r.json()), - // ]) - - await new Promise((r) => setTimeout(r, 500)) - - const mockData: Record = { - 'universe': { - friends: [ - { id: '1', name: 'Aurel', status: 'online' }, - { id: '2', name: 'Kira', status: 'ingame', game: 'Universe' }, - { id: '3', name: 'Noah', status: 'offline' } - ], - orgas: [ - { id: '1', name: 'Nova Corp', members: 12, isMember: true }, - { id: '2', name: 'Galaxy Team', members: 5, isMember: false }, - { id: '3', name: 'Void Squad', members: 8, isMember: false } - ], - requests: [ - { id: '1', name: 'Zed' }, - { id: '2', name: 'Mira' } - ], - loaded: true - }, - 'universe-testing': { - friends: [ - { id: '1', name: 'TestUser1', status: 'online' }, - { id: '2', name: 'TestUser2', status: 'ingame', game: 'Universe Testing' } - ], - orgas: [ - { id: '1', name: 'Test Squad', members: 3, isMember: false } - ], - requests: [], - loaded: true - } - } - - patchEnv(set, env, mockData[env]) - }, - - // ── Amis ─────────────────────────────────────────────────────────────────── - - addFriend: async (username: string) => { - const env = useEnvStore.getState().activeEnv - const trimmed = username.trim() - if (!trimmed) return - - // TODO: appel API - // const res = await fetch(`${API_BASE[env]}/friend-requests`, { - // method: 'POST', body: JSON.stringify({ username: trimmed }) - // }) - // if (!res.ok) throw new Error('Utilisateur introuvable ou demande déjà envoyée.') - - await new Promise((r) => setTimeout(r, 600)) - console.log(`[SocialStore] Demande envoyée à "${trimmed}" sur env: ${env}`) - }, - - removeFriend: (id: string) => { - const env = useEnvStore.getState().activeEnv - const { friends } = get().data[env] - - // TODO: appel API DELETE /friends/:id - - patchEnv(set, env, { friends: friends.filter((f) => f.id !== id) }) - }, - - // ── Demandes d'amis ──────────────────────────────────────────────────────── - - acceptRequest: async (id: string) => { - const env = useEnvStore.getState().activeEnv - const { friends, requests } = get().data[env] - const req = requests.find((r) => r.id === id) - if (!req) return - - // TODO: appel API POST /friend-requests/:id/accept - // await fetch(`${API_BASE[env]}/friend-requests/${id}/accept`, { method: 'POST' }) - - await new Promise((r) => setTimeout(r, 400)) - - patchEnv(set, env, { - requests: requests.filter((r) => r.id !== id), - friends: [...friends, { id: req.id, name: req.name, status: 'offline' }] - }) - }, - - declineRequest: async (id: string) => { - const env = useEnvStore.getState().activeEnv - const { requests } = get().data[env] - - // TODO: appel API POST /friend-requests/:id/decline - // await fetch(`${API_BASE[env]}/friend-requests/${id}/decline`, { method: 'POST' }) - - await new Promise((r) => setTimeout(r, 300)) - - patchEnv(set, env, { requests: requests.filter((r) => r.id !== id) }) - }, - - // ── Organisations ────────────────────────────────────────────────────────── - - joinOrga: async (id: string) => { - const env = useEnvStore.getState().activeEnv - const { orgas } = get().data[env] - - // TODO: appel API POST /organizations/:id/join - // const res = await fetch(`${API_BASE[env]}/organizations/${id}/join`, { method: 'POST' }) - // if (!res.ok) throw new Error('Impossible de rejoindre cette organisation.') - - await new Promise((r) => setTimeout(r, 500)) - - patchEnv(set, env, { - orgas: orgas.map((o) => - o.id === id ? { ...o, isMember: true, members: o.members + 1 } : o - ) - }) - }, - - createOrga: async (name: string) => { - const env = useEnvStore.getState().activeEnv - const trimmed = name.trim() - if (!trimmed) return - - // TODO: appel API POST /organizations - // const res = await fetch(`${API_BASE[env]}/organizations`, { - // method: 'POST', body: JSON.stringify({ name: trimmed }) - // }) - // const json = await res.json() - // if (json === false || !json.success) throw new Error('Ce nom d\'organisation est déjà pris.') - - await new Promise((r) => setTimeout(r, 600)) - - // Simulation : "DyingStar" est un nom déjà pris - if (trimmed.toLowerCase() === 'dyingstar') { - throw new Error('Ce nom d\'organisation est déjà pris.') - } - - const { orgas } = get().data[env] - const newOrga: Orga = { - id: `orga-${Date.now()}`, - name: trimmed, - members: 1, - isMember: true - } - - patchEnv(set, env, { orgas: [...orgas, newOrga] }) - } -})) \ No newline at end of file diff --git a/src/renderer/store/version.ts b/src/renderer/store/version.ts deleted file mode 100644 index 112fb2f..0000000 --- a/src/renderer/store/version.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { create } from 'zustand' -import type { Env } from './env' - -// ─── Types ──────────────────────────────────────────────────────────────────── - -export type GameVersionInfo = { - version: string | null - releaseDate: string | null -} - -type VersionState = { - // Launcher - currentLauncherVersion: string - latestLauncherVersion: string | null - latestLauncherReleaseDate: string | null - launcherUpdateAvailable: boolean - - // Jeu par env — version ET date de la release distante - latestGameVersions: Record - - checking: boolean - checked: boolean - - checkVersions: () => Promise -} - -// ─── Valeurs par défaut ─────────────────────────────────────────────────────── - -const defaultGameVersionInfo: GameVersionInfo = { version: null, releaseDate: null } - -// ─── Store ──────────────────────────────────────────────────────────────────── - -export const useVersionStore = create((set) => ({ - currentLauncherVersion: '', - latestLauncherVersion: null, - latestLauncherReleaseDate: null, - launcherUpdateAvailable: false, - - latestGameVersions: { - 'universe': { ...defaultGameVersionInfo }, - 'universe-testing': { ...defaultGameVersionInfo } - }, - - checking: false, - checked: false, - - checkVersions: async () => { - set({ checking: true }) - try { - const result = await window.api.checkVersions() - set({ - currentLauncherVersion: result.currentLauncherVersion, - latestLauncherVersion: result.latestLauncherVersion, - latestLauncherReleaseDate: result.latestLauncherReleaseDate, - launcherUpdateAvailable: result.launcherUpdateAvailable, - latestGameVersions: result.latestGameVersions, - checking: false, - checked: true - }) - } catch (err) { - console.error('[VersionStore] Échec du check :', err) - set({ checking: false, checked: true }) - } - } -})) \ No newline at end of file diff --git a/src/renderer/store/account.ts b/src/renderer/stores/account.ts similarity index 54% rename from src/renderer/store/account.ts rename to src/renderer/stores/account.ts index b94e12f..6bc5bb6 100644 --- a/src/renderer/store/account.ts +++ b/src/renderer/stores/account.ts @@ -1,79 +1,75 @@ import { create } from 'zustand' import { useEnvStore, type Env } from './env' -// ─── Types ──────────────────────────────────────────────────────────────────── - type AccountStatus = 'connected' | 'disconnected' | 'loading' type EnvAccountData = { - status: AccountStatus + status: AccountStatus username?: string - email?: string + email?: string } type AccountState = { data: Record - - login: () => Promise - logout: () => Promise + /** Opens OAuth login in the browser for the active environment. */ + login: () => Promise + /** Logs out and clears local session for the active environment. */ + logout: () => Promise + /** Cancels an in-progress login attempt (resets loading state). */ cancelLogin: () => void } -// ─── Valeurs par défaut ─────────────────────────────────────────────────────── - const defaultEnvData: EnvAccountData = { - status: 'disconnected', - username: undefined, - email: undefined + status: 'disconnected', + username: undefined, + email: undefined } const defaultData: Record = { - 'universe': { ...defaultEnvData }, + universe: { ...defaultEnvData }, 'universe-testing': { ...defaultEnvData } } -// ─── Helper ─────────────────────────────────────────────────────────────────── - type SetFn = (fn: (s: AccountState) => Partial) => void +/** Merges partial account fields for one environment into the store. */ function patchEnv(set: SetFn, env: Env, patch: Partial): void { set((s) => ({ data: { ...s.data, [env]: { ...s.data[env], ...patch } } })) } -// ─── Store ──────────────────────────────────────────────────────────────────── - +/** + * Per-environment Discord/Keycloak auth state and login actions. + */ export const useAccountStore = create((set) => { - - // Écoute les changements d'état auth envoyés depuis le main process. - // Le payload inclut maintenant l'env pour mettre à jour le bon slot. + // Main process pushes final auth result after OAuth callback window.api.onAuthStateChanged((data) => { if (data.status === 'connected') { patchEnv(set, data.env, { - status: 'connected', + status: 'connected', username: data.user.username, - email: data.user.email + email: data.user.email }) } else { console.error('[AccountStore] Auth error:', data.error) patchEnv(set, data.env, { - status: 'disconnected', + status: 'disconnected', username: undefined, - email: undefined + email: undefined }) } }) - // Restauration de session au démarrage — pour chaque env séparément + // Restore persisted sessions on startup (one request per env) const envs: Env[] = ['universe', 'universe-testing'] envs.forEach((env) => { window.api.authLoadUser(env).then((user) => { if (user) { patchEnv(set, env, { - status: 'connected', + status: 'connected', username: user.username, - email: user.email + email: user.email }) } }) @@ -87,7 +83,7 @@ export const useAccountStore = create((set) => { patchEnv(set, env, { status: 'loading' }) try { await window.api.authLogin(env) - // La mise à jour finale arrive via onAuthStateChanged + // Connected state is applied via onAuthStateChanged } catch { patchEnv(set, env, { status: 'disconnected' }) } @@ -104,4 +100,4 @@ export const useAccountStore = create((set) => { patchEnv(set, env, { status: 'disconnected' }) } } -}) \ No newline at end of file +}) diff --git a/src/renderer/store/availability.ts b/src/renderer/stores/availability.ts similarity index 58% rename from src/renderer/store/availability.ts rename to src/renderer/stores/availability.ts index 848b97a..2b99cd9 100644 --- a/src/renderer/store/availability.ts +++ b/src/renderer/stores/availability.ts @@ -1,19 +1,20 @@ -// Disponibilité runtime de chaque env — remplace envCapabilities.ts statique. -// Déterminée au démarrage en pingant ${API_BASE}/version pour chaque env. - import { create } from 'zustand' import type { Env } from './env' type AvailabilityState = { + /** Whether each env API responded successfully to `/version` at startup. */ available: Record - checked: boolean - + checked: boolean + /** Pings remote APIs and updates availability flags. */ checkAvailability: () => Promise } +/** + * Runtime availability of prod vs testing API bases (determined at app startup). + */ export const useAvailabilityStore = create((set) => ({ available: { - 'universe': false, + universe: false, 'universe-testing': false }, checked: false, @@ -23,7 +24,8 @@ export const useAvailabilityStore = create((set) => ({ const result = await window.api.checkEnvAvailability() set({ available: result, checked: true }) } catch { - set({ checked: true }) // en cas d'erreur, tout reste false + // On failure, leave all envs as unavailable + set({ checked: true }) } } -})) \ No newline at end of file +})) diff --git a/src/renderer/stores/env.ts b/src/renderer/stores/env.ts new file mode 100644 index 0000000..1e0ee45 --- /dev/null +++ b/src/renderer/stores/env.ts @@ -0,0 +1,18 @@ +import { create } from 'zustand' +import type { Env } from '@shared/types/env' + +export type { Env } from '@shared/types/env' + +interface EnvState { + activeEnv: Env + /** Switches the active universe (prod vs testing) for all env-scoped stores. */ + setEnv: (env: Env) => void +} + +/** + * Tracks which game environment (universe / universe-testing) the UI operates on. + */ +export const useEnvStore = create((set) => ({ + activeEnv: 'universe', + setEnv: (env) => set({ activeEnv: env }) +})) diff --git a/src/renderer/store/files.ts b/src/renderer/stores/files.ts similarity index 58% rename from src/renderer/store/files.ts rename to src/renderer/stores/files.ts index a1b0c47..4552b18 100644 --- a/src/renderer/store/files.ts +++ b/src/renderer/stores/files.ts @@ -1,40 +1,40 @@ import { create } from 'zustand' import { persist } from 'zustand/middleware' +import type { InstallProgressLabel } from '@shared/types/installProgress' import { useEnvStore, type Env } from './env' import { useVersionStore } from './version' -// ─── Types ──────────────────────────────────────────────────────────────────── - export type EnvFilesData = { - // Persistés + /** Persisted: game payload is installed under installPath/DyingStar */ installed: boolean version: string | null releaseDate: string | null needsUpdate: boolean installPath: string - // Transitoires + /** Transient: install/update in progress */ installing: boolean progress: number - progressLabel: string + progressEvent: InstallProgressLabel | null } -/** Résultat du vidage cache Godot (shader_cache / chunk_cache). */ +/** Outcome of clearing Godot shader/chunk caches. */ export type ClearGodotCacheOutcome = 'success' | 'partial' | 'error' type FilesState = { data: Record - setInstallPath: (path: string) => void selectDirectory: () => Promise install: () => Promise update: () => Promise verify: () => Promise clearCache: () => Promise + /** + * Reconciles persisted install flags with files on disk (startup, env switch, verify). + * Clears install state when the game folder or executable was removed manually. + */ syncInstalledVersions: () => Promise } -// ─── Valeurs par défaut ─────────────────────────────────────────────────────── - const defaultEnvData: EnvFilesData = { installed: false, version: null, @@ -43,26 +43,27 @@ const defaultEnvData: EnvFilesData = { installPath: '', installing: false, progress: 0, - progressLabel: '' + progressEvent: null } const defaultData: Record = { - 'universe': { ...defaultEnvData }, + universe: { ...defaultEnvData }, 'universe-testing': { ...defaultEnvData } } -// ─── Helper ─────────────────────────────────────────────────────────────────── - type SetFn = (fn: (s: FilesState) => Partial) => void +/** Merges partial file/install fields for one environment. */ function patchEnv(set: SetFn, env: Env, patch: Partial): void { set((s) => ({ data: { ...s.data, [env]: { ...s.data[env], ...patch } } })) } -// ─── Store ──────────────────────────────────────────────────────────────────── - +/** + * Per-environment install path, download progress, and install/update actions. + * Install metadata is persisted to disk via zustand/persist. + */ export const useFilesStore = create()( persist( (set, get) => ({ @@ -85,18 +86,17 @@ export const useFilesStore = create()( const env = useEnvStore.getState().activeEnv const { installPath } = get().data[env] if (!installPath) { - console.warn('[FilesStore] Aucun répertoire d\'installation défini.') + console.warn('[FilesStore] No install directory set.') return } - patchEnv(set, env, { installing: true, progress: 0, progressLabel: 'Connexion au serveur...' }) + patchEnv(set, env, { installing: true, progress: 0, progressEvent: { key: 'connecting' } }) window.api.onInstallProgress((progress, label) => { - patchEnv(set, env, { progress, progressLabel: label }) + patchEnv(set, env, { progress, progressEvent: label }) }) try { - // installGame retourne maintenant { version, releaseDate } depuis version.json const { version, releaseDate } = await window.api.installGame(env, installPath) patchEnv(set, env, { @@ -106,12 +106,12 @@ export const useFilesStore = create()( installing: false, needsUpdate: false, progress: 100, - progressLabel: `Installation terminée — v${version}` + progressEvent: { key: 'completeInstall', version } }) void useVersionStore.getState().checkVersions() } catch (err) { - console.error('[FilesStore] Échec installation :', err) - patchEnv(set, env, { installing: false, progress: 0, progressLabel: '' }) + console.error('[FilesStore] Install failed:', err) + patchEnv(set, env, { installing: false, progress: 0, progressEvent: null }) } }, @@ -120,10 +120,14 @@ export const useFilesStore = create()( const { installPath } = get().data[env] if (!installPath) return - patchEnv(set, env, { installing: true, progress: 0, progressLabel: 'Recherche des mises à jour...' }) + patchEnv(set, env, { + installing: true, + progress: 0, + progressEvent: { key: 'checkingUpdates' } + }) window.api.onInstallProgress((progress, label) => { - patchEnv(set, env, { progress, progressLabel: label }) + patchEnv(set, env, { progress, progressEvent: label }) }) try { @@ -132,7 +136,7 @@ export const useFilesStore = create()( try { await window.api.clearGodotGameCache() } catch (cacheErr) { - console.warn('[FilesStore] Cache Godot après mise à jour :', cacheErr) + console.warn('[FilesStore] Godot cache clear after update:', cacheErr) } patchEnv(set, env, { @@ -141,32 +145,33 @@ export const useFilesStore = create()( installing: false, needsUpdate: false, progress: 100, - progressLabel: `Mise à jour terminée — v${version}` + progressEvent: { key: 'completeUpdate', version } }) void useVersionStore.getState().checkVersions() } catch (err) { - console.error('[FilesStore] Échec mise à jour :', err) - patchEnv(set, env, { installing: false, progress: 0, progressLabel: '' }) + console.error('[FilesStore] Update failed:', err) + patchEnv(set, env, { installing: false, progress: 0, progressEvent: null }) } }, verify: async () => { - const env = useEnvStore.getState().activeEnv - const { installPath } = get().data[env] - console.log('[FilesStore] Vérification dans :', installPath, '(env:', env, ')') + await get().syncInstalledVersions() }, clearCache: async (): Promise => { try { const result = await window.api.clearGodotGameCache() if (result.errors.length > 0) { - console.warn('[FilesStore] Cache Godot — erreurs :', result.errors) + console.warn('[FilesStore] Godot cache — errors:', result.errors) return 'partial' } - console.log('[FilesStore] Cache Godot vidé', { root: result.root, removed: result.removed.length }) + console.log('[FilesStore] Godot cache cleared', { + root: result.root, + removed: result.removed.length + }) return 'success' } catch (err) { - console.error('[FilesStore] Échec vidage cache Godot :', err) + console.error('[FilesStore] Godot cache clear failed:', err) return 'error' } }, @@ -175,17 +180,42 @@ export const useFilesStore = create()( const envs: Env[] = ['universe', 'universe-testing'] await Promise.all( envs.map(async (env) => { - const { installed, installPath } = get().data[env] - if (!installed || !installPath) return + const { installPath } = get().data[env] + if (!installPath) { + if (get().data[env].installed) { + patchEnv(set, env, { + installed: false, + version: null, + releaseDate: null, + needsUpdate: false + }) + } + return + } try { const resolved = await window.api.resolveInstalledVersion(env, installPath) - if (!resolved?.version) return + if (!resolved?.version) { + patchEnv(set, env, { + installed: false, + version: null, + releaseDate: null, + needsUpdate: false + }) + return + } patchEnv(set, env, { + installed: true, version: resolved.version, releaseDate: resolved.releaseDate }) } catch (err) { - console.warn('[FilesStore] Sync version installée :', env, err) + console.warn('[FilesStore] Sync installed version:', env, err) + patchEnv(set, env, { + installed: false, + version: null, + releaseDate: null, + needsUpdate: false + }) } }) ) @@ -193,37 +223,40 @@ export const useFilesStore = create()( }), { name: 'dyingstar-files', + /** Persists only install metadata, not transient progress flags. */ partialize: (state) => ({ data: { - 'universe': { - installed: state.data['universe'].installed, - version: state.data['universe'].version, - releaseDate: state.data['universe'].releaseDate, - needsUpdate: state.data['universe'].needsUpdate, - installPath: state.data['universe'].installPath + universe: { + installed: state.data.universe.installed, + version: state.data.universe.version, + releaseDate: state.data.universe.releaseDate, + needsUpdate: state.data.universe.needsUpdate, + installPath: state.data.universe.installPath }, 'universe-testing': { - installed: state.data['universe-testing'].installed, - version: state.data['universe-testing'].version, + installed: state.data['universe-testing'].installed, + version: state.data['universe-testing'].version, releaseDate: state.data['universe-testing'].releaseDate, needsUpdate: state.data['universe-testing'].needsUpdate, installPath: state.data['universe-testing'].installPath } } }), + /** Restores persisted slice and merges with default transient fields. */ merge: (persisted: unknown, current) => { const p = persisted as Partial return { ...current, data: { - 'universe': { ...defaultEnvData, ...(p.data?.['universe'] ?? {}) }, + universe: { ...defaultEnvData, ...(p.data?.universe ?? {}) }, 'universe-testing': { ...defaultEnvData, ...(p.data?.['universe-testing'] ?? {}) } } } }, + /** After disk rehydrate, refresh versions from API/manifest. */ onRehydrateStorage: () => (state) => { if (state) void state.syncInstalledVersions() } } ) -) \ No newline at end of file +) diff --git a/src/renderer/store/game.ts b/src/renderer/stores/game.ts similarity index 70% rename from src/renderer/store/game.ts rename to src/renderer/stores/game.ts index d4a34b8..9232435 100644 --- a/src/renderer/store/game.ts +++ b/src/renderer/stores/game.ts @@ -1,30 +1,32 @@ import { create } from 'zustand' import { useEnvStore, type Env } from './env' import { useFilesStore } from './files' -import type { ServerStatusValue } from '../../main/services/gameStatus' - -// ─── Types ──────────────────────────────────────────────────────────────────── +import type { ServerStatusValue } from '@shared/types/game' export type { ServerStatusValue } type EnvGameData = { - status: ServerStatusValue + status: ServerStatusValue players: number } type GameState = { data: Record + /** True while a game process launched by the launcher is running. */ gameRunning: boolean - + /** Refreshes server status and player count for the active environment. */ fetchServerStatus: () => Promise + /** Syncs running state from the main process (e.g. after failed launch). */ syncGameRunning: () => Promise + /** Launches the game executable with a fresh auth token. */ play: () => Promise } const defaultEnvData: EnvGameData = { status: 'unknown', players: 0 } -// ─── Store ──────────────────────────────────────────────────────────────────── - +/** + * Server status, player count, and game launch state per environment. + */ export const useGameStore = create((set, get) => { window.api.onGameRunningChanged((running) => { set({ gameRunning: running }) @@ -36,7 +38,7 @@ export const useGameStore = create((set, get) => { return { data: { - 'universe': { ...defaultEnvData }, + universe: { ...defaultEnvData }, 'universe-testing': { ...defaultEnvData } }, gameRunning: false, @@ -71,7 +73,7 @@ export const useGameStore = create((set, get) => { const { installPath } = useFilesStore.getState().data[env] if (!installPath) { - console.warn('[GameStore] Aucun répertoire d\'installation pour env :', env) + console.warn('[GameStore] No install path for env:', env) return } @@ -79,7 +81,7 @@ export const useGameStore = create((set, get) => { await window.api.launchGame(env, installPath) set({ gameRunning: true }) } catch (err) { - console.error('[GameStore] Échec du lancement :', err) + console.error('[GameStore] Launch failed:', err) await get().syncGameRunning() } } diff --git a/src/renderer/store/lore.ts b/src/renderer/stores/lore.ts similarity index 59% rename from src/renderer/store/lore.ts rename to src/renderer/stores/lore.ts index a127a9f..1e8d785 100644 --- a/src/renderer/store/lore.ts +++ b/src/renderer/stores/lore.ts @@ -2,28 +2,26 @@ import { create } from 'zustand' type Article = { id: string - title: string file: string } type LoreState = { articles: Article[] current?: Article - + /** Selects a lore article by id for display in LoreArticle. */ select: (id: string) => void } +/** + * Lore sidebar catalog and currently selected markdown article. + * Article titles are resolved via i18n (`lore.articles.`). + */ export const useLoreStore = create((set, get) => ({ - articles: [ - { id: 'origins', title: 'Origines', file: 'origins.md' }, - { id: 'factions', title: 'Factions', file: 'factions.md' }, - { id: 'universe', title: 'Univers', file: 'universe.md' } - ], - + articles: [{ id: 'origins', file: 'origins.md' }], current: undefined, select: (id) => { const article = get().articles.find((a) => a.id === id) set({ current: article }) } -})) \ No newline at end of file +})) diff --git a/src/renderer/store/navigation.ts b/src/renderer/stores/navigation.ts similarity index 62% rename from src/renderer/store/navigation.ts rename to src/renderer/stores/navigation.ts index c59a93d..8fa1601 100644 --- a/src/renderer/store/navigation.ts +++ b/src/renderer/stores/navigation.ts @@ -1,13 +1,18 @@ import { create } from 'zustand' +/** Main shell views: universe panels, social page, or lore page. */ export type View = 'universe' | 'universe-testing' | 'social' | 'lore' interface NavigationState { currentView: View + /** Switches the active shell view. */ navigate: (view: View) => void } +/** + * Controls which top-level view is rendered inside the shell (below the navbar). + */ export const useNavigationStore = create((set) => ({ currentView: 'universe', navigate: (view) => set({ currentView: view }) -})) \ No newline at end of file +})) diff --git a/src/renderer/stores/social.ts b/src/renderer/stores/social.ts new file mode 100644 index 0000000..8517013 --- /dev/null +++ b/src/renderer/stores/social.ts @@ -0,0 +1,199 @@ +import { create } from 'zustand' +import { useEnvStore, type Env } from './env' +import { SOCIAL_ERROR, SocialStoreError } from '@lib/socialErrors' + +export type FriendStatus = 'online' | 'offline' | 'ingame' + +export type Friend = { + id: string + name: string + status: FriendStatus + game?: string + avatar?: string +} + +export type Orga = { + id: string + name: string + members: number + /** Whether the current user is already a member (from API). */ + isMember: boolean +} + +export type FriendRequest = { + id: string + name: string +} + +type EnvSocialData = { + friends: Friend[] + orgas: Orga[] + requests: FriendRequest[] + loaded: boolean +} + +type SocialState = { + data: Record + /** Loads friends, orgs, and requests for the active env (mock until API wired). */ + fetchAll: () => Promise + addFriend: (username: string) => Promise + removeFriend: (id: string) => void + acceptRequest: (id: string) => Promise + declineRequest: (id: string) => Promise + joinOrga: (id: string) => Promise + createOrga: (name: string) => Promise +} + +const defaultEnvData: EnvSocialData = { + friends: [], + orgas: [], + requests: [], + loaded: false +} + +const defaultData: Record = { + universe: { ...defaultEnvData }, + 'universe-testing': { ...defaultEnvData } +} + +type SetFn = (fn: (s: SocialState) => Partial) => void + +/** Merges partial social data for one environment. */ +function patchEnv(set: SetFn, env: Env, patch: Partial): void { + set((s) => ({ + data: { ...s.data, [env]: { ...s.data[env], ...patch } } + })) +} + +/** + * Social graph state per environment (friends, orgs, requests). + * Currently backed by mock data; replace with API calls when available. + */ +export const useSocialStore = create((set, get) => ({ + data: defaultData, + + fetchAll: async () => { + const env = useEnvStore.getState().activeEnv + + // TODO: replace with real API calls per env + await new Promise((r) => setTimeout(r, 500)) + + const mockData: Record = { + universe: { + friends: [ + { id: '1', name: 'Aurel', status: 'online' }, + { id: '2', name: 'Kira', status: 'ingame', game: 'Universe' }, + { id: '3', name: 'Noah', status: 'offline' } + ], + orgas: [ + { id: '1', name: 'Nova Corp', members: 12, isMember: true }, + { id: '2', name: 'Galaxy Team', members: 5, isMember: false }, + { id: '3', name: 'Void Squad', members: 8, isMember: false } + ], + requests: [ + { id: '1', name: 'Zed' }, + { id: '2', name: 'Mira' } + ], + loaded: true + }, + 'universe-testing': { + friends: [ + { id: '1', name: 'TestUser1', status: 'online' }, + { id: '2', name: 'TestUser2', status: 'ingame', game: 'Universe Testing' } + ], + orgas: [{ id: '1', name: 'Test Squad', members: 3, isMember: false }], + requests: [], + loaded: true + } + } + + patchEnv(set, env, mockData[env]) + }, + + addFriend: async (username: string) => { + const env = useEnvStore.getState().activeEnv + const trimmed = username.trim() + if (!trimmed) return + + const { friends, requests } = get().data[env] + const nameTaken = + friends.some((f) => f.name.toLowerCase() === trimmed.toLowerCase()) || + requests.some((r) => r.name.toLowerCase() === trimmed.toLowerCase()) + + // TODO: POST friend request API + await new Promise((r) => setTimeout(r, 600)) + + if (nameTaken) { + throw new SocialStoreError(SOCIAL_ERROR.FRIEND_REQUEST_FAILED) + } + + console.log(`[SocialStore] Friend request sent to "${trimmed}" on env:`, env) + }, + + removeFriend: (id: string) => { + const env = useEnvStore.getState().activeEnv + const { friends } = get().data[env] + // TODO: DELETE /friends/:id + patchEnv(set, env, { friends: friends.filter((f) => f.id !== id) }) + }, + + acceptRequest: async (id: string) => { + const env = useEnvStore.getState().activeEnv + const { friends, requests } = get().data[env] + const req = requests.find((r) => r.id === id) + if (!req) return + + // TODO: POST /friend-requests/:id/accept + await new Promise((r) => setTimeout(r, 400)) + + patchEnv(set, env, { + requests: requests.filter((r) => r.id !== id), + friends: [...friends, { id: req.id, name: req.name, status: 'offline' }] + }) + }, + + declineRequest: async (id: string) => { + const env = useEnvStore.getState().activeEnv + const { requests } = get().data[env] + + // TODO: POST /friend-requests/:id/decline + await new Promise((r) => setTimeout(r, 300)) + + patchEnv(set, env, { requests: requests.filter((r) => r.id !== id) }) + }, + + joinOrga: async (id: string) => { + const env = useEnvStore.getState().activeEnv + const { orgas } = get().data[env] + + // TODO: POST /organizations/:id/join + await new Promise((r) => setTimeout(r, 500)) + + patchEnv(set, env, { + orgas: orgas.map((o) => (o.id === id ? { ...o, isMember: true, members: o.members + 1 } : o)) + }) + }, + + createOrga: async (name: string) => { + const env = useEnvStore.getState().activeEnv + const trimmed = name.trim() + if (!trimmed) return + + // TODO: POST /organizations + await new Promise((r) => setTimeout(r, 600)) + + if (trimmed.toLowerCase() === 'dyingstar') { + throw new SocialStoreError(SOCIAL_ERROR.ORGA_NAME_TAKEN) + } + + const { orgas } = get().data[env] + const newOrga: Orga = { + id: `orga-${Date.now()}`, + name: trimmed, + members: 1, + isMember: true + } + + patchEnv(set, env, { orgas: [...orgas, newOrga] }) + } +})) diff --git a/src/renderer/stores/version.ts b/src/renderer/stores/version.ts new file mode 100644 index 0000000..32b5b2f --- /dev/null +++ b/src/renderer/stores/version.ts @@ -0,0 +1,57 @@ +import { create } from 'zustand' +import type { Env } from './env' +import type { GameVersionInfo } from '@shared/types/version' + +export type { GameVersionInfo } from '@shared/types/version' + +type VersionState = { + currentLauncherVersion: string + latestLauncherVersion: string | null + latestLauncherReleaseDate: string | null + launcherUpdateAvailable: boolean + /** Latest remote game version per environment (from API `/version`). */ + latestGameVersions: Record + checking: boolean + checked: boolean + /** Fetches launcher (GitHub) and game (API) version info from the main process. */ + checkVersions: () => Promise +} + +const defaultGameVersionInfo: GameVersionInfo = { version: null, releaseDate: null } + +/** + * Launcher and per-env game version state for update banners. + */ +export const useVersionStore = create((set) => ({ + currentLauncherVersion: '', + latestLauncherVersion: null, + latestLauncherReleaseDate: null, + launcherUpdateAvailable: false, + + latestGameVersions: { + universe: { ...defaultGameVersionInfo }, + 'universe-testing': { ...defaultGameVersionInfo } + }, + + checking: false, + checked: false, + + checkVersions: async () => { + set({ checking: true }) + try { + const result = await window.api.checkVersions() + set({ + currentLauncherVersion: result.currentLauncherVersion, + latestLauncherVersion: result.latestLauncherVersion, + latestLauncherReleaseDate: result.latestLauncherReleaseDate, + launcherUpdateAvailable: result.launcherUpdateAvailable, + latestGameVersions: result.latestGameVersions, + checking: false, + checked: true + }) + } catch (err) { + console.error('[VersionStore] Version check failed:', err) + set({ checking: false, checked: true }) + } + } +})) diff --git a/src/renderer/views/Lore.tsx b/src/renderer/views/Lore.tsx new file mode 100644 index 0000000..e185204 --- /dev/null +++ b/src/renderer/views/Lore.tsx @@ -0,0 +1,13 @@ +import type React from 'react' +import LoreSidebar from '@components/ui/lore/LoreSidebar' +import LoreArticle from '@components/ui/lore/LoreArticle' + +/** Lore page: article sidebar and markdown content viewer. */ +export default function LorePage(): React.JSX.Element { + return ( +
+ + +
+ ) +} diff --git a/src/renderer/views/social.tsx b/src/renderer/views/Social.tsx similarity index 56% rename from src/renderer/views/social.tsx rename to src/renderer/views/Social.tsx index 18eaba2..8125798 100644 --- a/src/renderer/views/social.tsx +++ b/src/renderer/views/Social.tsx @@ -1,16 +1,19 @@ import { useEffect, useState } from 'react' -import { useSocialStore } from '@store/social' -import { useEnvStore } from '@store/env' -import SocialSidebar from '@components/ui/socialSidebar' -import Button from '@components/ui/button' -import InputField from '@components/ui/inputField' -import { FriendRow } from '@components/ui/friendRow' -import { OrgaRow } from '@components/ui/orgaRow' -import { RequestRow } from '@components/ui/requestRow' - -// ─── Formulaire : ajouter un ami ────────────────────────────────────────────── - +import { useTranslation } from 'react-i18next' +import { useSocialStore } from '@stores/social' +import { useEnvStore } from '@stores/env' +import SocialSidebar from '@components/ui/social/SocialSidebar' +import Button from '@components/ui/primitives/Button' +import InputField from '@components/ui/primitives/InputField' +import { FriendRow } from '@components/ui/social/FriendRow' +import { OrgaRow } from '@components/ui/social/OrgaRow' +import { RequestRow } from '@components/ui/social/RequestRow' +import { socialPanelAutoCloseMs } from '@lib/env' +import { getSocialErrorMessage } from '@lib/socialErrors' + +/** Inline form to send a friend request by username. */ function AddFriendForm({ onClose }: { onClose: () => void }): React.JSX.Element { + const { t } = useTranslation() const { addFriend } = useSocialStore() const [username, setUsername] = useState('') const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle') @@ -24,45 +27,46 @@ function AddFriendForm({ onClose }: { onClose: () => void }): React.JSX.Element await addFriend(username) setStatus('success') setUsername('') - setTimeout(onClose, 1200) + setTimeout(onClose, socialPanelAutoCloseMs()) } catch (err) { setStatus('error') - setErrorMsg(err instanceof Error ? err.message : 'Utilisateur introuvable ou demande déjà envoyée.') + setErrorMsg(getSocialErrorMessage(err, t, 'universe.socialPage.errors.friendRequestFailed')) } } return ( -
+

- Ajouter un ami + {t('universe.socialPage.addFriendForm.title')}

{status === 'success' && ( -

Demande envoyée !

- )} - {status === 'error' && ( -

{errorMsg}

+

{t('universe.socialPage.addFriendForm.success')}

)} + {status === 'error' &&

{errorMsg}

}
) } -// ─── Formulaire : créer une organisation ────────────────────────────────────── - +/** Inline form to create a new organization. */ function CreateOrgaForm({ onClose }: { onClose: () => void }): React.JSX.Element { + const { t } = useTranslation() const { createOrga } = useSocialStore() const [name, setName] = useState('') const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle') @@ -76,64 +80,50 @@ function CreateOrgaForm({ onClose }: { onClose: () => void }): React.JSX.Element await createOrga(name) setStatus('success') setName('') - setTimeout(onClose, 1200) + setTimeout(onClose, socialPanelAutoCloseMs()) } catch (err) { setStatus('error') - setErrorMsg(err instanceof Error ? err.message : 'Ce nom d\'organisation est déjà pris.') + setErrorMsg(getSocialErrorMessage(err, t)) } } return ( -
+

- Créer une organisation + {t('universe.socialPage.createOrgaForm.title')}

{status === 'success' && ( -

Organisation créée !

- )} - {status === 'error' && ( -

{errorMsg}

+

+ {t('universe.socialPage.createOrgaForm.success')} +

)} + {status === 'error' &&

{errorMsg}

}
) } -// ─── Types ──────────────────────────────────────────────────────────────────── - type Tab = 'friends' | 'organizations' | 'requests' -const TAB_META: Record = { - friends: { - label: 'Amis', - subtitle: 'Gère ta liste d\'amis et ton statut.' - }, - organizations: { - label: 'Organisations', - subtitle: 'Organisations, membres et invitations.' - }, - requests: { - label: 'Demandes', - subtitle: 'Demandes d\'amis en attente.' - } -} - -// ─── Page ───────────────────────────────────────────────────────────────────── - +/** Full social page: friends, organizations, and friend requests. */ export default function SocialPage(): React.JSX.Element { + const { t } = useTranslation() const { activeEnv } = useEnvStore() const { data, fetchAll, acceptRequest, declineRequest, joinOrga } = useSocialStore() const { friends, orgas, requests } = data[activeEnv] @@ -143,8 +133,8 @@ export default function SocialPage(): React.JSX.Element { const [showCreateOrga, setShowCreateOrga] = useState(false) useEffect(() => { - fetchAll() - }, [activeEnv]) + void fetchAll() + }, [activeEnv, fetchAll]) const handleTabChange = (next: string): void => { setTab(next as Tab) @@ -152,47 +142,46 @@ export default function SocialPage(): React.JSX.Element { setShowCreateOrga(false) } - const meta = TAB_META[tab] + const tabLabel = t(`universe.socialPage.tabs.${tab}.label`) + const tabSubtitle = t(`universe.socialPage.tabs.${tab}.subtitle`) return ( -
- +
-
- - {/* Header */} +
-

- {meta.label} -

-

- {meta.subtitle} -

+

{tabLabel}

+

{tabSubtitle}

{tab === 'friends' && ( )} {tab === 'organizations' && ( )}
- {/* Formulaires contextuels */} {showAddFriend && tab === 'friends' && ( setShowAddFriend(false)} /> )} @@ -200,22 +189,19 @@ export default function SocialPage(): React.JSX.Element { setShowCreateOrga(false)} /> )} - {/* Compteur requêtes */} {tab === 'requests' && requests.length > 0 && (

- {requests.length} demande{requests.length > 1 ? 's' : ''} en attente + {t('universe.socialPage.pendingRequests', { count: requests.length })}

)} - {/* Contenu */} -
+
- {tab === 'friends' && ( <> {friends.length === 0 && (

- Aucun ami pour le moment. + {t('universe.socialPage.emptyFriends')}

)} {friends.map((f) => ( @@ -228,7 +214,7 @@ export default function SocialPage(): React.JSX.Element { <> {orgas.length === 0 && (

- Aucune organisation. + {t('universe.socialPage.emptyOrganizations')}

)} {orgas.map((o) => ( @@ -241,7 +227,7 @@ export default function SocialPage(): React.JSX.Element { <> {requests.length === 0 && (

- Aucune demande en attente. + {t('universe.socialPage.emptyRequests')}

)} {requests.map((r) => ( @@ -254,11 +240,9 @@ export default function SocialPage(): React.JSX.Element { ))} )} -
-
) -} \ No newline at end of file +} diff --git a/src/renderer/views/UniverseView.tsx b/src/renderer/views/UniverseView.tsx new file mode 100644 index 0000000..a7dd0f1 --- /dev/null +++ b/src/renderer/views/UniverseView.tsx @@ -0,0 +1,63 @@ +import { useNavigationStore } from '@stores/navigation' +import { useVersionStore } from '@stores/version' +import { useTranslation } from 'react-i18next' +import AccountPanel from '@components/panel/AccountPanel' +import GamePanel from '@components/panel/GamePanel' +import SocialPanel from '@components/panel/SocialPanel' +import FilesPanel from '@components/panel/FilesPanel' +import UpdateAlert from '@components/ui/feedback/UpdateAlert' + +type UniverseViewProps = { + showTestingBanner?: boolean +} + +/** Four-panel universe layout (account, social preview, game, files) with optional testing banner. */ +export default function UniverseView({ + showTestingBanner = false +}: UniverseViewProps): React.JSX.Element { + useNavigationStore() + const { t } = useTranslation() + const { + launcherUpdateAvailable, + currentLauncherVersion, + latestLauncherVersion, + latestLauncherReleaseDate + } = useVersionStore() + + return ( +
+ {showTestingBanner && ( +
+ + + {t('universeTesting.banner')} + +
+ )} + + {launcherUpdateAvailable && latestLauncherVersion && ( +
+ +
+ )} + +
+ + + + +
+
+ ) +} diff --git a/src/renderer/views/lore.tsx b/src/renderer/views/lore.tsx deleted file mode 100644 index 59696e1..0000000 --- a/src/renderer/views/lore.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import LoreSidebar from '@components/ui/loreSidebar' -import LoreArticle from '@components/ui/loreArticle' - -export default function LorePage() { - return ( -
- - -
- ) -} \ No newline at end of file diff --git a/src/renderer/views/universe.tsx b/src/renderer/views/universe.tsx deleted file mode 100644 index a8edfa5..0000000 --- a/src/renderer/views/universe.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { useNavigationStore } from '@store/navigation' -import { useVersionStore } from '@store/version' -import AccountPanel from '@components/panel/accountPanel' -import GamePanel from '@components/panel/gamePanel' -import SocialPanel from '@components/panel/socialPanel' -import FilesPanel from '@components/panel/filesPanel' -import UpdateAlert from '@components/ui/updateAlert' - -export default function Universe(): React.JSX.Element { - useNavigationStore() - const { - launcherUpdateAvailable, - currentLauncherVersion, - latestLauncherVersion, - latestLauncherReleaseDate - } = useVersionStore() - - return ( -
- - {/* Alerte launcher */} - {launcherUpdateAvailable && latestLauncherVersion && ( -
- -
- )} - -
- - - - -
-
- ) -} \ No newline at end of file diff --git a/src/renderer/views/universeTesting.tsx b/src/renderer/views/universeTesting.tsx deleted file mode 100644 index 5d9462a..0000000 --- a/src/renderer/views/universeTesting.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { useNavigationStore } from '@store/navigation' -import { useVersionStore } from '@store/version' -import { useTranslation } from 'react-i18next' -import AccountPanel from '@components/panel/accountPanel' -import GamePanel from '@components/panel/gamePanel' -import SocialPanel from '@components/panel/socialPanel' -import FilesPanel from '@components/panel/filesPanel' -import UpdateAlert from '@components/ui/updateAlert' - -export default function UniverseTesting(): React.JSX.Element { - useNavigationStore() - const { t } = useTranslation() - const { - launcherUpdateAvailable, - currentLauncherVersion, - latestLauncherVersion, - latestLauncherReleaseDate - } = useVersionStore() - - return ( -
- -
- - - {t('universeTesting.banner')} - -
- - {launcherUpdateAvailable && latestLauncherVersion && ( -
- -
- )} - -
- - - - -
-
- ) -} diff --git a/src/shared/env.d.ts b/src/shared/env.d.ts new file mode 100644 index 0000000..9ef08e4 --- /dev/null +++ b/src/shared/env.d.ts @@ -0,0 +1,52 @@ +/** Vite environment variables (main + renderer). */ +interface ImportMetaEnv { + readonly VITE_API_BASE_UNIVERSE: string + readonly VITE_API_BASE_TESTING: string + readonly VITE_GAME_DOWNLOAD_BASE_UNIVERSE: string + readonly VITE_GAME_DOWNLOAD_BASE_TESTING: string + readonly VITE_GAME_ZIP_LINUX: string + readonly VITE_GAME_ZIP_WINDOWS: string + readonly VITE_GAME_ZIP_DARWIN: string + readonly VITE_GAME_ZIP_TESTING_WINDOWS: string + readonly VITE_GAME_ZIP_TESTING_LINUX: string + readonly VITE_GAME_ZIP_TESTING_DARWIN: string + readonly VITE_LAUNCHER_GITHUB_REPO_URL: string + readonly VITE_LAUNCHER_RELEASE_DISCORD_URL: string + readonly VITE_WINDOW_WIDTH: string + readonly VITE_WINDOW_HEIGHT: string + readonly VITE_WINDOW_MAX_WIDTH: string + readonly VITE_WINDOW_MAX_HEIGHT: string + readonly VITE_ENABLE_DEVTOOLS: string + readonly VITE_ELECTRON_ENABLE_LOGGING: string + readonly VITE_STATUS_COMPONENT_ID_UNIVERSE: string + readonly VITE_STATUS_COMPONENT_ID_TESTING: string + readonly VITE_STATUS_METRIC_ID_UNIVERSE: string + readonly VITE_STATUS_METRIC_ID_TESTING: string + readonly VITE_STATUS_PAGE_UNIVERSE: string + readonly VITE_STATUS_PAGE_TESTING: string + readonly VITE_SERVER_STATUS_POLL_MINUTES: string + readonly VITE_NAV_WEBSITE_URL: string + readonly VITE_NAV_DISCORD_URL: string + readonly VITE_NAV_WIKI_URL: string + readonly VITE_NAV_DONATE_URL: string + readonly VITE_HTTP_TIMEOUT_API_MS: string + readonly VITE_HTTP_TIMEOUT_VERSION_PING_MS: string + readonly VITE_HTTP_TIMEOUT_GITHUB_MS: string + readonly VITE_DOWNLOAD_TIMEOUT_MS: string + readonly VITE_GAME_PROCESS_POLL_MS: string + readonly VITE_GAME_INSTALL_SUBDIR: string + readonly VITE_GAME_EXE_WINDOWS: string + readonly VITE_GAME_EXE_LINUX: string + readonly VITE_GAME_EXE_DARWIN: string + readonly VITE_APP_PROTOCOL: string + readonly VITE_DOWNLOAD_USER_AGENT: string + readonly VITE_AUTH_CLIENT_ID: string + readonly VITE_AUTH_REALM: string + readonly VITE_AUTH_REDIRECT_URI: string + readonly VITE_UI_TOAST_DURATION_MS: string + readonly VITE_UI_SOCIAL_PANEL_CLOSE_MS: string +} + +interface ImportMeta { + readonly env: ImportMetaEnv +} diff --git a/src/shared/types/auth.ts b/src/shared/types/auth.ts new file mode 100644 index 0000000..9781873 --- /dev/null +++ b/src/shared/types/auth.ts @@ -0,0 +1,6 @@ +/** Authenticated player profile decoded from the OAuth id_token. */ +export interface UserInfo { + sub: string + username: string + email: string +} diff --git a/src/shared/types/env.ts b/src/shared/types/env.ts new file mode 100644 index 0000000..cfcf2ee --- /dev/null +++ b/src/shared/types/env.ts @@ -0,0 +1,2 @@ +/** Target game environment: production (`universe`) or testing (`universe-testing`). */ +export type Env = 'universe' | 'universe-testing' diff --git a/src/shared/types/game.ts b/src/shared/types/game.ts new file mode 100644 index 0000000..0fa6372 --- /dev/null +++ b/src/shared/types/game.ts @@ -0,0 +1,16 @@ +/** Normalized server operational status from the status API. */ +export type ServerStatusValue = + | 'online' + | 'degraded' + | 'offline' + | 'maintenance' + | 'unknown' + | 'unavailable' + +/** Server status and player count returned to the renderer. */ +export interface GameStatusResult { + status: ServerStatusValue + statusLabel: string + players: number + available: boolean +} diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts new file mode 100644 index 0000000..a8fc4b0 --- /dev/null +++ b/src/shared/types/index.ts @@ -0,0 +1,5 @@ +export type { Env } from './env' +export type { ServerStatusValue, GameStatusResult } from './game' +export type { UserInfo } from './auth' +export type { GameVersionInfo, VersionCheckResult } from './version' +export type { InstallResult } from './install' diff --git a/src/shared/types/install.ts b/src/shared/types/install.ts new file mode 100644 index 0000000..ecca8e9 --- /dev/null +++ b/src/shared/types/install.ts @@ -0,0 +1,5 @@ +/** Version metadata returned after a successful game install or update. */ +export interface InstallResult { + version: string + releaseDate: string +} diff --git a/src/shared/types/installProgress.ts b/src/shared/types/installProgress.ts new file mode 100644 index 0000000..438f212 --- /dev/null +++ b/src/shared/types/installProgress.ts @@ -0,0 +1,11 @@ +/** Install/download progress label sent from main → renderer (translated in UI). */ +export type InstallProgressLabel = + | { key: 'connecting' } + | { key: 'checkingUpdates' } + | { key: 'downloading'; downloaded: number; total: number } + | { key: 'downloadingIndeterminate'; downloaded: number } + | { key: 'preparing' } + | { key: 'extracting'; current: number; total: number } + | { key: 'cleaning' } + | { key: 'completeInstall'; version: string } + | { key: 'completeUpdate'; version: string } diff --git a/src/shared/types/version.ts b/src/shared/types/version.ts new file mode 100644 index 0000000..23d1a39 --- /dev/null +++ b/src/shared/types/version.ts @@ -0,0 +1,16 @@ +import type { Env } from './env' + +/** Remote game build version and release date for one environment. */ +export interface GameVersionInfo { + version: string | null + releaseDate: string | null +} + +/** Result of comparing local launcher and remote game/launcher versions. */ +export interface VersionCheckResult { + currentLauncherVersion: string + latestLauncherVersion: string | null + latestLauncherReleaseDate: string | null + launcherUpdateAvailable: boolean + latestGameVersions: Record +} diff --git a/tailwind.config.ts b/tailwind.config.ts index 56d1a9f..8dca49c 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,21 +1,21 @@ export default { - content: ["./src/renderer/**/*.{ts,tsx}"], + content: ['./src/renderer/**/*.{ts,tsx}'], theme: { extend: { colors: { - "ds-bg": "#0d0d14", // fond principal - "ds-surface": "#16161f", // cards / panneaux - "ds-border": "#2a2a3a", // bordures - "ds-accent": "#6c63ff", // couleur principale (à ajuster) - "ds-text": "#e8e8f0", - "ds-muted": "#6b6b80", - "ds-success": "#22c55e", // serveurs OK - "ds-warning": "#f59e0b", // serveurs problèmes - "ds-danger": "#ef4444", // serveurs indispo + 'ds-bg': '#0d0d14', // fond principal + 'ds-surface': '#16161f', // cards / panneaux + 'ds-border': '#2a2a3a', // bordures + 'ds-accent': '#6c63ff', // couleur principale (à ajuster) + 'ds-text': '#e8e8f0', + 'ds-muted': '#6b6b80', + 'ds-success': '#22c55e', // serveurs OK + 'ds-warning': '#f59e0b', // serveurs problèmes + 'ds-danger': '#ef4444' // serveurs indispo }, fontFamily: { - sans: ["Poppins", "system-ui", "sans-serif"], - }, - }, - }, -} \ No newline at end of file + sans: ['Poppins', 'system-ui', 'sans-serif'] + } + } + } +} diff --git a/tsconfig.json b/tsconfig.json index eaa0418..a99c5ba 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,10 +3,6 @@ "references": [{ "path": "./tsconfig.node.json" }, { "path": "./tsconfig.web.json" }], "compilerOptions": { "strict": true, - "noImplicitAny": true, - "paths": { - "@renderer/*": ["./src/renderer/*"], - "@main/*": ["./src/main/*"] - } + "noImplicitAny": true } } diff --git a/tsconfig.node.json b/tsconfig.node.json index 0563ccb..d52c76d 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,8 +1,17 @@ { - "extends": "./node_modules/@electron-toolkit/tsconfig/tsconfig.node.json", - "include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*"], + "extends": "@electron-toolkit/tsconfig/tsconfig.node.json", + "include": [ + "electron.vite.config.*", + "src/main/**/*", + "src/preload/**/*", + "src/shared/**/*" + ], "compilerOptions": { "composite": true, - "types": ["electron-vite/node"] + "types": ["electron-vite/node"], + "baseUrl": ".", + "paths": { + "@shared/*": ["src/shared/*"] + } } } diff --git a/tsconfig.web.json b/tsconfig.web.json index 7c4348e..2bdaa4d 100644 --- a/tsconfig.web.json +++ b/tsconfig.web.json @@ -1,20 +1,24 @@ { "extends": "@electron-toolkit/tsconfig/tsconfig.web.json", "include": [ - "src/renderer/src/env.d.ts", - "src/renderer/src/**/*", - "src/renderer/src/**/*.tsx", - "src/preload/*.d.ts" + "src/renderer/**/*", + "src/shared/env.d.ts", + "src/preload/index.d.ts" ], "compilerOptions": { "composite": true, "jsx": "react-jsx", "baseUrl": ".", "paths": { - "@renderer/*": ["src/renderer/src/*"], + "@shared/*": ["src/shared/*"], + "@hooks/*": ["src/renderer/hooks/*"], + "@lib/*": ["src/renderer/lib/*"], + "@assets/*": ["src/renderer/assets/*"], + "@content/*": ["src/renderer/content/*"], + "@stores/*": ["src/renderer/stores/*"], "@components/*": ["src/renderer/components/*"], "@views/*": ["src/renderer/views/*"], - "@store/*": ["src/renderer/store/*"], + "@i18n": ["src/renderer/i18n/index.ts"], "@i18n/*": ["src/renderer/i18n/*"] } }