From a18e93583f31457c65edfa522f34cd1eb1664f65 Mon Sep 17 00:00:00 2001 From: samtiz Date: Mon, 7 Jul 2025 03:47:12 +0900 Subject: [PATCH 01/52] WIP: refactoring in process --- IPC_CHANNELS.md | 87 ++++ REFACTORING_PLAN.md | 119 +++++ REFACTORING_STATUS.md | 80 +++ .../backend_node/db.js => db_backup.js | 0 pickleglass_web/backend_node/index.js | 9 +- pickleglass_web/backend_node/ipcBridge.js | 19 + pickleglass_web/backend_node/jwt.js | 13 - .../backend_node/middleware/auth.js | 2 - pickleglass_web/backend_node/routes/auth.js | 29 +- .../backend_node/routes/conversations.js | 105 +--- .../backend_node/routes/presets.js | 70 +-- pickleglass_web/backend_node/routes/user.js | 122 ++--- pickleglass_web/utils/api.ts | 36 +- pickleglass_web/utils/auth.ts | 9 - preload.js | 0 src/app/AppHeader.js | 15 - src/app/HeaderController.js | 254 ++-------- src/app/PickleGlassApp.js | 10 +- src/app/content.html | 11 - src/common/repositories/preset/index.js | 19 + .../repositories/preset/sqlite.repository.js | 87 ++++ src/common/repositories/session/index.js | 26 + .../repositories/session/sqlite.repository.js | 189 ++++++++ .../repositories/systemSettings/index.js | 11 + .../systemSettings/sqlite.repository.js | 14 + src/common/repositories/user/index.js | 19 + .../repositories/user/sqlite.repository.js | 107 ++++ src/common/services/apiClient.js | 239 --------- src/common/services/authService.js | 179 +++++++ src/common/services/dataService.js | 158 ------ src/common/services/firebaseClient.js | 103 ++++ src/common/services/sqliteClient.js | 241 +--------- src/electron/windowManager.js | 455 +++--------------- src/features/ask/AskView.js | 52 +- src/features/ask/askService.js | 305 ++++++++++++ src/features/ask/repositories/index.js | 18 + .../ask/repositories/sqlite.repository.js | 35 ++ src/features/customize/CustomizeView.js | 76 +-- src/features/listen/SetupView.js | 179 ------- src/features/listen/liveSummaryService.js | 145 ++---- src/features/listen/renderer.js | 385 +-------------- src/features/listen/repositories/index.js | 20 + .../listen/repositories/sqlite.repository.js | 66 +++ src/features/onboarding/OnboardingView.js | 372 -------------- src/index.js | 294 +++++------ src/preload.js | 39 -- 46 files changed, 1966 insertions(+), 2857 deletions(-) create mode 100644 IPC_CHANNELS.md create mode 100644 REFACTORING_PLAN.md create mode 100644 REFACTORING_STATUS.md rename pickleglass_web/backend_node/db.js => db_backup.js (100%) create mode 100644 pickleglass_web/backend_node/ipcBridge.js delete mode 100644 pickleglass_web/backend_node/jwt.js create mode 100644 preload.js create mode 100644 src/common/repositories/preset/index.js create mode 100644 src/common/repositories/preset/sqlite.repository.js create mode 100644 src/common/repositories/session/index.js create mode 100644 src/common/repositories/session/sqlite.repository.js create mode 100644 src/common/repositories/systemSettings/index.js create mode 100644 src/common/repositories/systemSettings/sqlite.repository.js create mode 100644 src/common/repositories/user/index.js create mode 100644 src/common/repositories/user/sqlite.repository.js delete mode 100644 src/common/services/apiClient.js create mode 100644 src/common/services/authService.js delete mode 100644 src/common/services/dataService.js create mode 100644 src/common/services/firebaseClient.js create mode 100644 src/features/ask/askService.js create mode 100644 src/features/ask/repositories/index.js create mode 100644 src/features/ask/repositories/sqlite.repository.js delete mode 100644 src/features/listen/SetupView.js create mode 100644 src/features/listen/repositories/index.js create mode 100644 src/features/listen/repositories/sqlite.repository.js delete mode 100644 src/features/onboarding/OnboardingView.js diff --git a/IPC_CHANNELS.md b/IPC_CHANNELS.md new file mode 100644 index 0000000..5c4cf7f --- /dev/null +++ b/IPC_CHANNELS.md @@ -0,0 +1,87 @@ +# IPC Channel Reference + +This document lists all the IPC channels used for communication between the main process and renderer processes in the Glass application. It serves as a central reference for developers. + +--- + +## 1. Two-Way Channels (`ipcMain.handle` / `ipcRenderer.invoke`) + +These channels are used for request-response communication where the renderer process expects a value to be returned from the main process. + +### Window & System Management +- `get-header-position`: Gets the current [x, y] coordinates of the header window. +- `move-header-to`: Moves the header window to a specific [x, y] coordinate. +- `resize-header-window`: Resizes the header window to a specific width and height. +- `move-window-step`: Moves the header window by a predefined step in a given direction. +- `is-window-visible`: Checks if a specific feature window (e.g., 'ask') is currently visible. +- `force-close-window`: Forces a specific feature window to hide. +- `toggle-all-windows-visibility`: Toggles the visibility of all application windows. +- `toggle-feature`: Shows or hides a specific feature window (e.g., 'ask', 'listen'). +- `quit-application`: Quits the entire application. + +### Authentication & User +- `get-current-user`: Retrieves the full state of the current user (Firebase or local). +- `start-firebase-auth`: Opens the Firebase login flow in the system browser. +- `firebase-logout`: Initiates the user logout process. +- `save-api-key`: Saves a user-provided API key. +- `remove-api-key`: Removes the currently stored API key. +- `get-stored-api-key`: Retrieves the currently active API key. +- `get-ai-provider`: Gets the currently configured AI provider (e.g., 'openai'). + +### Permissions & Settings +- `get-content-protection-status`: Checks if window content protection is enabled. +- `check-system-permissions`: Checks for microphone and screen recording permissions. +- `request-microphone-permission`: Prompts the user for microphone access. +- `open-system-preferences`: Opens the macOS System Preferences for a specific privacy setting. +- `mark-permissions-completed`: Marks the initial permission setup as completed. +- `check-permissions-completed`: Checks if the initial permission setup was completed. +- `update-google-search-setting`: Updates the setting for Google Search integration. + +### Data & Content +- `get-user-presets`: Fetches all custom prompt presets for the current user. +- `get-preset-templates`: Fetches the default prompt preset templates. +- `save-ask-message`: Saves a user question and AI response pair to the database. +- `get-web-url`: Gets the dynamically assigned URLs for the backend and web frontend. + +### Features (Listen, Ask, etc.) +- `initialize-openai`: Initializes the STT and other AI services for a new session. +- `is-session-active`: Checks if a listen/summary session is currently active. +- `send-audio-content`: Sends a chunk of audio data from renderer to main for processing. +- `start-macos-audio`, `stop-macos-audio`: Controls the background process for system audio capture on macOS. +- `close-session`: Stops the current listen session. +- `message-sending`: Notifies the main process that an 'ask' message is being sent. +- `send-question-to-ask`: Sends a question from one feature window (e.g., listen) to the 'ask' window. +- `capture-screenshot`: Requests the main process to take a screenshot. +- `get-current-screenshot`: Retrieves the most recent screenshot. +- `adjust-window-height`: Requests the main process to resize a window to a specific height. + +--- + +## 2. One-Way Channels (`ipcMain.on` / `ipcRenderer.send` / `webContents.send`) + +These channels are used for events or commands that do not require a direct response. + +### Main to Renderer (Events & Updates) +- `user-state-changed`: Notifies all windows that the user's authentication state has changed. +- `auth-failed`: Informs the UI that a Firebase authentication attempt failed. +- `session-state-changed`: Broadcasts whether a listen session is active or inactive. +- `api-key-validated`, `api-key-updated`, `api-key-removed`: Events related to the lifecycle of the API key. +- `stt-update`: Sends real-time speech-to-text transcription updates to the UI. +- `update-structured-data`: Sends processed data (summaries, topics) to the UI. +- `ask-response-chunk`, `ask-response-stream-end`: Sends streaming AI responses for the 'ask' feature. +- `window-show-animation`: Triggers a show/fade-in animation. +- `window-hide-animation`, `settings-window-hide-animation`: Triggers a hide/fade-out animation. +- `window-blur`: Notifies a window that it has lost focus. +- `window-did-show`: Confirms to a window that it is now visible. +- `click-through-toggled`: Informs the UI about the status of click-through mode. +- `start-listening-session`: Commands to control the main application view. +- `receive-question-from-assistant`: Delivers a question to the `AskView`. +- `ask-global-send`, `toggle-text-input`, `clear-ask-response`, `hide-text-input`: Commands for controlling the state of the `AskView`. + +### Renderer to Main (Commands & Events) +- `header-state-changed`: Informs the `windowManager` that the header's state (e.g., `apikey` vs `app`) has changed. +- `update-keybinds`: Sends updated keybinding preferences to the main process. +- `view-changed`: Notifies the main process that the visible view in `PickleGlassApp` has changed. +- `header-animation-complete`: Lets the main process know that a show/hide animation has finished. +- `cancel-hide-window`, `show-window`, `hide-window`: Commands to manage feature window visibility from the renderer. +- `session-did-close`: Notifies the main process that the user has manually closed the listen session. \ No newline at end of file diff --git a/REFACTORING_PLAN.md b/REFACTORING_PLAN.md new file mode 100644 index 0000000..fea86d5 --- /dev/null +++ b/REFACTORING_PLAN.md @@ -0,0 +1,119 @@ +# DB & Architecture Refactoring Plan + +## 1. Goal + +DB 접근 로직을 **Electron 메인 프로세스로 중앙화**하고, **Feature 중심의 계층형 아키텍처**를 도입하여 코드의 안정성과 유지보수성을 극대화한다. + +--- + +## 2. Architecture: AS-IS → TO-BE + +```mermaid +graph TD + subgraph "AS-IS: 다중 접근 (충돌 위험)" + A_Main[Main Process] --> A_DB[(DB)] + A_Backend[Web Backend] --> A_DB + A_Browser[Browser] -- HTTP --> A_Backend + style A_Backend fill:#f99 + end + + subgraph "TO-BE: 단일 접근 (안정)" + B_Main[Main Process] --> B_DB[(DB)] + B_Backend[Web Backend] -- IPC --> B_Main + B_Browser[Browser] -- HTTP --> B_Backend + style B_Main fill:#9f9 + end +``` + +--- + +## 3. Target Folder Structure + +- `features` : 기능별로 View, Service, Repository를 그룹화하여 응집도 상승 +- `common`: 여러 기능이 공유하는 Repository 및 저수준 Service 배치 + +``` +src/ +├── features/ +│ └── listen/ +│ ├── listenView.js # View (UI) +│ ├── listenService.js # ViewModel (Logic) +│ └── repositories/ # Model (Feature-Data) +│ ├── index.js # <- 저장소 전략 선택 +│ ├── sqlite.repository.js +│ └── firebase.repository.js +│ +└── common/ + ├── services/ + │ └── sqliteClient.js # <- DB 연결/관리 + └── repositories/ # <- 공통 데이터 + ├── user/ + └── session/ +``` +--- + +## 4. Key Changes + +- **DB 접근 단일화** + - 모든 DB Read/Write는 **Electron 메인 프로세스**에서만 수행. + - 웹 백엔드(`backend_node`)는 IPC 통신을 통해 메인 프로세스에 데이터를 요청. + - 웹 백엔드의 DB 직접 연결 (`better-sqlite3`, `db.js`) 코드 전부 제거. + +- **Repository 패턴 도입** + - 모든 SQL 쿼리는 `*.repository.js` 파일로 분리 및 이동. + - **공통 Repository:** `common/repositories/` (e.g., `user`, `session`) + - **기능별 Repository:** `features/*/repositories/` (e.g., `transcript`, `summary`) + +- **Service 역할 명확화** + - `*Service.js`는 비즈니스 로직만 담당. Repository를 호출하여 데이터를 요청/저장하지만, **직접 SQL을 다루지 않음.** + +- **`renderer.js` 제거** + - `renderer.js`의 기능들을 각 책임에 맞는 View, Service로 이전 후 최종적으로 파일 삭제. + +--- + +## 5. Future-Proofing: 저장소 전략 패턴 + +로그인 여부에 따라 `SQLite`와 `Firebase` 저장소를 동적으로 스위칭할 수 있는 기반을 마련한다. Service 코드는 수정할 필요 없이, Repository 구현체만 추가하면 된다. + +```javascript +// e.g., common/repositories/session/index.js + +const sqliteRepo = require('./sqlite.repository.js'); +const firebaseRepo = require('./firebase.repository.js'); + +// 현재 상태에 따라 적절한 저장소를 동적으로 반환 +exports.getRepository = () => { + return isUserLoggedIn() ? firebaseRepo : sqliteRepo; +}; +``` + +--- + +## 6. Design Pattern & Feature Structure Guide + +각 Feature는 아래의 3-Layer 구조를 따르며, 이는 MVVM 패턴의 정신을 차용한 것입니다. + +| 파일 / 폴더 | 계층 (Layer) | 역할 (Role) & 책임 (Responsibilities) | +| ---------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| `*View.js` | **View** | - **UI 렌더링:** Service로부터 받은 데이터를 화면에 표시.
- **사용자 입력:** 클릭, 입력 등의 이벤트를 감지하여 Service에 명령 전달. | +| `*Service.js` | **ViewModel** | - **상태 관리:** Feature에 필요한 모든 상태(State)를 소유하고 관리.
- **비즈니스 로직:** View의 요청을 받아 로직 수행.
- **데이터 조율:** Repository를 통해 데이터를 요청/저장하고, Main 프로세스와 IPC 통신. | +| `repositories/` | **Model / Data** | - **데이터 추상화:** DB(SQLite/Firebase)의 복잡한 쿼리를 숨기고, Service에 간단한 함수(`getById`, `save` 등)를 제공. | + +### 확장성 가이드: 파일이 너무 커진다면? + +"단일 책임 원칙"에 따라, 한 파일이 너무 많은 일을 하게 되면 주저 없이 분리합니다. + +- **Service Layer 분할:** + - **언제?** `listenService.js`가 STT 연결, 오디오 처리, 텍스트 분석 등 너무 많은 역할을 맡게 될 때. + - **어떻게?** 책임을 기준으로 더 작은 서비스로 분리합니다. + - `listenService.js` → **`sttService.js`**, **`audioService.js`**, **`analysisService.js`** + - 이때, 최상위 `listenService.js`는 여러 하위 서비스를 조율하는 **"Orchestrator(조정자)"**의 역할을 맡게 됩니다. + +- **View Layer 분할:** + - **언제?** `AssistantView.js` 하나의 파일이 너무 많은 UI 요소를 포함하고 복잡해질 때. + - **어떻게?** 재사용 가능한 UI 조각으로 분리합니다. + - `AssistantView.js` → **`TranscriptLog.js`**, **`SummaryDisplay.js`**, **`ActionButtons.js`** + +이 가이드를 따르면, 기능이 추가되거나 복잡해지더라도 코드베이스 전체가 일관되고 예측 가능한 구조를 유지할 수 있습니다. + diff --git a/REFACTORING_STATUS.md b/REFACTORING_STATUS.md new file mode 100644 index 0000000..6637ce0 --- /dev/null +++ b/REFACTORING_STATUS.md @@ -0,0 +1,80 @@ +# 리팩터링 진행 상황 보고서 + +> 이 문서는 `REFACTORING_PLAN.md`를 기준으로 현재까지의 진행 상황과 남은 과제를 추적합니다. + +### Phase 1: 아키텍처 기반 구축 (완료) + +이 단계의 목표는 **DB 접근을 메인 프로세스로 중앙화**하고, **계층형 아키텍처의 뼈대를 구축**하는 것이었습니다. 이 목표는 성공적으로 달성되었습니다. + +- **[✓] DB 접근 단일화:** + - `dataService.js`와 웹 백엔드의 DB 직접 접근 코드를 모두 제거했습니다. + - 이제 모든 DB 접근은 메인 프로세스의 `Repository` 계층을 통해서만 안전하게 이루어집니다. + +- **[✓] Repository 패턴 도입:** + - `userRepository`, `systemSettingsRepository`, `presetRepository` 등 공통 데이터 관리를 위한 저장소 계층을 성공적으로 구현하고 적용했습니다. + +- **[✓] Service 역할 명확화:** + - `authService`를 도입하여 모든 인증 로직을 중앙에서 관리하도록 했습니다. + - `liveSummaryService` 등 기존 서비스들이 더 이상 직접 DB에 접근하지 않고 Repository에 의존하도록 수정했습니다. + +### Phase 1.5: 인증 시스템 현대화 및 안정화 (완료) + +1단계에서 구축한 뼈대 위에, 앱의 핵심인 인증 시스템을 더욱 견고하고 사용자 친화적으로 만드는 작업을 완료했습니다. + +- **[✓] 완전한 인증 생명주기 관리:** + - `authService`가 Firebase 로그인 시 가상 API 키를 **자동으로 발급/저장**하고, 로그아웃 시 **자동으로 삭제**하는 전체 흐름을 구현했습니다. + +- **[✓] 상태 관리 중앙화 및 전파:** + - `authService`가 **유일한 진실의 원천(Single Source of Truth)**이 되어, `isLoggedIn`과 `hasApiKey` 상태를 명확히 구분하여 관리합니다. + - `user-state-changed`라는 단일 이벤트를 통해 모든 UI 컴포넌트가 일관된 상태 정보를 받도록 데이터 흐름을 정리했습니다. + +- **[✓] 레거시 코드 제거:** + - `windowManager`와 여러 렌더러 파일에 흩어져 있던 레거시 인증 로직, API 키 캐싱, 불필요한 IPC 핸들러들을 모두 제거하여 코드베이스를 깔끔하게 정리했습니다. + +- **[✓] 사용자 경험 최적화:** + - 로그인 세션을 영속화하여 **자동 로그인**을 구현했으며, 느린 네트워크 요청을 **비동기 백그라운드 처리**하여 UI 반응성을 극대화했습니다. + +--- + +### Phase 2: 기능별 모듈화 및 레거시 코드 완전 제거 (진행 예정) + +핵심 아키텍처가 안정화된 지금, 남아있는 기술 부채를 청산하고 앱 전체에 일관된 구조를 적용하는 마지막 단계를 진행합니다. + +#### 1. `renderer.js` 책임 분산 및 제거 (최우선 과제) + +- **최종 목표:** 거대 파일 `renderer.js` (1100+줄)를 완전히 제거하여, 각 기능의 UI 로직이 독립적인 모듈에서 관리되도록 합니다. +- **현황:** 현재 `renderer.js`는 `ask` 기능의 AI 메시지 전송, `listen` 기능의 오디오/스크린 캡처 및 전처리, 상태 관리 등 여러 책임이 복잡하게 얽혀있습니다. +- **수행 작업:** + 1. **`ask` 기능 책임 이전:** + - `renderer.js`의 `sendMessage`, `PICKLE_GLASS_SYSTEM_PROMPT`, 관련 유틸 함수(`formatRealtimeConversationHistory`, `getCurrentScreenshot` 등)를 `features/ask/askService.js` (또는 유사 모듈)로 이전합니다. + - `liveSummaryService.js`의 `save-ask-message` IPC 핸들러 로직을 `features/ask/repositories/askRepository.js`를 사용하는 `askService.js`로 이동시킵니다. + 2. **`listen` 기능 책임 이전:** + - `renderer.js`의 `startCapture`, `stopCapture`, `setupMicProcessing` 등 오디오/스크린 캡처 및 처리 관련 로직을 `features/listen/` 폴더 내의 적절한 파일 (예: `listenView.js` 또는 신규 `listenCaptureService.js`)로 이전합니다. + 3. **`renderer.js` 최종 제거:** + - 위 1, 2번 작업이 완료되어 `renderer.js`에 더 이상 의존하는 코드가 없을 때, 이 파일을 프로젝트에서 **삭제**합니다. + +#### 2. `listen` 기능 심화 리팩터링 + +- **목표:** 거대해진 `liveSummaryService.js`를 단일 책임 원칙에 따라 여러 개의 작은 서비스로 분리하여 유지보수성을 극대화합니다. +- **수행 작업:** + - `sttService.js`: STT 세션 연결 및 데이터 스트리밍을 전담합니다. + - `analysisService.js`: STT 텍스트를 받아 AI 모델에게 분석/요약을 요청하는 로직을 전담합니다. + - `listenService.js`: 상위 서비스로서, `sttService`와 `analysisService`를 조율하고 전체 "Listen" 기능의 상태를 관리하는 **조정자(Orchestrator)** 역할을 수행합니다. + +#### 3. `windowManager` 모듈화 + +- **목표:** 비대해진 `windowManager.js`의 책임들을 기능별로 분리하여, 각 모듈이 자신의 창 관련 로직만 책임지도록 구조를 개선합니다. +- **현황:** 현재 `windowManager.js`는 모든 창의 생성, 위치 계산, 단축키 등록, IPC 핸들링 등 너무 많은 역할을 수행하고 있습니다. +- **수행 작업:** + - **`windowLayoutManager.js`:** 여러 창의 위치를 동적으로 계산하고 배치하는 로직을 분리합니다. + - **`shortcutManager.js`:** 전역 단축키를 등록하고 관리하는 로직을 분리합니다. + - **`featureWindowManager.js` (가칭):** `ask`, `listen` 등 각 기능 창의 생성/소멸 및 관련 IPC 핸들러를 관리하는 로직을 분리합니다. + - `windowManager.js`: 최상위 관리자로서, `header` 창과 각 하위 관리자 모듈을 총괄하는 역할만 남깁니다. + +--- + +### Phase 3: 최종 정리 및 고도화 (향후) + +- **[ ] 전체 기능 회귀 테스트:** 모든 리팩터링 완료 후, 앱의 모든 기능이 의도대로 동작하는지 검증합니다. +- **[ ] 코드 클린업:** 디버깅용 `console.log`, 불필요한 주석 등을 최종적으로 정리합니다. +- **[ ] 문서 최신화:** `IPC_CHANNELS.md`를 포함한 모든 관련 문서를 최종 아키텍처에 맞게 업데이트합니다. \ No newline at end of file diff --git a/pickleglass_web/backend_node/db.js b/db_backup.js similarity index 100% rename from pickleglass_web/backend_node/db.js rename to db_backup.js diff --git a/pickleglass_web/backend_node/index.js b/pickleglass_web/backend_node/index.js index a60d6f0..a466490 100644 --- a/pickleglass_web/backend_node/index.js +++ b/pickleglass_web/backend_node/index.js @@ -1,9 +1,9 @@ const express = require('express'); const cors = require('cors'); -const db = require('./db'); +// const db = require('./db'); // No longer needed const { identifyUser } = require('./middleware/auth'); -function createApp() { +function createApp(eventBridge) { const app = express(); const webUrl = process.env.pickleglass_WEB_URL || 'http://localhost:3000'; @@ -20,6 +20,11 @@ function createApp() { res.json({ message: "pickleglass API is running" }); }); + app.use((req, res, next) => { + req.bridge = eventBridge; + next(); + }); + app.use('/api', identifyUser); app.use('/api/auth', require('./routes/auth')); diff --git a/pickleglass_web/backend_node/ipcBridge.js b/pickleglass_web/backend_node/ipcBridge.js new file mode 100644 index 0000000..46d1e04 --- /dev/null +++ b/pickleglass_web/backend_node/ipcBridge.js @@ -0,0 +1,19 @@ +const crypto = require('crypto'); + +function ipcRequest(req, channel, payload) { + return new Promise((resolve, reject) => { + const responseChannel = `${channel}-${crypto.randomUUID()}`; + + req.bridge.once(responseChannel, (response) => { + if (response.success) { + resolve(response.data); + } else { + reject(new Error(response.error || `IPC request to ${channel} failed`)); + } + }); + + req.bridge.emit('web-data-request', channel, responseChannel, payload); + }); +} + +module.exports = { ipcRequest }; \ No newline at end of file diff --git a/pickleglass_web/backend_node/jwt.js b/pickleglass_web/backend_node/jwt.js deleted file mode 100644 index abb79ad..0000000 --- a/pickleglass_web/backend_node/jwt.js +++ /dev/null @@ -1,13 +0,0 @@ -const jwt = require('jsonwebtoken'); -const SECRET = process.env.JWT_SECRET_KEY || 'change-me'; -const EXPIRE = 60 * 24; // minutes - -exports.sign = (sub, extra = {}) => jwt.sign({ sub, ...extra }, SECRET, { algorithm: 'HS256', expiresIn: `${EXPIRE}m` }); - -exports.verify = token => { - try { - return jwt.verify(token, SECRET).sub; - } catch { - return null; - } -}; diff --git a/pickleglass_web/backend_node/middleware/auth.js b/pickleglass_web/backend_node/middleware/auth.js index f20b0eb..cb7a265 100644 --- a/pickleglass_web/backend_node/middleware/auth.js +++ b/pickleglass_web/backend_node/middleware/auth.js @@ -1,5 +1,3 @@ -const { verify } = require('../jwt'); - function identifyUser(req, res, next) { const userId = req.get('X-User-ID'); diff --git a/pickleglass_web/backend_node/routes/auth.js b/pickleglass_web/backend_node/routes/auth.js index 5dbe34d..6ccdc3f 100644 --- a/pickleglass_web/backend_node/routes/auth.js +++ b/pickleglass_web/backend_node/routes/auth.js @@ -1,19 +1,24 @@ const express = require('express'); -const db = require('../db'); const router = express.Router(); +const { ipcRequest } = require('../ipcBridge'); -router.get('/status', (req, res) => { - const user = db.prepare('SELECT uid, display_name FROM users WHERE uid = ?').get('default_user'); - if (!user) { - return res.status(500).json({ error: 'Default user not initialized' }); - } - res.json({ - authenticated: true, - user: { - id: user.uid, - name: user.display_name +router.get('/status', async (req, res) => { + try { + const user = await ipcRequest(req, 'get-user-profile'); + if (!user) { + return res.status(500).json({ error: 'Default user not initialized' }); } - }); + res.json({ + authenticated: true, + user: { + id: user.uid, + name: user.display_name + } + }); + } catch (error) { + console.error('Failed to get auth status via IPC:', error); + res.status(500).json({ error: 'Failed to retrieve auth status' }); + } }); module.exports = router; diff --git a/pickleglass_web/backend_node/routes/conversations.js b/pickleglass_web/backend_node/routes/conversations.js index 903b446..7ea9d8a 100644 --- a/pickleglass_web/backend_node/routes/conversations.js +++ b/pickleglass_web/backend_node/routes/conversations.js @@ -1,121 +1,54 @@ const express = require('express'); -const db = require('../db'); const router = express.Router(); -const crypto = require('crypto'); -const validator = require('validator'); +const { ipcRequest } = require('../ipcBridge'); -router.get('/', (req, res) => { +router.get('/', async (req, res) => { try { - const sessions = db.prepare( - "SELECT id, uid, title, session_type, started_at, ended_at, sync_state, updated_at FROM sessions WHERE uid = ? ORDER BY started_at DESC" - ).all(req.uid); + const sessions = await ipcRequest(req, 'get-sessions'); res.json(sessions); } catch (error) { - console.error('Failed to get sessions:', error); + console.error('Failed to get sessions via IPC:', error); res.status(500).json({ error: 'Failed to retrieve sessions' }); } }); -router.post('/', (req, res) => { - const { title } = req.body; - const sessionId = crypto.randomUUID(); - const now = Math.floor(Date.now() / 1000); - +router.post('/', async (req, res) => { try { - db.prepare( - `INSERT INTO sessions (id, uid, title, started_at, updated_at) - VALUES (?, ?, ?, ?, ?)` - ).run(sessionId, req.uid, title || 'New Conversation', now, now); - - res.status(201).json({ id: sessionId, message: 'Session created successfully' }); + const result = await ipcRequest(req, 'create-session', req.body); + res.status(201).json({ ...result, message: 'Session created successfully' }); } catch (error) { - console.error('Failed to create session:', error); + console.error('Failed to create session via IPC:', error); res.status(500).json({ error: 'Failed to create session' }); } }); -router.get('/:session_id', (req, res) => { - const { session_id } = req.params; +router.get('/:session_id', async (req, res) => { try { - const session = db.prepare("SELECT * FROM sessions WHERE id = ?").get(session_id); - if (!session) { + const details = await ipcRequest(req, 'get-session-details', req.params.session_id); + if (!details) { return res.status(404).json({ error: 'Session not found' }); } - - const transcripts = db.prepare("SELECT * FROM transcripts WHERE session_id = ? ORDER BY start_at ASC").all(session_id); - const ai_messages = db.prepare("SELECT * FROM ai_messages WHERE session_id = ? ORDER BY sent_at ASC").all(session_id); - const summary = db.prepare("SELECT * FROM summaries WHERE session_id = ?").get(session_id); - - res.json({ - session, - transcripts, - ai_messages, - summary: summary || null - }); + res.json(details); } catch (error) { - console.error(`Failed to get session ${session_id}:`, error); + console.error(`Failed to get session details via IPC for ${req.params.session_id}:`, error); res.status(500).json({ error: 'Failed to retrieve session details' }); } }); -router.delete('/:session_id', (req, res) => { - const { session_id } = req.params; - - const session = db.prepare("SELECT id FROM sessions WHERE id = ?").get(session_id); - if (!session) { - return res.status(404).json({ error: 'Session not found' }); - } - +router.delete('/:session_id', async (req, res) => { try { - db.transaction(() => { - db.prepare("DELETE FROM transcripts WHERE session_id = ?").run(session_id); - db.prepare("DELETE FROM ai_messages WHERE session_id = ?").run(session_id); - db.prepare("DELETE FROM summaries WHERE session_id = ?").run(session_id); - db.prepare("DELETE FROM sessions WHERE id = ?").run(session_id); - })(); + await ipcRequest(req, 'delete-session', req.params.session_id); res.status(200).json({ message: 'Session deleted successfully' }); } catch (error) { - console.error(`Failed to delete session ${session_id}:`, error); + console.error(`Failed to delete session via IPC for ${req.params.session_id}:`, error); res.status(500).json({ error: 'Failed to delete session' }); } }); +// The search functionality will be more complex to move to IPC. +// For now, we can disable it or leave it as is, knowing it's a future task. router.get('/search', (req, res) => { - const { q } = req.query; - if (!q || !validator.isLength(q, { min: 3 })) { - return res.status(400).json({ error: 'Query parameter "q" is required' }); - } - // Sanitize and validate input - const sanitizedQuery = validator.escape(q.trim()); // Escapes HTML and special chars - if (sanitizedQuery.length === 0 || sanitizedQuery.length > 255) { - return res.status(400).json({ error: 'Query parameter "q" must be between 3 and 255 characters' }); - } - try { - const searchQuery = `%${sanitizedQuery}%`; - const sessionIds = db.prepare(` - SELECT DISTINCT session_id FROM ( - SELECT session_id FROM transcripts WHERE text LIKE ? - UNION - SELECT session_id FROM ai_messages WHERE content LIKE ? - UNION - SELECT session_id FROM summaries WHERE text LIKE ? OR tldr LIKE ? - ) - `).all(searchQuery, searchQuery, searchQuery, searchQuery).map(row => row.session_id); - - if (sessionIds.length === 0) { - return res.json([]); - } - - const placeholders = sessionIds.map(() => '?').join(','); - const sessions = db.prepare( - `SELECT id, uid, title, started_at, ended_at, sync_state, updated_at FROM sessions WHERE id IN (${placeholders}) ORDER BY started_at DESC` - ).all(sessionIds); - - res.json(sessions); - } catch (error) { - console.error('Search failed:', error); - res.status(500).json({ error: 'Failed to perform search' }); - } + res.status(501).json({ error: 'Search not implemented for IPC bridge yet.' }); }); module.exports = router; \ No newline at end of file diff --git a/pickleglass_web/backend_node/routes/presets.js b/pickleglass_web/backend_node/routes/presets.js index 8812f7e..c9c3f47 100644 --- a/pickleglass_web/backend_node/routes/presets.js +++ b/pickleglass_web/backend_node/routes/presets.js @@ -1,85 +1,43 @@ const express = require('express'); -const crypto = require('crypto'); -const db = require('../db'); const router = express.Router(); +const { ipcRequest } = require('../ipcBridge'); -router.get('/', (req, res) => { +router.get('/', async (req, res) => { try { - const presets = db.prepare( - `SELECT * FROM prompt_presets - WHERE uid = ? OR is_default = 1 - ORDER BY is_default DESC, title ASC` - ).all(req.uid); + const presets = await ipcRequest(req, 'get-presets'); res.json(presets); } catch (error) { - console.error('Failed to get presets:', error); + console.error('Failed to get presets via IPC:', error); res.status(500).json({ error: 'Failed to retrieve presets' }); } }); -router.post('/', (req, res) => { - const { title, prompt } = req.body; - if (!title || !prompt) { - return res.status(400).json({ error: 'Title and prompt are required' }); - } - - const presetId = crypto.randomUUID(); - const now = Math.floor(Date.now() / 1000); - +router.post('/', async (req, res) => { try { - db.prepare( - `INSERT INTO prompt_presets (id, uid, title, prompt, is_default, created_at, sync_state) - VALUES (?, ?, ?, ?, 0, ?, 'dirty')` - ).run(presetId, req.uid, title, prompt, now); - - res.status(201).json({ id: presetId, message: 'Preset created successfully' }); + const result = await ipcRequest(req, 'create-preset', req.body); + res.status(201).json({ ...result, message: 'Preset created successfully' }); } catch (error) { - console.error('Failed to create preset:', error); + console.error('Failed to create preset via IPC:', error); res.status(500).json({ error: 'Failed to create preset' }); } }); -router.put('/:id', (req, res) => { - const { id } = req.params; - const { title, prompt } = req.body; - if (!title || !prompt) { - return res.status(400).json({ error: 'Title and prompt are required' }); - } - +router.put('/:id', async (req, res) => { try { - const result = db.prepare( - `UPDATE prompt_presets - SET title = ?, prompt = ?, sync_state = 'dirty' - WHERE id = ? AND uid = ? AND is_default = 0` - ).run(title, prompt, id, req.uid); - - if (result.changes === 0) { - return res.status(404).json({ error: "Preset not found or you don't have permission to edit it." }); - } - + await ipcRequest(req, 'update-preset', { id: req.params.id, data: req.body }); res.json({ message: 'Preset updated successfully' }); } catch (error) { - console.error('Failed to update preset:', error); + console.error('Failed to update preset via IPC:', error); res.status(500).json({ error: 'Failed to update preset' }); } }); -router.delete('/:id', (req, res) => { - const { id } = req.params; - +router.delete('/:id', async (req, res) => { try { - const result = db.prepare( - `DELETE FROM prompt_presets - WHERE id = ? AND uid = ? AND is_default = 0` - ).run(id, req.uid); - - if (result.changes === 0) { - return res.status(404).json({ error: "Preset not found or you don't have permission to delete it." }); - } - + await ipcRequest(req, 'delete-preset', req.params.id); res.json({ message: 'Preset deleted successfully' }); } catch (error) { - console.error('Failed to delete preset:', error); + console.error('Failed to delete preset via IPC:', error); res.status(500).json({ error: 'Failed to delete preset' }); } }); diff --git a/pickleglass_web/backend_node/routes/user.js b/pickleglass_web/backend_node/routes/user.js index 8e5ff19..e0fe054 100644 --- a/pickleglass_web/backend_node/routes/user.js +++ b/pickleglass_web/backend_node/routes/user.js @@ -1,144 +1,76 @@ const express = require('express'); -const db = require('../db'); const router = express.Router(); +const { ipcRequest } = require('../ipcBridge'); -router.put('/profile', (req, res) => { - const { displayName } = req.body; - if (!displayName) return res.status(400).json({ error: 'displayName is required' }); - +router.put('/profile', async (req, res) => { try { - db.prepare("UPDATE users SET display_name = ? WHERE uid = ?").run(displayName, req.uid); + await ipcRequest(req, 'update-user-profile', req.body); res.json({ message: 'Profile updated successfully' }); } catch (error) { - console.error('Failed to update profile:', error); + console.error('Failed to update profile via IPC:', error); res.status(500).json({ error: 'Failed to update profile' }); } }); -router.get('/profile', (req, res) => { +router.get('/profile', async (req, res) => { try { - const user = db.prepare('SELECT uid, display_name, email FROM users WHERE uid = ?').get(req.uid); + const user = await ipcRequest(req, 'get-user-profile'); if (!user) return res.status(404).json({ error: 'User not found' }); res.json(user); } catch (error) { - console.error('Failed to get profile:', error); + console.error('Failed to get profile via IPC:', error); res.status(500).json({ error: 'Failed to get profile' }); } }); -router.post('/find-or-create', (req, res) => { - const { uid, displayName, email } = req.body; - if (!uid || !displayName || !email) { - return res.status(400).json({ error: 'uid, displayName, and email are required' }); - } - +router.post('/find-or-create', async (req, res) => { try { - const now = Math.floor(Date.now() / 1000); - db.prepare( - `INSERT INTO users (uid, display_name, email, created_at) - VALUES (?, ?, ?, ?) - ON CONFLICT(uid) DO NOTHING` - ).run(uid, displayName, email, now); - - const user = db.prepare('SELECT * FROM users WHERE uid = ?').get(uid); + const user = await ipcRequest(req, 'find-or-create-user', req.body); res.status(200).json(user); - } catch (error) { - console.error('Failed to find or create user:', error); + console.error('Failed to find or create user via IPC:', error); res.status(500).json({ error: 'Failed to find or create user' }); } }); -router.post('/api-key', (req, res) => { - const { apiKey } = req.body; - if (typeof apiKey !== 'string') { - return res.status(400).json({ error: 'API key must be a string' }); - } - +router.post('/api-key', async (req, res) => { try { - db.prepare("UPDATE users SET api_key = ? WHERE uid = ?").run(apiKey, req.uid); - res.json({ message: 'API key saved successfully' }); + await ipcRequest(req, 'save-api-key', req.body.apiKey); + res.json({ message: 'API key saved successfully' }); } catch (error) { - console.error('Failed to save API key:', error); + console.error('Failed to save API key via IPC:', error); res.status(500).json({ error: 'Failed to save API key' }); } }); -router.get('/api-key-status', (req, res) => { +router.get('/api-key-status', async (req, res) => { try { - const row = db.prepare('SELECT api_key FROM users WHERE uid = ?').get(req.uid); - if (!row) { - return res.status(404).json({ error: 'User not found' }); - } - res.json({ hasApiKey: !!row.api_key && row.api_key.length > 0 }); + const status = await ipcRequest(req, 'check-api-key-status'); + res.json(status); } catch (error) { - console.error('Failed to get API key status:', error); + console.error('Failed to get API key status via IPC:', error); res.status(500).json({ error: 'Failed to get API key status' }); } }); -router.delete('/profile', (req, res) => { +router.delete('/profile', async (req, res) => { try { - const user = db.prepare('SELECT uid FROM users WHERE uid = ?').get(req.uid); - if (!user) { - return res.status(404).json({ error: 'User not found' }); - } - - const userSessions = db.prepare('SELECT id FROM sessions WHERE uid = ?').all(user.uid); - const sessionIds = userSessions.map(s => s.id); - - db.transaction(() => { - if (sessionIds.length > 0) { - const placeholders = sessionIds.map(() => '?').join(','); - db.prepare(`DELETE FROM transcripts WHERE session_id IN (${placeholders})`).run(...sessionIds); - db.prepare(`DELETE FROM ai_messages WHERE session_id IN (${placeholders})`).run(...sessionIds); - db.prepare(`DELETE FROM summaries WHERE session_id IN (${placeholders})`).run(...sessionIds); - db.prepare(`DELETE FROM sessions WHERE uid = ?`).run(user.uid); - } - db.prepare('DELETE FROM prompt_presets WHERE uid = ?').run(user.uid); - db.prepare('DELETE FROM users WHERE uid = ?').run(user.uid); - })(); - + await ipcRequest(req, 'delete-account'); res.status(200).json({ message: 'User account and all data deleted successfully.' }); - } catch (error) { - console.error('Failed to delete user account:', error); + console.error('Failed to delete user account via IPC:', error); res.status(500).json({ error: 'Failed to delete user account' }); } }); -async function getUserBatchData(req, res) { - const { include = 'profile,presets,sessions' } = req.query; - +router.get('/batch', async (req, res) => { try { - const includes = include.split(',').map(item => item.trim()); - const result = {}; - - if (includes.includes('profile')) { - const user = db.prepare('SELECT uid, display_name, email FROM users WHERE uid = ?').get(req.uid); - result.profile = user || null; - } - - if (includes.includes('presets')) { - const presets = db.prepare('SELECT * FROM prompt_presets WHERE uid = ? OR is_default = 1').all(req.uid); - result.presets = presets || []; - } - - if (includes.includes('sessions')) { - const recent_sessions = db.prepare( - "SELECT id, title, started_at, updated_at FROM sessions WHERE uid = ? ORDER BY updated_at DESC LIMIT 10" - ).all(req.uid); - result.sessions = recent_sessions || []; - } - - res.json(result); - - } catch (error) { - console.error('Failed to get batch data:', error); + const result = await ipcRequest(req, 'get-batch-data', req.query.include); + res.json(result); + } catch(error) { + console.error('Failed to get batch data via IPC:', error); res.status(500).json({ error: 'Failed to get batch data' }); } -} - -router.get('/batch', getUserBatchData); +}); module.exports = router; diff --git a/pickleglass_web/utils/api.ts b/pickleglass_web/utils/api.ts index aa80e87..958325f 100644 --- a/pickleglass_web/utils/api.ts +++ b/pickleglass_web/utils/api.ts @@ -87,7 +87,11 @@ export interface SessionDetails { const isFirebaseMode = (): boolean => { - return firebaseAuth.currentUser !== null; + // The web frontend can no longer directly access Firebase state, + // so we assume communication always goes through the backend API. + // In the future, we can create an endpoint like /api/auth/status + // in the backend to retrieve the authentication state. + return false; }; const timestampToUnix = (timestamp: Timestamp): number => { @@ -185,41 +189,13 @@ const loadRuntimeConfig = async (): Promise => { return null; }; -const getApiUrlFromElectron = (): string | null => { - if (typeof window !== 'undefined') { - try { - const { ipcRenderer } = window.require?.('electron') || {}; - if (ipcRenderer) { - try { - const apiUrl = ipcRenderer.sendSync('get-api-url-sync'); - if (apiUrl) { - console.log('✅ API URL from Electron IPC:', apiUrl); - return apiUrl; - } - } catch (error) { - console.log('⚠️ Electron IPC failed:', error); - } - } - } catch (error) { - console.log('ℹ️ Not in Electron environment'); - } - } - return null; -}; - let apiUrlInitialized = false; let initializationPromise: Promise | null = null; const initializeApiUrl = async () => { if (apiUrlInitialized) return; - const electronUrl = getApiUrlFromElectron(); - if (electronUrl) { - API_ORIGIN = electronUrl; - apiUrlInitialized = true; - return; - } - + // Electron IPC 관련 코드를 모두 제거하고 runtime-config.json 또는 fallback에만 의존합니다. const runtimeUrl = await loadRuntimeConfig(); if (runtimeUrl) { API_ORIGIN = runtimeUrl; diff --git a/pickleglass_web/utils/auth.ts b/pickleglass_web/utils/auth.ts index c3de542..afac3b2 100644 --- a/pickleglass_web/utils/auth.ts +++ b/pickleglass_web/utils/auth.ts @@ -36,21 +36,12 @@ export const useAuth = () => { setUser(profile); setUserInfo(profile); - - if (window.ipcRenderer) { - window.ipcRenderer.send('set-current-user', profile.uid); - } - } else { console.log('🏠 Local mode activated'); setMode('local'); setUser(defaultLocalUser); setUserInfo(defaultLocalUser); - - if (window.ipcRenderer) { - window.ipcRenderer.send('set-current-user', defaultLocalUser.uid); - } } setIsLoading(false); }); diff --git a/preload.js b/preload.js new file mode 100644 index 0000000..e69de29 diff --git a/src/app/AppHeader.js b/src/app/AppHeader.js index faf633b..1ae4715 100644 --- a/src/app/AppHeader.js +++ b/src/app/AppHeader.js @@ -304,19 +304,6 @@ export class AppHeader extends LitElement { this.settingsHideTimer = null; this.isSessionActive = false; this.animationEndTimer = null; - - if (window.require) { - const { ipcRenderer } = window.require('electron'); - - ipcRenderer.on('toggle-header-visibility', () => { - this.toggleVisibility(); - }); - - ipcRenderer.on('cancel-hide-settings', () => { - this.cancelHideWindow('settings'); - }); - } - this.handleMouseMove = this.handleMouseMove.bind(this); this.handleMouseUp = this.handleMouseUp.bind(this); this.handleAnimationEnd = this.handleAnimationEnd.bind(this); @@ -478,8 +465,6 @@ export class AppHeader extends LitElement { if (window.require) { const { ipcRenderer } = window.require('electron'); - ipcRenderer.removeAllListeners('toggle-header-visibility'); - ipcRenderer.removeAllListeners('cancel-hide-settings'); if (this._sessionStateListener) { ipcRenderer.removeListener('session-state-changed', this._sessionStateListener); } diff --git a/src/app/HeaderController.js b/src/app/HeaderController.js index 313b59e..f88e40a 100644 --- a/src/app/HeaderController.js +++ b/src/app/HeaderController.js @@ -1,26 +1,9 @@ -import { initializeApp } from 'firebase/app'; -import { getAuth, onAuthStateChanged, GoogleAuthProvider, signInWithCredential, signInWithCustomToken, signOut } from 'firebase/auth'; - import './AppHeader.js'; import './ApiKeyHeader.js'; import './PermissionSetup.js'; -const firebaseConfig = { - apiKey: 'AIzaSyAgtJrmsFWG1C7m9S55HyT1laICEzuUS2g', - authDomain: 'pickle-3651a.firebaseapp.com', - projectId: 'pickle-3651a', - storageBucket: 'pickle-3651a.firebasestorage.app', - messagingSenderId: '904706892885', - appId: '1:904706892885:web:0e42b3dda796674ead20dc', - measurementId: 'G-SQ0WM6S28T', -}; - -const firebaseApp = initializeApp(firebaseConfig); -const auth = getAuth(firebaseApp); - class HeaderTransitionManager { constructor() { - this.headerContainer = document.getElementById('header-container'); this.currentHeaderType = null; // 'apikey' | 'app' | 'permission' this.apiKeyHeader = null; @@ -60,150 +43,24 @@ class HeaderTransitionManager { console.log('[HeaderController] Manager initialized'); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer - .invoke('get-current-api-key') - .then(storedKey => { - this.hasApiKey = !!storedKey; - }) - .catch(() => {}); - } - - if (window.require) { - const { ipcRenderer } = window.require('electron'); - - ipcRenderer.on('login-successful', async (event, payload) => { - const { customToken, token, error } = payload || {}; - try { - if (customToken) { - console.log('[HeaderController] Received custom token, signing in with custom token...'); - await signInWithCustomToken(auth, customToken); - return; - } - - if (token) { - console.log('[HeaderController] Received ID token, attempting Google credential sign-in...'); - const credential = GoogleAuthProvider.credential(token); - await signInWithCredential(auth, credential); - return; - } - - if (error) { - console.warn('[HeaderController] Login payload indicates verification failure. Showing permission setup.'); - // Show permission setup after login error - this.transitionToPermissionSetup(); - } - } catch (error) { - console.error('[HeaderController] Sign-in failed', error); - // Show permission setup after sign-in failure - this.transitionToPermissionSetup(); - } - }); - - - ipcRenderer.on('request-firebase-logout', async () => { - console.log('[HeaderController] Received request to sign out.'); - try { - this.hasApiKey = false; - await signOut(auth); - } catch (error) { - console.error('[HeaderController] Sign out failed', error); - } - }); - - ipcRenderer.on('api-key-validated', () => { - this.hasApiKey = true; - // Wait for animation to complete before transitioning - setTimeout(() => { - this.transitionToPermissionSetup(); - }, 350); // Give time for slide-out animation to complete - }); - - ipcRenderer.on('api-key-removed', () => { - this.hasApiKey = false; - this.transitionToApiKeyHeader(); - }); - - ipcRenderer.on('api-key-updated', () => { - this.hasApiKey = true; - if (!auth.currentUser) { - this.transitionToPermissionSetup(); - } - }); - - ipcRenderer.on('firebase-auth-success', async (event, firebaseUser) => { - console.log('[HeaderController] Received firebase-auth-success:', firebaseUser.uid); - try { - if (firebaseUser.idToken) { - const credential = GoogleAuthProvider.credential(firebaseUser.idToken); - await signInWithCredential(auth, credential); - console.log('[HeaderController] Firebase sign-in successful via ID token'); - } else { - console.warn('[HeaderController] No ID token received from deeplink, showing permission setup'); - // Show permission setup after Firebase auth - this.transitionToPermissionSetup(); - } - } catch (error) { - console.error('[HeaderController] Firebase auth failed:', error); - this.transitionToPermissionSetup(); - } - }); - } - this._bootstrap(); - onAuthStateChanged(auth, async user => { - console.log('[HeaderController] Auth state changed. User:', user ? user.email : 'null'); + if (window.require) { + const { ipcRenderer } = window.require('electron'); - if (window.require) { - const { ipcRenderer } = window.require('electron'); + ipcRenderer.on('user-state-changed', (event, userState) => { + console.log('[HeaderController] Received user state change:', userState); + this.handleStateUpdate(userState); + }); - let userDataWithToken = null; - if (user) { - try { - const idToken = await user.getIdToken(); - userDataWithToken = { - uid: user.uid, - email: user.email, - name: user.displayName, - photoURL: user.photoURL, - idToken: idToken, - }; - } catch (error) { - console.error('[HeaderController] Failed to get ID token:', error); - userDataWithToken = { - uid: user.uid, - email: user.email, - name: user.displayName, - photoURL: user.photoURL, - idToken: null, - }; - } + ipcRenderer.on('auth-failed', (event, { message }) => { + console.error('[HeaderController] Received auth failure from main process:', message); + if (this.apiKeyHeader) { + this.apiKeyHeader.errorMessage = 'Authentication failed. Please try again.'; + this.apiKeyHeader.isLoading = false; } - - ipcRenderer.invoke('firebase-auth-state-changed', userDataWithToken).catch(console.error); - } - - if (!this.isInitialized) { - this.isInitialized = true; - return; // Skip on initial load - bootstrap handles it - } - - // Only handle state changes after initial load - if (user) { - console.log('[HeaderController] User logged in, updating hasApiKey and checking permissions...'); - this.hasApiKey = true; // User login should provide API key - // Delay permission check to ensure smooth login flow - setTimeout(() => this.transitionToPermissionSetup(), 500); - } else if (this.hasApiKey) { - console.log('[HeaderController] No Firebase user but API key exists, checking if permission setup is needed...'); - setTimeout(() => this.transitionToPermissionSetup(), 500); - } else { - console.log('[HeaderController] No auth & no API key — showing ApiKeyHeader'); - this.transitionToApiKeyHeader(); - } - }); + }); + } } notifyHeaderState(stateOverride) { @@ -214,40 +71,36 @@ class HeaderTransitionManager { } async _bootstrap() { - let storedKey = null; + // The initial state will be sent by the main process via 'user-state-changed' + // We just need to request it. if (window.require) { - try { - storedKey = await window - .require('electron') - .ipcRenderer.invoke('get-current-api-key'); - } catch (_) {} - } - this.hasApiKey = !!storedKey; - - const user = await new Promise(resolve => { - const unsubscribe = onAuthStateChanged(auth, u => { - unsubscribe(); - resolve(u); - }); - }); - - // check flow order: API key -> Permissions -> App - if (!user && !this.hasApiKey) { - // No auth and no API key -> show API key input - await this._resizeForApiKey(); - this.ensureHeader('apikey'); + const userState = await window.require('electron').ipcRenderer.invoke('get-current-user'); + console.log('[HeaderController] Bootstrapping with initial user state:', userState); + this.handleStateUpdate(userState); } else { - // Has API key or user -> check permissions first + // Fallback for non-electron environment (testing/web) + this.ensureHeader('apikey'); + } + } + + async handleStateUpdate(userState) { + const { isLoggedIn, hasApiKey } = userState; + + if (isLoggedIn) { + // Firebase user: Check permissions, then show App or Permission Setup const permissionResult = await this.checkPermissions(); if (permissionResult.success) { - // All permissions granted -> go to app - await this._resizeForApp(); - this.ensureHeader('app'); + this.transitionToAppHeader(); } else { - // Permissions needed -> show permission setup - await this._resizeForPermissionSetup(); - this.ensureHeader('permission'); + this.transitionToPermissionSetup(); } + } else if (hasApiKey) { + // API Key only user: Skip permission check, go directly to App + this.transitionToAppHeader(); + } else { + // No auth at all + await this._resizeForApiKey(); + this.ensureHeader('apikey'); } } @@ -290,25 +143,8 @@ class HeaderTransitionManager { return this._resizeForApp(); } - const canAnimate = - animate && - (this.apiKeyHeader || this.permissionSetup) && - this.currentHeaderType !== 'app'; - - if (canAnimate && this.apiKeyHeader?.startSlideOutAnimation) { - const old = this.apiKeyHeader; - const onEnd = () => { - clearTimeout(fallback); - this._resizeForApp().then(() => this.ensureHeader('app')); - }; - old.addEventListener('animationend', onEnd, { once: true }); - old.startSlideOutAnimation(); - - const fallback = setTimeout(onEnd, 450); - } else { - this.ensureHeader('app'); - this._resizeForApp(); - } + await this._resizeForApp(); + this.ensureHeader('app'); } _resizeForApp() { @@ -335,16 +171,6 @@ class HeaderTransitionManager { .catch(() => {}); } - async transitionToApiKeyHeader() { - await this._resizeForApiKey(); - - if (this.currentHeaderType !== 'apikey') { - this.ensureHeader('apikey'); - } - - if (this.apiKeyHeader) this.apiKeyHeader.reset(); - } - async checkPermissions() { if (!window.require) { return { success: true }; @@ -353,7 +179,6 @@ class HeaderTransitionManager { const { ipcRenderer } = window.require('electron'); try { - // Check permission status const permissions = await ipcRenderer.invoke('check-system-permissions'); console.log('[HeaderController] Current permissions:', permissions); @@ -361,7 +186,6 @@ class HeaderTransitionManager { return { success: true }; } - // If permissions are not set up, return false let errorMessage = ''; if (!permissions.microphone && !permissions.screen) { errorMessage = 'Microphone and screen recording access required'; diff --git a/src/app/PickleGlassApp.js b/src/app/PickleGlassApp.js index a2fd887..eb639eb 100644 --- a/src/app/PickleGlassApp.js +++ b/src/app/PickleGlassApp.js @@ -83,10 +83,6 @@ export class PickleGlassApp extends LitElement { ipcRenderer.on('click-through-toggled', (_, isEnabled) => { this._isClickThrough = isEnabled; }); - ipcRenderer.on('show-view', (_, view) => { - this.currentView = view; - this.isMainViewVisible = true; - }); ipcRenderer.on('start-listening-session', () => { console.log('Received start-listening-session command, calling handleListenClick.'); this.handleListenClick(); @@ -100,7 +96,6 @@ export class PickleGlassApp extends LitElement { const { ipcRenderer } = window.require('electron'); ipcRenderer.removeAllListeners('update-status'); ipcRenderer.removeAllListeners('click-through-toggled'); - ipcRenderer.removeAllListeners('show-view'); ipcRenderer.removeAllListeners('start-listening-session'); } } @@ -110,10 +105,7 @@ export class PickleGlassApp extends LitElement { this.requestWindowResize(); } - if (changedProperties.has('currentView') && window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.send('view-changed', this.currentView); - + if (changedProperties.has('currentView')) { const viewContainer = this.shadowRoot?.querySelector('.view-container'); if (viewContainer) { viewContainer.classList.add('entering'); diff --git a/src/app/content.html b/src/app/content.html index 48c7691..9ce8d1c 100644 --- a/src/app/content.html +++ b/src/app/content.html @@ -253,17 +253,6 @@ }, 250); }); - ipcRenderer.on('settings-window-show-animation', () => { - console.log('Starting settings window show animation'); - app.classList.remove('window-hidden', 'window-sliding-up', 'settings-window-hide'); - app.classList.add('settings-window-show'); - - if (animationTimeout) clearTimeout(animationTimeout); - animationTimeout = setTimeout(() => { - app.classList.remove('settings-window-show'); - }, 220); - }); - ipcRenderer.on('window-hide-animation', () => { console.log('Starting window hide animation'); app.classList.remove('window-sliding-down', 'settings-window-show'); diff --git a/src/common/repositories/preset/index.js b/src/common/repositories/preset/index.js new file mode 100644 index 0000000..ebf7f77 --- /dev/null +++ b/src/common/repositories/preset/index.js @@ -0,0 +1,19 @@ +const sqliteRepository = require('./sqlite.repository'); +// const firebaseRepository = require('./firebase.repository'); +const authService = require('../../../common/services/authService'); + +function getRepository() { + // const user = authService.getCurrentUser(); + // if (user.isLoggedIn) { + // return firebaseRepository; + // } + return sqliteRepository; +} + +module.exports = { + getPresets: (...args) => getRepository().getPresets(...args), + getPresetTemplates: (...args) => getRepository().getPresetTemplates(...args), + create: (...args) => getRepository().create(...args), + update: (...args) => getRepository().update(...args), + delete: (...args) => getRepository().delete(...args), +}; \ No newline at end of file diff --git a/src/common/repositories/preset/sqlite.repository.js b/src/common/repositories/preset/sqlite.repository.js new file mode 100644 index 0000000..579fcbd --- /dev/null +++ b/src/common/repositories/preset/sqlite.repository.js @@ -0,0 +1,87 @@ +const sqliteClient = require('../../services/sqliteClient'); + +function getPresets(uid) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = ` + SELECT * FROM prompt_presets + WHERE uid = ? OR is_default = 1 + ORDER BY is_default DESC, title ASC + `; + db.all(query, [uid], (err, rows) => { + if (err) { + console.error('SQLite: Failed to get presets:', err); + reject(err); + } else { + resolve(rows); + } + }); + }); +} + +function getPresetTemplates() { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = ` + SELECT * FROM prompt_presets + WHERE is_default = 1 + ORDER BY title ASC + `; + db.all(query, [], (err, rows) => { + if (err) { + console.error('SQLite: Failed to get preset templates:', err); + reject(err); + } else { + resolve(rows); + } + }); + }); +} + +function create({ uid, title, prompt }) { + const db = sqliteClient.getDb(); + const presetId = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = `INSERT INTO prompt_presets (id, uid, title, prompt, is_default, created_at, sync_state) VALUES (?, ?, ?, ?, 0, ?, 'dirty')`; + + return new Promise((resolve, reject) => { + db.run(query, [presetId, uid, title, prompt, now], function(err) { + if (err) reject(err); + else resolve({ id: presetId }); + }); + }); +} + +function update(id, { title, prompt }, uid) { + const db = sqliteClient.getDb(); + const query = `UPDATE prompt_presets SET title = ?, prompt = ?, sync_state = 'dirty' WHERE id = ? AND uid = ? AND is_default = 0`; + + return new Promise((resolve, reject) => { + db.run(query, [title, prompt, id, uid], function(err) { + if (err) reject(err); + else if (this.changes === 0) reject(new Error("Preset not found or permission denied.")); + else resolve({ changes: this.changes }); + }); + }); +} + +function del(id, uid) { + const db = sqliteClient.getDb(); + const query = `DELETE FROM prompt_presets WHERE id = ? AND uid = ? AND is_default = 0`; + + return new Promise((resolve, reject) => { + db.run(query, [id, uid], function(err) { + if (err) reject(err); + else if (this.changes === 0) reject(new Error("Preset not found or permission denied.")); + else resolve({ changes: this.changes }); + }); + }); +} + +module.exports = { + getPresets, + getPresetTemplates, + create, + update, + delete: del +}; \ No newline at end of file diff --git a/src/common/repositories/session/index.js b/src/common/repositories/session/index.js new file mode 100644 index 0000000..42e7ec0 --- /dev/null +++ b/src/common/repositories/session/index.js @@ -0,0 +1,26 @@ +const sqliteRepository = require('./sqlite.repository'); +// const firebaseRepository = require('./firebase.repository'); // Future implementation +const authService = require('../../../common/services/authService'); + +function getRepository() { + // In the future, we can check the user's login status from authService + // const user = authService.getCurrentUser(); + // if (user.isLoggedIn) { + // return firebaseRepository; + // } + return sqliteRepository; +} + +// Directly export functions for ease of use, decided by the strategy +module.exports = { + getById: (...args) => getRepository().getById(...args), + create: (...args) => getRepository().create(...args), + getAllByUserId: (...args) => getRepository().getAllByUserId(...args), + updateTitle: (...args) => getRepository().updateTitle(...args), + deleteWithRelatedData: (...args) => getRepository().deleteWithRelatedData(...args), + end: (...args) => getRepository().end(...args), + updateType: (...args) => getRepository().updateType(...args), + touch: (...args) => getRepository().touch(...args), + getOrCreateActive: (...args) => getRepository().getOrCreateActive(...args), + endAllActiveSessions: (...args) => getRepository().endAllActiveSessions(...args), +}; \ No newline at end of file diff --git a/src/common/repositories/session/sqlite.repository.js b/src/common/repositories/session/sqlite.repository.js new file mode 100644 index 0000000..3f3ecac --- /dev/null +++ b/src/common/repositories/session/sqlite.repository.js @@ -0,0 +1,189 @@ +const sqliteClient = require('../../services/sqliteClient'); + +function getById(id) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + db.get('SELECT * FROM sessions WHERE id = ?', [id], (err, row) => { + if (err) reject(err); + else resolve(row); + }); + }); +} + +function create(uid, type = 'ask') { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const sessionId = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = `INSERT INTO sessions (id, uid, title, session_type, started_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)`; + + db.run(query, [sessionId, uid, `Session @ ${new Date().toLocaleTimeString()}`, type, now, now], function(err) { + if (err) { + console.error('SQLite: Failed to create session:', err); + reject(err); + } else { + console.log(`SQLite: Created session ${sessionId} for user ${uid} (type: ${type})`); + resolve(sessionId); + } + }); + }); +} + +function getAllByUserId(uid) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = "SELECT id, uid, title, session_type, started_at, ended_at, sync_state, updated_at FROM sessions WHERE uid = ? ORDER BY started_at DESC"; + db.all(query, [uid], (err, rows) => { + if (err) reject(err); + else resolve(rows); + }); + }); +} + +function updateTitle(id, title) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + db.run('UPDATE sessions SET title = ? WHERE id = ?', [title, id], function(err) { + if (err) reject(err); + else resolve({ changes: this.changes }); + }); + }); +} + +function deleteWithRelatedData(id) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + db.serialize(() => { + db.run("BEGIN TRANSACTION;"); + const queries = [ + "DELETE FROM transcripts WHERE session_id = ?", + "DELETE FROM ai_messages WHERE session_id = ?", + "DELETE FROM summaries WHERE session_id = ?", + "DELETE FROM sessions WHERE id = ?" + ]; + queries.forEach(query => { + db.run(query, [id], (err) => { + if (err) { + db.run("ROLLBACK;"); + return reject(err); + } + }); + }); + db.run("COMMIT;", (err) => { + if (err) { + db.run("ROLLBACK;"); + return reject(err); + } + resolve({ success: true }); + }); + }); + }); +} + +function end(id) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const now = Math.floor(Date.now() / 1000); + const query = `UPDATE sessions SET ended_at = ?, updated_at = ? WHERE id = ?`; + db.run(query, [now, now, id], function(err) { + if (err) reject(err); + else resolve({ changes: this.changes }); + }); + }); +} + +function updateType(id, type) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const now = Math.floor(Date.now() / 1000); + const query = 'UPDATE sessions SET session_type = ?, updated_at = ? WHERE id = ?'; + db.run(query, [type, now, id], function(err) { + if (err) { + reject(err); + } else { + resolve({ changes: this.changes }); + } + }); + }); +} + +function touch(id) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const now = Math.floor(Date.now() / 1000); + const query = 'UPDATE sessions SET updated_at = ? WHERE id = ?'; + db.run(query, [now, id], function(err) { + if (err) reject(err); + else resolve({ changes: this.changes }); + }); + }); +} + +async function getOrCreateActive(uid, requestedType = 'ask') { + const db = sqliteClient.getDb(); + + // 1. Look for ANY active session for the user (ended_at IS NULL). + // Prefer 'listen' sessions over 'ask' sessions to ensure continuity. + const findQuery = ` + SELECT id, session_type FROM sessions + WHERE uid = ? AND ended_at IS NULL + ORDER BY CASE session_type WHEN 'listen' THEN 1 WHEN 'ask' THEN 2 ELSE 3 END + LIMIT 1 + `; + + const activeSession = await new Promise((resolve, reject) => { + db.get(findQuery, [uid], (err, row) => { + if (err) reject(err); + else resolve(row); + }); + }); + + if (activeSession) { + // An active session exists. + console.log(`[Repo] Found active session ${activeSession.id} of type ${activeSession.session_type}`); + + // 2. Promotion Logic: If it's an 'ask' session and we need 'listen', promote it. + if (activeSession.session_type === 'ask' && requestedType === 'listen') { + await updateType(activeSession.id, 'listen'); + console.log(`[Repo] Promoted session ${activeSession.id} to 'listen' type.`); + } + + // 3. Touch the session and return its ID. + await touch(activeSession.id); + return activeSession.id; + } else { + // 4. No active session found, create a new one. + console.log(`[Repo] No active session for user ${uid}. Creating new '${requestedType}' session.`); + return create(uid, requestedType); + } +} + +function endAllActiveSessions() { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const now = Math.floor(Date.now() / 1000); + const query = `UPDATE sessions SET ended_at = ?, updated_at = ? WHERE ended_at IS NULL`; + db.run(query, [now, now], function(err) { + if (err) { + console.error('SQLite: Failed to end all active sessions:', err); + reject(err); + } else { + console.log(`[Repo] Ended ${this.changes} active session(s).`); + resolve({ changes: this.changes }); + } + }); + }); +} + +module.exports = { + getById, + create, + getAllByUserId, + updateTitle, + deleteWithRelatedData, + end, + updateType, + touch, + getOrCreateActive, + endAllActiveSessions, +}; \ No newline at end of file diff --git a/src/common/repositories/systemSettings/index.js b/src/common/repositories/systemSettings/index.js new file mode 100644 index 0000000..aef30f1 --- /dev/null +++ b/src/common/repositories/systemSettings/index.js @@ -0,0 +1,11 @@ +const sqliteRepository = require('./sqlite.repository'); + +// This repository is not user-specific, so we always return sqlite. +function getRepository() { + return sqliteRepository; +} + +module.exports = { + markPermissionsAsCompleted: (...args) => getRepository().markPermissionsAsCompleted(...args), + checkPermissionsCompleted: (...args) => getRepository().checkPermissionsCompleted(...args), +}; \ No newline at end of file diff --git a/src/common/repositories/systemSettings/sqlite.repository.js b/src/common/repositories/systemSettings/sqlite.repository.js new file mode 100644 index 0000000..1643395 --- /dev/null +++ b/src/common/repositories/systemSettings/sqlite.repository.js @@ -0,0 +1,14 @@ +const sqliteClient = require('../../services/sqliteClient'); + +async function markPermissionsAsCompleted() { + return sqliteClient.markPermissionsAsCompleted(); +} + +async function checkPermissionsCompleted() { + return sqliteClient.checkPermissionsCompleted(); +} + +module.exports = { + markPermissionsAsCompleted, + checkPermissionsCompleted, +}; \ No newline at end of file diff --git a/src/common/repositories/user/index.js b/src/common/repositories/user/index.js new file mode 100644 index 0000000..9455ef8 --- /dev/null +++ b/src/common/repositories/user/index.js @@ -0,0 +1,19 @@ +const sqliteRepository = require('./sqlite.repository'); +// const firebaseRepository = require('./firebase.repository'); +const authService = require('../../../common/services/authService'); + +function getRepository() { + // const user = authService.getCurrentUser(); + // if (user.isLoggedIn) { + // return firebaseRepository; + // } + return sqliteRepository; +} + +module.exports = { + findOrCreate: (...args) => getRepository().findOrCreate(...args), + getById: (...args) => getRepository().getById(...args), + saveApiKey: (...args) => getRepository().saveApiKey(...args), + update: (...args) => getRepository().update(...args), + deleteById: (...args) => getRepository().deleteById(...args), +}; \ No newline at end of file diff --git a/src/common/repositories/user/sqlite.repository.js b/src/common/repositories/user/sqlite.repository.js new file mode 100644 index 0000000..47da7ad --- /dev/null +++ b/src/common/repositories/user/sqlite.repository.js @@ -0,0 +1,107 @@ +const sqliteClient = require('../../services/sqliteClient'); + +function findOrCreate(user) { + const db = sqliteClient.getDb(); + const { uid, displayName, email } = user; + const now = Math.floor(Date.now() / 1000); + + const query = ` + INSERT INTO users (uid, display_name, email, created_at) + VALUES (?, ?, ?, ?) + ON CONFLICT(uid) DO UPDATE SET + display_name=excluded.display_name, + email=excluded.email + `; + + return new Promise((resolve, reject) => { + db.run(query, [uid, displayName, email, now], (err) => { + if (err) { + console.error('SQLite: Failed to find or create user:', err); + return reject(err); + } + getById(uid).then(resolve).catch(reject); + }); + }); +} + +function getById(uid) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + db.get('SELECT * FROM users WHERE uid = ?', [uid], (err, row) => { + if (err) reject(err); + else resolve(row); + }); + }); +} + +function saveApiKey(apiKey, uid, provider = 'openai') { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + db.run( + 'UPDATE users SET api_key = ?, provider = ? WHERE uid = ?', + [apiKey, provider, uid], + function(err) { + if (err) { + console.error('SQLite: Failed to save API key:', err); + reject(err); + } else { + console.log(`SQLite: API key saved for user ${uid} with provider ${provider}.`); + resolve({ changes: this.changes }); + } + } + ); + }); +} + +function update({ uid, displayName }) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + db.run('UPDATE users SET display_name = ? WHERE uid = ?', [displayName, uid], function(err) { + if (err) reject(err); + else resolve({ changes: this.changes }); + }); + }); +} + +function deleteById(uid) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const userSessions = db.prepare('SELECT id FROM sessions WHERE uid = ?').all(uid); + const sessionIds = userSessions.map(s => s.id); + + db.serialize(() => { + db.run("BEGIN TRANSACTION;"); + + try { + if (sessionIds.length > 0) { + const placeholders = sessionIds.map(() => '?').join(','); + db.prepare(`DELETE FROM transcripts WHERE session_id IN (${placeholders})`).run(...sessionIds); + db.prepare(`DELETE FROM ai_messages WHERE session_id IN (${placeholders})`).run(...sessionIds); + db.prepare(`DELETE FROM summaries WHERE session_id IN (${placeholders})`).run(...sessionIds); + db.prepare(`DELETE FROM sessions WHERE uid = ?`).run(uid); + } + db.prepare('DELETE FROM prompt_presets WHERE uid = ? AND is_default = 0').run(uid); + db.prepare('DELETE FROM users WHERE uid = ?').run(uid); + + db.run("COMMIT;", (err) => { + if (err) { + db.run("ROLLBACK;"); + return reject(err); + } + resolve({ success: true }); + }); + } catch (err) { + db.run("ROLLBACK;"); + reject(err); + } + }); + }); +} + +module.exports = { + findOrCreate, + getById, + saveApiKey, + update, + deleteById +}; \ No newline at end of file diff --git a/src/common/services/apiClient.js b/src/common/services/apiClient.js deleted file mode 100644 index 7f27e6a..0000000 --- a/src/common/services/apiClient.js +++ /dev/null @@ -1,239 +0,0 @@ -const axios = require('axios'); -const config = require('../config/config'); - -class APIClient { - constructor() { - this.baseURL = config.get('apiUrl'); - this.client = axios.create({ - baseURL: this.baseURL, - timeout: config.get('apiTimeout'), - headers: { - 'Content-Type': 'application/json' - } - }); - - this.client.interceptors.response.use( - (response) => response, - (error) => { - console.error('API request failed:', error.message); - if (error.response) { - console.error('response status:', error.response.status); - console.error('response data:', error.response.data); - } - return Promise.reject(error); - } - ); - } - - async initialize() { - try { - const response = await this.client.get('/api/auth/status'); - console.log('[APIClient] checked default user status:', response.data); - return true; - } catch (error) { - console.error('[APIClient] failed to initialize:', error); - return false; - } - } - - async checkConnection() { - try { - const response = await this.client.get('/'); - return response.status === 200; - } catch (error) { - return false; - } - } - - async saveApiKey(apiKey) { - try { - const response = await this.client.post('/api/user/api-key', { apiKey }); - return response.data; - } catch (error) { - console.error('failed to save api key:', error); - throw error; - } - } - - async checkApiKey() { - try { - const response = await this.client.get('/api/user/api-key'); - return response.data; - } catch (error) { - console.error('failed to check api key:', error); - return { hasApiKey: false }; - } - } - - async getUserBatchData(includes = ['profile', 'context', 'presets']) { - try { - const includeParam = includes.join(','); - const response = await this.client.get(`/api/user/batch?include=${includeParam}`); - return response.data; - } catch (error) { - console.error('failed to get user batch data:', error); - return null; - } - } - - async getUserContext() { - try { - const response = await this.client.get('/api/user/context'); - return response.data.context; - } catch (error) { - console.error('fail to get user context:', error); - return null; - } - } - - async getUserProfile() { - try { - const response = await this.client.get('/api/user/profile'); - return response.data; - } catch (error) { - console.error('failed to get user profile:', error); - return null; - } - } - - async getUserPresets() { - try { - const response = await this.client.get('/api/user/presets'); - return response.data; - } catch (error) { - console.error('failed to get user presets:', error); - return []; - } - } - - async updateUserContext(context) { - try { - const response = await this.client.post('/api/user/context', context); - return response.data; - } catch (error) { - console.error('failed to update user context:', error); - throw error; - } - } - - async addActivity(activity) { - try { - const response = await this.client.post('/api/user/activities', activity); - return response.data; - } catch (error) { - console.error('failed to add activity:', error); - throw error; - } - } - - async getPresetTemplates() { - try { - const response = await this.client.get('/api/preset-templates'); - return response.data; - } catch (error) { - console.error('failed to get preset templates:', error); - return []; - } - } - - async updateUserProfile(profile) { - try { - const response = await this.client.post('/api/user/profile', profile); - return response.data; - } catch (error) { - console.error('failed to update user profile:', error); - throw error; - } - } - - async searchUsers(name = '') { - try { - const response = await this.client.get('/api/users/search', { - params: { name } - }); - return response.data; - } catch (error) { - console.error('failed to search users:', error); - return []; - } - } - - async getUserProfileById(userId) { - try { - const response = await this.client.get(`/api/users/${userId}/profile`); - return response.data; - } catch (error) { - console.error('failed to get user profile by id:', error); - return null; - } - } - - async saveConversationSession(sessionId, conversationHistory) { - try { - const payload = { - sessionId, - conversationHistory - }; - const response = await this.client.post('/api/conversations', payload); - return response.data; - } catch (error) { - console.error('failed to save conversation session:', error); - throw error; - } - } - - async getConversationSession(sessionId) { - try { - const response = await this.client.get(`/api/conversations/${sessionId}`); - return response.data; - } catch (error) { - console.error('failed to get conversation session:', error); - return null; - } - } - - async getAllConversationSessions() { - try { - const response = await this.client.get('/api/conversations'); - return response.data; - } catch (error) { - console.error('failed to get all conversation sessions:', error); - return []; - } - } - - async deleteConversationSession(sessionId) { - try { - const response = await this.client.delete(`/api/conversations/${sessionId}`); - return response.data; - } catch (error) { - console.error('failed to delete conversation session:', error); - throw error; - } - } - - async getSyncStatus() { - try { - const response = await this.client.get('/api/sync/status'); - return response.data; - } catch (error) { - console.error('failed to get sync status:', error); - return null; - } - } - - async getFullUserData() { - try { - const response = await this.client.get('/api/user/full'); - return response.data; - } catch (error) { - console.error('failed to get full user data:', error); - return null; - } - } -} - -const apiClient = new APIClient(); - -module.exports = apiClient; -module.exports = apiClient; \ No newline at end of file diff --git a/src/common/services/authService.js b/src/common/services/authService.js new file mode 100644 index 0000000..c7aab4e --- /dev/null +++ b/src/common/services/authService.js @@ -0,0 +1,179 @@ +const { onAuthStateChanged, signInWithCustomToken, signOut } = require('firebase/auth'); +const { BrowserWindow } = require('electron'); +const { getFirebaseAuth } = require('./firebaseClient'); +const userRepository = require('../repositories/user'); +const fetch = require('node-fetch'); + +async function getVirtualKeyByEmail(email, idToken) { + if (!idToken) { + throw new Error('Firebase ID token is required for virtual key request'); + } + + const resp = await fetch('https://serverless-api-sf3o.vercel.app/api/virtual_key', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${idToken}`, + }, + body: JSON.stringify({ email: email.trim().toLowerCase() }), + redirect: 'follow', + }); + + const json = await resp.json().catch(() => ({})); + if (!resp.ok) { + console.error('[VK] API request failed:', json.message || 'Unknown error'); + throw new Error(json.message || `HTTP ${resp.status}: Virtual key request failed`); + } + + const vKey = json?.data?.virtualKey || json?.data?.virtual_key || json?.data?.newVKey?.slug; + + if (!vKey) throw new Error('virtual key missing in response'); + return vKey; +} + +class AuthService { + constructor() { + this.currentUserId = 'default_user'; + this.currentUserMode = 'local'; // 'local' or 'firebase' + this.currentUser = null; + this.hasApiKey = false; // Add a flag for API key status + this.isInitialized = false; + } + + initialize() { + if (this.isInitialized) return; + + const auth = getFirebaseAuth(); + onAuthStateChanged(auth, async (user) => { + const previousUser = this.currentUser; + + if (user) { + // User signed IN + console.log(`[AuthService] Firebase user signed in:`, user.uid); + this.currentUser = user; + this.currentUserId = user.uid; + this.currentUserMode = 'firebase'; + this.hasApiKey = false; // Optimistically assume no key yet + + // Broadcast immediately to make UI feel responsive + this.broadcastUserState(); + + // Start background task to fetch and save virtual key + (async () => { + try { + const idToken = await user.getIdToken(true); + const virtualKey = await getVirtualKeyByEmail(user.email, idToken); + await userRepository.saveApiKey(virtualKey, user.uid, 'openai'); + console.log(`[AuthService] BG: Virtual key for ${user.email} has been saved.`); + // Now update the key status, which will trigger another broadcast + await this.updateApiKeyStatus(); + } catch (error) { + console.error('[AuthService] BG: Failed to fetch or save virtual key:', error); + } + })(); + + } else { + // User signed OUT + console.log(`[AuthService] Firebase user signed out.`); + if (previousUser) { + console.log(`[AuthService] Clearing API key for logged-out user: ${previousUser.uid}`); + await userRepository.saveApiKey(null, previousUser.uid); + } + this.currentUser = null; + this.currentUserId = 'default_user'; + this.currentUserMode = 'local'; + // Update API key status (e.g., if a local key for default_user exists) + // This will also broadcast the final logged-out state. + await this.updateApiKeyStatus(); + } + }); + + // Check for initial API key state + this.updateApiKeyStatus(); + + this.isInitialized = true; + console.log('[AuthService] Initialized and attached to Firebase Auth state.'); + } + + async signInWithCustomToken(token) { + const auth = getFirebaseAuth(); + try { + const userCredential = await signInWithCustomToken(auth, token); + console.log(`[AuthService] Successfully signed in with custom token for user:`, userCredential.user.uid); + // onAuthStateChanged will handle the state update and broadcast + } catch (error) { + console.error('[AuthService] Error signing in with custom token:', error); + throw error; // Re-throw to be handled by the caller + } + } + + async signOut() { + const auth = getFirebaseAuth(); + try { + await signOut(auth); + console.log('[AuthService] User sign-out initiated successfully.'); + // onAuthStateChanged will handle the state update and broadcast, + // which will also re-evaluate the API key status. + } catch (error) { + console.error('[AuthService] Error signing out:', error); + } + } + + broadcastUserState() { + const userState = this.getCurrentUser(); + console.log('[AuthService] Broadcasting user state change:', userState); + BrowserWindow.getAllWindows().forEach(win => { + if (win && !win.isDestroyed()) { + win.webContents.send('user-state-changed', userState); + } + }); + } + + /** + * Updates the internal API key status from the repository and broadcasts if changed. + */ + async updateApiKeyStatus() { + try { + const user = await userRepository.getById(this.currentUserId); + const newStatus = !!(user && user.api_key); + if (this.hasApiKey !== newStatus) { + console.log(`[AuthService] API key status changed to: ${newStatus}`); + this.hasApiKey = newStatus; + this.broadcastUserState(); + } + } catch (error) { + console.error('[AuthService] Error checking API key status:', error); + this.hasApiKey = false; + } + } + + getCurrentUserId() { + return this.currentUserId; + } + + getCurrentUser() { + const isLoggedIn = !!(this.currentUserMode === 'firebase' && this.currentUser); + + if (isLoggedIn) { + return { + uid: this.currentUser.uid, + email: this.currentUser.email, + displayName: this.currentUser.displayName, + mode: 'firebase', + isLoggedIn: true, + hasApiKey: this.hasApiKey // Always true for firebase users, but good practice + }; + } + return { + uid: this.currentUserId, // returns 'default_user' + email: 'contact@pickle.com', + displayName: 'Default User', + mode: 'local', + isLoggedIn: false, + hasApiKey: this.hasApiKey + }; + } +} + +const authService = new AuthService(); +module.exports = authService; \ No newline at end of file diff --git a/src/common/services/dataService.js b/src/common/services/dataService.js deleted file mode 100644 index 6ebc334..0000000 --- a/src/common/services/dataService.js +++ /dev/null @@ -1,158 +0,0 @@ -const config = require('../config/config'); - -class DataService { - constructor() { - this.cache = new Map(); - this.cacheTimeout = config.get('cacheTimeout'); - this.enableCaching = config.get('enableCaching'); - this.sqliteClient = null; - this.currentUserId = 'default_user'; - this.isInitialized = false; - - if (config.get('enableSQLiteStorage')) { - try { - this.sqliteClient = require('./sqliteClient'); - console.log('[DataService] SQLite storage enabled.'); - } catch (error) { - console.error('[DataService] Failed to load SQLite client:', error); - } - } - } - - async initialize() { - if (this.isInitialized || !this.sqliteClient) { - return; - } - - try { - await this.sqliteClient.connect(); - this.isInitialized = true; - console.log('[DataService] Initialized successfully'); - } catch (error) { - console.error('[DataService] Failed to initialize:', error); - throw error; - } - } - - setCurrentUser(uid) { - if (this.currentUserId !== uid) { - console.log(`[DataService] Current user switched to: ${uid}`); - this.currentUserId = uid; - this.clearCache(); - } - } - - getCacheKey(operation, params = '') { - return `${this.currentUserId}:${operation}:${params}`; - } - - getFromCache(key) { - if (!this.enableCaching) return null; - const cached = this.cache.get(key); - if (cached && (Date.now() - cached.timestamp) < this.cacheTimeout) { - return cached.data; - } - return null; - } - - setCache(key, data) { - if (!this.enableCaching) return; - this.cache.set(key, { data, timestamp: Date.now() }); - } - - clearCache() { - this.cache.clear(); - } - - async findOrCreateUser(firebaseUser) { - if (!this.sqliteClient) { - console.log('[DataService] SQLite client not available, skipping user creation'); - return firebaseUser; - } - - try { - await this.initialize(); - const existingUser = await this.sqliteClient.getUser(firebaseUser.uid); - - if (!existingUser) { - console.log(`[DataService] Creating new user in local DB: ${firebaseUser.uid}`); - await this.sqliteClient.findOrCreateUser({ - uid: firebaseUser.uid, - display_name: firebaseUser.displayName || firebaseUser.display_name, - email: firebaseUser.email - }); - } - - this.clearCache(); - return firebaseUser; - } catch (error) { - console.error('[DataService] Failed to sync Firebase user to local DB:', error); - return firebaseUser; - } - } - - async saveApiKey(apiKey) { - if (!this.sqliteClient) { - throw new Error("SQLite client not available."); - } - try { - await this.initialize(); - const result = await this.sqliteClient.saveApiKey(apiKey, this.currentUserId); - this.clearCache(); - return result; - } catch (error) { - console.error('[DataService] Failed to save API key to SQLite:', error); - throw error; - } - } - - async checkApiKey() { - if (!this.sqliteClient) return { hasApiKey: false }; - try { - await this.initialize(); - const user = await this.sqliteClient.getUser(this.currentUserId); - return { hasApiKey: !!user?.api_key && user.api_key.length > 0 }; - } catch (error) { - console.error('[DataService] Failed to check API key from SQLite:', error); - return { hasApiKey: false }; - } - } - - async getUserPresets() { - const cacheKey = this.getCacheKey('presets'); - const cached = this.getFromCache(cacheKey); - if (cached) return cached; - - if (!this.sqliteClient) return []; - try { - await this.initialize(); - const presets = await this.sqliteClient.getPresets(this.currentUserId); - this.setCache(cacheKey, presets); - return presets; - } catch (error) { - console.error('[DataService] Failed to get presets from SQLite:', error); - return []; - } - } - - async getPresetTemplates() { - const cacheKey = this.getCacheKey('preset_templates'); - const cached = this.getFromCache(cacheKey); - if (cached) return cached; - - if (!this.sqliteClient) return []; - try { - await this.initialize(); - const templates = await this.sqliteClient.getPresetTemplates(); - this.setCache(cacheKey, templates); - return templates; - } catch (error) { - console.error('[DataService] Failed to get preset templates from SQLite:', error); - return []; - } - } -} - -const dataService = new DataService(); - -module.exports = dataService; \ No newline at end of file diff --git a/src/common/services/firebaseClient.js b/src/common/services/firebaseClient.js new file mode 100644 index 0000000..5ccb6d5 --- /dev/null +++ b/src/common/services/firebaseClient.js @@ -0,0 +1,103 @@ +const { initializeApp } = require('firebase/app'); +const { initializeAuth } = require('firebase/auth'); +const Store = require('electron-store'); + +/** + * Firebase Auth expects the `persistence` option passed to `initializeAuth()` to be *classes*, + * not instances. It then calls `new PersistenceClass()` internally. + * + * The helper below returns such a class, pre-configured with an `electron-store` instance that + * will be shared across all constructed objects. This mirrors the pattern used by Firebase's own + * `browserLocalPersistence` implementation as well as community solutions for NodeJS. + */ +function createElectronStorePersistence(storeName = 'firebase-auth-session') { + // Create a single `electron-store` behind the scenes – all Persistence instances will use it. + const sharedStore = new Store({ name: storeName }); + + return class ElectronStorePersistence { + constructor() { + this.store = sharedStore; + this.type = 'LOCAL'; + } + + /** + * Firebase calls this to check whether the persistence is usable in the current context. + */ + _isAvailable() { + return Promise.resolve(true); + } + + async _set(key, value) { + this.store.set(key, value); + } + + async _get(key) { + return this.store.get(key) ?? null; + } + + async _remove(key) { + this.store.delete(key); + } + + /** + * These are used by Firebase to react to external storage events (e.g. multi-tab). + * Electron apps are single-renderer per process, so we can safely provide no-op + * implementations. + */ + _addListener(_key, _listener) { + // no-op + } + + _removeListener(_key, _listener) { + // no-op + } + }; +} + +const firebaseConfig = { + apiKey: 'AIzaSyAgtJrmsFWG1C7m9S55HyT1laICEzuUS2g', + authDomain: 'pickle-3651a.firebaseapp.com', + projectId: 'pickle-3651a', + storageBucket: 'pickle-3651a.firebasestorage.app', + messagingSenderId: '904706892885', + appId: '1:904706892885:web:0e42b3dda796674ead20dc', + measurementId: 'G-SQ0WM6S28T', +}; + +let firebaseApp = null; +let firebaseAuth = null; + +function initializeFirebase() { + if (firebaseApp) { + console.log('[FirebaseClient] Firebase already initialized.'); + return; + } + try { + firebaseApp = initializeApp(firebaseConfig); + + // Build a *class* persistence provider and hand it to Firebase. + const ElectronStorePersistence = createElectronStorePersistence('firebase-auth-session'); + + firebaseAuth = initializeAuth(firebaseApp, { + // `initializeAuth` accepts a single class or an array – we pass an array for future + // extensibility and to match Firebase examples. + persistence: [ElectronStorePersistence], + }); + + console.log('[FirebaseClient] Firebase initialized successfully with class-based electron-store persistence.'); + } catch (error) { + console.error('[FirebaseClient] Firebase initialization failed:', error); + } +} + +function getFirebaseAuth() { + if (!firebaseAuth) { + throw new Error("Firebase Auth has not been initialized. Call initializeFirebase() first."); + } + return firebaseAuth; +} + +module.exports = { + initializeFirebase, + getFirebaseAuth, +}; \ No newline at end of file diff --git a/src/common/services/sqliteClient.js b/src/common/services/sqliteClient.js index d91ccee..a022159 100644 --- a/src/common/services/sqliteClient.js +++ b/src/common/services/sqliteClient.js @@ -34,6 +34,13 @@ class SQLiteClient { }); } + getDb() { + if (!this.db) { + throw new Error("Database not connected. Call connect() first."); + } + return this.db; + } + async synchronizeSchema() { console.log('[DB Sync] Starting schema synchronization...'); const tablesInDb = await this.getTablesFromDb(); @@ -194,231 +201,19 @@ class SQLiteClient { }); } - async findOrCreateUser(user) { - return new Promise((resolve, reject) => { - const { uid, display_name, email } = user; - const now = Math.floor(Date.now() / 1000); - - const query = ` - INSERT INTO users (uid, display_name, email, created_at) - VALUES (?, ?, ?, ?) - ON CONFLICT(uid) DO UPDATE SET - display_name=excluded.display_name, - email=excluded.email - `; - - this.db.run(query, [uid, display_name, email, now], (err) => { - if (err) { - console.error('Failed to find or create user in SQLite:', err); - return reject(err); - } - this.getUser(uid).then(resolve).catch(reject); - }); - }); + async markPermissionsAsCompleted() { + return this.query( + 'INSERT OR REPLACE INTO system_settings (key, value) VALUES (?, ?)', + ['permissions_completed', 'true'] + ); } - async getUser(uid) { - return new Promise((resolve, reject) => { - this.db.get('SELECT * FROM users WHERE uid = ?', [uid], (err, row) => { - if (err) reject(err); - else resolve(row); - }); - }); - } - - async saveApiKey(apiKey, uid = this.defaultUserId, provider = 'openai') { - return new Promise((resolve, reject) => { - this.db.run( - 'UPDATE users SET api_key = ?, provider = ? WHERE uid = ?', - [apiKey, provider, uid], - function(err) { - if (err) { - console.error('SQLite: Failed to save API key:', err); - reject(err); - } else { - console.log(`SQLite: API key saved for user ${uid} with provider ${provider}.`); - resolve({ changes: this.changes }); - } - } - ); - }); - } - - async getPresets(uid) { - return new Promise((resolve, reject) => { - const query = ` - SELECT * FROM prompt_presets - WHERE uid = ? OR is_default = 1 - ORDER BY is_default DESC, title ASC - `; - this.db.all(query, [uid], (err, rows) => { - if (err) { - console.error('SQLite: Failed to get presets:', err); - reject(err); - } else { - resolve(rows); - } - }); - }); - } - - async getPresetTemplates() { - return new Promise((resolve, reject) => { - const query = ` - SELECT * FROM prompt_presets - WHERE is_default = 1 - ORDER BY title ASC - `; - this.db.all(query, [], (err, rows) => { - if (err) { - console.error('SQLite: Failed to get preset templates:', err); - reject(err); - } else { - resolve(rows); - } - }); - }); - } - - async getSession(id) { - return new Promise((resolve, reject) => { - this.db.get('SELECT * FROM sessions WHERE id = ?', [id], (err, row) => { - if (err) reject(err); - else resolve(row); - }); - }); - } - - async updateSessionType(id, type) { - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const query = 'UPDATE sessions SET session_type = ?, updated_at = ? WHERE id = ?'; - this.db.run(query, [type, now, id], function(err) { - if (err) { - reject(err); - } else { - resolve({ changes: this.changes }); - } - }); - }); - } - - async touchSession(id) { - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const query = 'UPDATE sessions SET updated_at = ? WHERE id = ?'; - this.db.run(query, [now, id], function(err) { - if (err) reject(err); - else resolve({ changes: this.changes }); - }); - }); - } - - async createSession(uid, type = 'ask') { - return new Promise((resolve, reject) => { - const sessionId = require('crypto').randomUUID(); - const now = Math.floor(Date.now() / 1000); - const query = `INSERT INTO sessions (id, uid, title, session_type, started_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)`; - - this.db.run(query, [sessionId, uid, `Session @ ${new Date().toLocaleTimeString()}`, type, now, now], function(err) { - if (err) { - console.error('SQLite: Failed to create session:', err); - reject(err); - } else { - console.log(`SQLite: Created session ${sessionId} for user ${uid} (type: ${type})`); - resolve(sessionId); - } - }); - }); - } - - async endSession(sessionId) { - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const query = `UPDATE sessions SET ended_at = ?, updated_at = ? WHERE id = ?`; - this.db.run(query, [now, now, sessionId], function(err) { - if (err) reject(err); - else resolve({ changes: this.changes }); - }); - }); - } - - async addTranscript({ sessionId, speaker, text }) { - return new Promise((resolve, reject) => { - this.touchSession(sessionId).catch(err => console.error("Failed to touch session", err)); - const transcriptId = require('crypto').randomUUID(); - const now = Math.floor(Date.now() / 1000); - const query = `INSERT INTO transcripts (id, session_id, start_at, speaker, text, created_at) VALUES (?, ?, ?, ?, ?, ?)`; - this.db.run(query, [transcriptId, sessionId, now, speaker, text, now], function(err) { - if (err) reject(err); - else resolve({ id: transcriptId }); - }); - }); - } - - async addAiMessage({ sessionId, role, content, model = 'gpt-4.1' }) { - return new Promise((resolve, reject) => { - this.touchSession(sessionId).catch(err => console.error("Failed to touch session", err)); - const messageId = require('crypto').randomUUID(); - const now = Math.floor(Date.now() / 1000); - const query = `INSERT INTO ai_messages (id, session_id, sent_at, role, content, model, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)`; - this.db.run(query, [messageId, sessionId, now, role, content, model, now], function(err) { - if (err) reject(err); - else resolve({ id: messageId }); - }); - }); - } - - async saveSummary({ sessionId, tldr, text, bullet_json, action_json, model = 'gpt-4.1' }) { - return new Promise((resolve, reject) => { - this.touchSession(sessionId).catch(err => console.error("Failed to touch session", err)); - const now = Math.floor(Date.now() / 1000); - const query = ` - INSERT INTO summaries (session_id, generated_at, model, text, tldr, bullet_json, action_json, updated_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(session_id) DO UPDATE SET - generated_at=excluded.generated_at, - model=excluded.model, - text=excluded.text, - tldr=excluded.tldr, - bullet_json=excluded.bullet_json, - action_json=excluded.action_json, - updated_at=excluded.updated_at - `; - this.db.run(query, [sessionId, now, model, text, tldr, bullet_json, action_json, now], function(err) { - if (err) reject(err); - else resolve({ changes: this.changes }); - }); - }); - } - - async runMigrations() { - return new Promise((resolve, reject) => { - console.log('[DB Migration] Checking schema for `sessions` table...'); - this.db.all("PRAGMA table_info(sessions)", (err, columns) => { - if (err) { - console.error('[DB Migration] Error checking sessions table schema:', err); - return reject(err); - } - - const hasSessionTypeCol = columns.some(col => col.name === 'session_type'); - - if (!hasSessionTypeCol) { - console.log('[DB Migration] `session_type` column missing. Altering table...'); - this.db.run("ALTER TABLE sessions ADD COLUMN session_type TEXT DEFAULT 'ask'", (alterErr) => { - if (alterErr) { - console.error('[DB Migration] Failed to add `session_type` column:', alterErr); - return reject(alterErr); - } - console.log('[DB Migration] `sessions` table updated successfully.'); - resolve(); - }); - } else { - console.log('[DB Migration] Schema is up to date.'); - resolve(); - } - }); - }); + async checkPermissionsCompleted() { + const result = await this.query( + 'SELECT value FROM system_settings WHERE key = ?', + ['permissions_completed'] + ); + return result.length > 0 && result[0].value === 'true'; } close() { diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 9098d7c..586e3f8 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -5,10 +5,11 @@ const os = require('os'); const util = require('util'); const execFile = util.promisify(require('child_process').execFile); const sharp = require('sharp'); -const sqliteClient = require('../common/services/sqliteClient'); +const authService = require('../common/services/authService'); +const systemSettingsRepository = require('../common/repositories/systemSettings'); +const userRepository = require('../common/repositories/user'); const fetch = require('node-fetch'); -let currentFirebaseUser = null; let isContentProtectionOn = true; let currentDisplayId = null; @@ -233,7 +234,7 @@ class WindowLayoutManager { const PAD = 8; - /* ① 헤더 중심 X를 “디스플레이 기준 상대좌표”로 변환 */ + /* ① 헤더 중심 X를 "디스플레이 기준 상대좌표"로 변환 */ const headerCenterXRel = headerBounds.x - workAreaX + headerBounds.width / 2; let askBounds = askVisible ? ask.getBounds() : null; @@ -1365,17 +1366,6 @@ function setupIpcHandlers(openaiSessionRef) { app.quit(); }); - ipcMain.handle('message-sending', async event => { - console.log('📨 Main: Received message-sending signal'); - const askWindow = windowPool.get('ask'); - if (askWindow && !askWindow.isDestroyed()) { - console.log('📤 Main: Sending hide-text-input to ask window'); - askWindow.webContents.send('hide-text-input'); - return { success: true }; - } - return { success: false }; - }); - ipcMain.handle('is-window-visible', (event, windowName) => { const window = windowPool.get(windowName); if (window && !window.isDestroyed()) { @@ -1444,46 +1434,6 @@ function setupIpcHandlers(openaiSessionRef) { } }); - ipcMain.handle('get-available-screens', async () => { - try { - const sources = await desktopCapturer.getSources({ - types: ['screen'], - thumbnailSize: { width: 300, height: 200 }, - }); - - const displays = screen.getAllDisplays(); - - return sources.map((source, index) => { - const display = displays[index] || displays[0]; - return { - id: source.id, - name: source.name, - thumbnail: source.thumbnail.toDataURL(), - display: { - id: display.id, - bounds: display.bounds, - workArea: display.workArea, - scaleFactor: display.scaleFactor, - isPrimary: display.id === screen.getPrimaryDisplay().id, - }, - }; - }); - } catch (error) { - console.error('Failed to get available screens:', error); - return []; - } - }); - - ipcMain.handle('set-capture-source', (event, sourceId) => { - selectedCaptureSourceId = sourceId; - console.log(`[Capture] Selected source: ${sourceId}`); - return { success: true }; - }); - - ipcMain.handle('get-capture-source', () => { - return selectedCaptureSourceId; - }); - ipcMain.on('update-keybinds', (event, newKeybinds) => { updateGlobalShortcuts(newKeybinds); }); @@ -1581,12 +1531,6 @@ function setupIpcHandlers(openaiSessionRef) { } }); - ipcMain.on('move-to-edge', (event, direction) => { - if (movementManager) { - movementManager.moveToEdge(direction); - } - }); - ipcMain.handle('force-close-window', (event, windowName) => { const window = windowPool.get(windowName); if (window && !window.isDestroyed()) { @@ -1627,68 +1571,7 @@ function setupIpcHandlers(openaiSessionRef) { }); ipcMain.handle('capture-screenshot', async (event, options = {}) => { - if (process.platform === 'darwin') { - try { - const tempPath = path.join(os.tmpdir(), `screenshot-${Date.now()}.jpg`); - - await execFile('screencapture', ['-x', '-t', 'jpg', tempPath]); - - const imageBuffer = await fs.promises.readFile(tempPath); - await fs.promises.unlink(tempPath); - - const resizedBuffer = await sharp(imageBuffer) - // .resize({ height: 1080 }) - .resize({ height: 384 }) - .jpeg({ quality: 80 }) - .toBuffer(); - - const base64 = resizedBuffer.toString('base64'); - const metadata = await sharp(resizedBuffer).metadata(); - - lastScreenshot = { - base64, - width: metadata.width, - height: metadata.height, - timestamp: Date.now(), - }; - - return { success: true, base64, width: metadata.width, height: metadata.height }; - } catch (error) { - console.error('Failed to capture and resize screenshot:', error); - return { success: false, error: error.message }; - } - } - - try { - const sources = await desktopCapturer.getSources({ - types: ['screen'], - thumbnailSize: { - width: 1920, - height: 1080, - }, - }); - - if (sources.length === 0) { - throw new Error('No screen sources available'); - } - const source = sources[0]; - const buffer = source.thumbnail.toJPEG(70); - const base64 = buffer.toString('base64'); - const size = source.thumbnail.getSize(); - - return { - success: true, - base64, - width: size.width, - height: size.height, - }; - } catch (error) { - console.error('Failed to capture screenshot using desktopCapturer:', error); - return { - success: false, - error: error.message, - }; - } + return captureScreenshot(options); }); ipcMain.handle('get-current-screenshot', async event => { @@ -1715,133 +1598,19 @@ function setupIpcHandlers(openaiSessionRef) { } }); - ipcMain.handle('firebase-auth-state-changed', (event, user) => { - console.log('[WindowManager] Firebase auth state changed:', user ? user.email : 'null'); - const previousUser = currentFirebaseUser; - - // 🛡️ Guard: ignore duplicate events where auth state did not actually change - const sameUser = user && previousUser && user.uid && previousUser.uid && user.uid === previousUser.uid; - const bothNull = !user && !previousUser; - if (sameUser || bothNull) { - // No real state change ➜ skip further processing - console.log('[WindowManager] No real state change, skipping further processing'); - return; - } - - currentFirebaseUser = user; - - if (user && user.email) { - (async () => { - try { - const existingKey = getStoredApiKey(); - if (existingKey) { - console.log('[WindowManager] Virtual key already exists, skipping fetch'); - return; - } - - if (!user.idToken) { - console.warn('[WindowManager] No ID token available, cannot fetch virtual key'); - return; - } - - console.log('[WindowManager] Fetching virtual key via onAuthStateChanged'); - const vKey = await getVirtualKeyByEmail(user.email, user.idToken); - console.log('[WindowManager] Virtual key fetched successfully'); - - setApiKey(vKey) - .then(() => { - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-updated'); - } - }); - }) - .catch(err => console.error('[WindowManager] Failed to save virtual key:', err)); - } catch (err) { - console.error('[WindowManager] Virtual key fetch failed:', err); - - if (err.message.includes('token') || err.message.includes('Authentication')) { - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - win.webContents.send('auth-error', { - message: 'Authentication expired. Please login again.', - shouldLogout: true, - }); - } - }); - } - } - })(); - } - - // If the user logged out, also hide the settings window - if (!user && previousUser) { - // ADDED: Only trigger on actual state change from logged in to logged out - console.log('[WindowManager] User logged out, clearing API key and notifying renderers'); - - setApiKey(null) - .then(() => { - console.log('[WindowManager] API key cleared successfully after logout'); - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-removed'); - } - }); - }) - .catch(err => { - console.error('[WindowManager] setApiKey error:', err); - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-removed'); - } - }); - }); - - const settingsWindow = windowPool.get('settings'); - if (settingsWindow && settingsWindow.isVisible()) { - settingsWindow.hide(); - console.log('[WindowManager] Settings window hidden after logout.'); - } - } - // Broadcast to all windows + ipcMain.handle('firebase-logout', async () => { + console.log('[WindowManager] Received request to log out.'); + + await authService.signOut(); + await setApiKey(null); + windowPool.forEach(win => { if (win && !win.isDestroyed()) { - win.webContents.send('firebase-user-updated', user); + win.webContents.send('api-key-removed'); } }); }); - ipcMain.handle('get-current-firebase-user', () => { - return currentFirebaseUser; - }); - - ipcMain.handle('firebase-logout', () => { - console.log('[WindowManager] Received request to log out.'); - setApiKey(null) - .then(() => { - console.log('[WindowManager] API key cleared successfully after logout'); - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-removed'); - } - }); - }) - .catch(err => { - console.error('[WindowManager] setApiKey error:', err); - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-removed'); - } - }); - }); - - const header = windowPool.get('header'); - if (header && !header.isDestroyed()) { - console.log('[WindowManager] Header window exists, sending to renderer...'); - header.webContents.send('request-firebase-logout'); - } - }); - ipcMain.handle('check-system-permissions', async () => { const { systemPreferences } = require('electron'); const permissions = { @@ -1898,7 +1667,7 @@ function setupIpcHandlers(openaiSessionRef) { // Req mic permission const granted = await systemPreferences.askForMediaAccess('microphone'); return { - success: granted, + success: granted, status: granted ? 'granted' : 'denied' }; } catch (error) { @@ -1944,11 +1713,8 @@ function setupIpcHandlers(openaiSessionRef) { ipcMain.handle('mark-permissions-completed', async () => { try { - // Store in SQLite that permissions have been completed - await sqliteClient.query( - 'INSERT OR REPLACE INTO system_settings (key, value) VALUES (?, ?)', - ['permissions_completed', 'true'] - ); + // This is a system-level setting, not user-specific. + await systemSettingsRepository.markPermissionsAsCompleted(); console.log('[Permissions] Marked permissions as completed'); return { success: true }; } catch (error) { @@ -1959,11 +1725,7 @@ function setupIpcHandlers(openaiSessionRef) { ipcMain.handle('check-permissions-completed', async () => { try { - const result = await sqliteClient.query( - 'SELECT value FROM system_settings WHERE key = ?', - ['permissions_completed'] - ); - const completed = result.length > 0 && result[0].value === 'true'; + const completed = await systemSettingsRepository.checkPermissionsCompleted(); console.log('[Permissions] Permissions completed status:', completed); return completed; } catch (error) { @@ -1971,21 +1733,27 @@ function setupIpcHandlers(openaiSessionRef) { return false; } }); + + ipcMain.handle('close-ask-window-if-empty', async () => { + const askWindow = windowPool.get('ask'); + if (askWindow && !askWindow.isFocused()) { + askWindow.hide(); + } + }); } - - -let storedApiKey = null; let storedProvider = 'openai'; async function setApiKey(apiKey, provider = 'openai') { - storedApiKey = apiKey; - storedProvider = provider; - console.log('[WindowManager] API key and provider stored (and will be persisted to DB)'); + console.log('[WindowManager] Persisting API key and provider to DB'); try { - await sqliteClient.saveApiKey(apiKey, sqliteClient.defaultUserId, provider); + await userRepository.saveApiKey(apiKey, authService.getCurrentUserId(), provider); console.log('[WindowManager] API key and provider saved to SQLite'); + + // Notify authService that the key status may have changed + await authService.updateApiKeyStatus(); + } catch (err) { console.error('[WindowManager] Failed to save API key to SQLite:', err); } @@ -2004,55 +1772,25 @@ async function setApiKey(apiKey, provider = 'openai') { }); } -async function loadApiKeyFromDb() { - try { - const user = await sqliteClient.getUser(sqliteClient.defaultUserId); - if (user && user.api_key) { - console.log('[WindowManager] API key and provider loaded from SQLite for default user.'); - storedApiKey = user.api_key; - storedProvider = user.provider || 'openai'; - return user.api_key; - } - return null; - } catch (error) { - console.error('[WindowManager] Failed to load API key from SQLite:', error); - return null; - } +async function getStoredApiKey() { + const userId = authService.getCurrentUserId(); + if (!userId) return null; + const user = await userRepository.getById(userId); + return user?.api_key || null; } -function getCurrentFirebaseUser() { - return currentFirebaseUser; -} - -function isFirebaseLoggedIn() { - return !!currentFirebaseUser; -} - -function setCurrentFirebaseUser(user) { - currentFirebaseUser = user; - console.log('[WindowManager] Firebase user updated:', user ? user.email : 'null'); -} - -function getStoredApiKey() { - return storedApiKey; -} - -function getStoredProvider() { - return storedProvider || 'openai'; +async function getStoredProvider() { + const userId = authService.getCurrentUserId(); + if (!userId) return 'openai'; + const user = await userRepository.getById(userId); + return user?.provider || 'openai'; } function setupApiKeyIPC() { const { ipcMain } = require('electron'); - ipcMain.handle('get-stored-api-key', async () => { - if (storedApiKey === null) { - const dbKey = await loadApiKeyFromDb(); - if (dbKey) { - await setApiKey(dbKey, storedProvider); - } - } - return storedApiKey; - }); + // Both handlers now do the same thing: fetch the key from the source of truth. + ipcMain.handle('get-stored-api-key', getStoredApiKey); ipcMain.handle('api-key-validated', async (event, data) => { console.log('[WindowManager] API key validation completed, saving...'); @@ -2090,21 +1828,8 @@ function setupApiKeyIPC() { return { success: true }; }); - - ipcMain.handle('get-current-api-key', async () => { - if (storedApiKey === null) { - const dbKey = await loadApiKeyFromDb(); - if (dbKey) { - await setApiKey(dbKey, storedProvider); - } - } - return storedApiKey; - }); - ipcMain.handle('get-ai-provider', async () => { - console.log('[WindowManager] AI provider requested from renderer'); - return storedProvider || 'openai'; - }); + ipcMain.handle('get-ai-provider', getStoredProvider); console.log('[WindowManager] API key related IPC handlers registered (SQLite-backed)'); } @@ -2470,42 +2195,40 @@ function setupWindowIpcHandlers(mainWindow, sendToRenderer, openaiSessionRef) { // ... other handlers like open-external, etc. can be added from the old file if needed } -function clearApiKey() { - setApiKey(null); -} +async function captureScreenshot(options = {}) { + if (process.platform === 'darwin') { + try { + const tempPath = path.join(os.tmpdir(), `screenshot-${Date.now()}.jpg`); -async function getVirtualKeyByEmail(email, idToken) { - if (!idToken) { - throw new Error('Firebase ID token is required for virtual key request'); + await execFile('screencapture', ['-x', '-t', 'jpg', tempPath]); + + const imageBuffer = await fs.promises.readFile(tempPath); + await fs.promises.unlink(tempPath); + + const resizedBuffer = await sharp(imageBuffer) + // .resize({ height: 1080 }) + .resize({ height: 384 }) + .jpeg({ quality: 80 }) + .toBuffer(); + + const base64 = resizedBuffer.toString('base64'); + const metadata = await sharp(resizedBuffer).metadata(); + + lastScreenshot = { + base64, + width: metadata.width, + height: metadata.height, + timestamp: Date.now(), + }; + + return { success: true, base64, width: metadata.width, height: metadata.height }; + } catch (error) { + console.error('Failed to capture and resize screenshot:', error); + return { success: false, error: error.message }; + } } - const resp = await fetch('https://serverless-api-sf3o.vercel.app/api/virtual_key', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${idToken}`, - }, - body: JSON.stringify({ email: email.trim().toLowerCase() }), - redirect: 'follow', - }); - - const json = await resp.json().catch(() => ({})); - if (!resp.ok) { - console.error('[VK] API request failed:', json.message || 'Unknown error'); - throw new Error(json.message || `HTTP ${resp.status}: Virtual key request failed`); - } - - const vKey = json?.data?.virtualKey || json?.data?.virtual_key || json?.data?.newVKey?.slug; - - if (!vKey) throw new Error('virtual key missing in response'); - return vKey; -} - -// Helper function to avoid code duplication -async function captureScreenshotInternal(options = {}) { try { - const quality = options.quality || 'medium'; - const sources = await desktopCapturer.getSources({ types: ['screen'], thumbnailSize: { @@ -2517,28 +2240,10 @@ async function captureScreenshotInternal(options = {}) { if (sources.length === 0) { throw new Error('No screen sources available'); } - const source = sources[0]; - const thumbnail = source.thumbnail; - - let jpegQuality; - switch (quality) { - case 'high': - jpegQuality = 90; - break; - case 'low': - jpegQuality = 50; - break; - case 'medium': - default: - jpegQuality = 70; - break; - } - - const buffer = thumbnail.toJPEG(jpegQuality); + const buffer = source.thumbnail.toJPEG(70); const base64 = buffer.toString('base64'); - - const size = thumbnail.getSize(); + const size = source.thumbnail.getSize(); return { success: true, @@ -2547,7 +2252,11 @@ async function captureScreenshotInternal(options = {}) { height: size.height, }; } catch (error) { - throw error; + console.error('Failed to capture screenshot using desktopCapturer:', error); + return { + success: false, + error: error.message, + }; } } @@ -2558,9 +2267,5 @@ module.exports = { setApiKey, getStoredApiKey, getStoredProvider, - clearApiKey, - getCurrentFirebaseUser, - isFirebaseLoggedIn, - setCurrentFirebaseUser, - getVirtualKeyByEmail, + captureScreenshot, }; diff --git a/src/features/ask/AskView.js b/src/features/ask/AskView.js index 437aa91..78e3ba3 100644 --- a/src/features/ask/AskView.js +++ b/src/features/ask/AskView.js @@ -703,9 +703,10 @@ export class AskView extends LitElement { handleWindowBlur() { if (!this.currentResponse && !this.isLoading && !this.isStreaming) { - const askWindow = window.require('electron').remote.getCurrentWindow(); - if (!askWindow.isFocused()) { - this.closeIfNoContent(); + // If there's no active content, ask the main process to close this window. + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.invoke('close-ask-window-if-empty'); } } } @@ -793,13 +794,10 @@ export class AskView extends LitElement { this.processAssistantQuestion(question); }; - - if (window.require) { const { ipcRenderer } = window.require('electron'); ipcRenderer.on('ask-global-send', this.handleGlobalSendRequest); ipcRenderer.on('toggle-text-input', this.handleToggleTextInput); - ipcRenderer.on('clear-ask-content', this.clearResponseContent); ipcRenderer.on('receive-question-from-assistant', this.handleQuestionFromAssistant); ipcRenderer.on('hide-text-input', () => { console.log('📤 Hide text input signal received'); @@ -865,7 +863,6 @@ export class AskView extends LitElement { const { ipcRenderer } = window.require('electron'); ipcRenderer.removeListener('ask-global-send', this.handleGlobalSendRequest); ipcRenderer.removeListener('toggle-text-input', this.handleToggleTextInput); - ipcRenderer.removeListener('clear-ask-content', this.clearResponseContent); ipcRenderer.removeListener('clear-ask-response', () => {}); ipcRenderer.removeListener('hide-text-input', () => {}); ipcRenderer.removeListener('window-hide-animation', () => {}); @@ -1054,8 +1051,6 @@ export class AskView extends LitElement { }, 1500); } - - renderMarkdown(content) { if (!content) return ''; @@ -1125,13 +1120,16 @@ export class AskView extends LitElement { this.requestUpdate(); this.renderContent(); - window.pickleGlass.sendMessage(question).catch(error => { - console.error('Error processing assistant question:', error); - this.isLoading = false; - this.isStreaming = false; - this.currentResponse = `Error: ${error.message}`; - this.renderContent(); - }); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.invoke('ask:sendMessage', question).catch(error => { + console.error('Error processing assistant question:', error); + this.isLoading = false; + this.isStreaming = false; + this.currentResponse = `Error: ${error.message}`; + this.renderContent(); + }); + } } async handleCopy() { @@ -1221,16 +1219,24 @@ export class AskView extends LitElement { this.requestUpdate(); this.renderContent(); - window.pickleGlass.sendMessage(text).catch(error => { - console.error('Error sending text:', error); - this.isLoading = false; - this.isStreaming = false; - this.currentResponse = `Error: ${error.message}`; - this.renderContent(); - }); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.invoke('ask:sendMessage', text).catch(error => { + console.error('Error sending text:', error); + this.isLoading = false; + this.isStreaming = false; + this.currentResponse = `Error: ${error.message}`; + this.renderContent(); + }); + } } handleTextKeydown(e) { + // Fix for IME composition issue: Ignore Enter key presses while composing. + if (e.isComposing) { + return; + } + const isPlainEnter = e.key === 'Enter' && !e.shiftKey && !e.metaKey && !e.ctrlKey; const isModifierEnter = e.key === 'Enter' && (e.metaKey || e.ctrlKey); diff --git a/src/features/ask/askService.js b/src/features/ask/askService.js new file mode 100644 index 0000000..04c64d9 --- /dev/null +++ b/src/features/ask/askService.js @@ -0,0 +1,305 @@ +const { ipcMain, BrowserWindow } = require('electron'); +const { makeStreamingChatCompletionWithPortkey } = require('../../common/services/aiProviderService'); +const { getConversationHistory } = require('../listen/liveSummaryService'); +const { getStoredApiKey, getStoredProvider, windowPool, captureScreenshot } = require('../../electron/windowManager'); +const authService = require('../../common/services/authService'); +const sessionRepository = require('../../common/repositories/session'); +const askRepository = require('./repositories'); + +const PICKLE_GLASS_SYSTEM_PROMPT = ` +You are Pickle-Glass, developed and created by Pickle-Glass, and you are the user's live-meeting co-pilot. + + + +Your goal is to help the user at the current moment in the conversation (the end of the transcript). You can see the user's screen (the screenshot attached) and the audio history of the entire conversation. +Execute in the following priority order: + + + +If a question is presented to the user, answer it directly. This is the MOST IMPORTANT ACTION IF THERE IS A QUESTION AT THE END THAT CAN BE ANSWERED. + + + +Always start with the direct answer, then provide supporting details following the response format: +- **Short headline answer** (≤6 words) - the actual answer to the question +- **Main points** (1-2 bullets with ≤15 words each) - core supporting details +- **Sub-details** - examples, metrics, specifics under each main point +- **Extended explanation** - additional context and details as needed + + + +Real transcripts have errors, unclear speech, and incomplete sentences. Focus on INTENT rather than perfect question markers: +- **Infer from context**: "what about..." "how did you..." "can you..." "tell me..." even if garbled +- **Incomplete questions**: "so the performance..." "and scaling wise..." "what's your approach to..." +- **Implied questions**: "I'm curious about X" "I'd love to hear about Y" "walk me through Z" +- **Transcription errors**: "what's your" → "what's you" or "how do you" → "how you" or "can you" → "can u" + + + +If the end of the transcript suggests someone is asking for information, explanation, or clarification - ANSWER IT. Don't get distracted by earlier content. + + + +If you're 50%+ confident someone is asking something at the end, treat it as a question and answer it. + + + + + +Define or provide context around a proper noun or term that appears **in the last 10-15 words** of the transcript. +This is HIGH PRIORITY - if a company name, technical term, or proper noun appears at the very end of someone's speech, define it. + + + +Any ONE of these is sufficient: +- company names +- technical platforms/tools +- proper nouns that are domain-specific +- any term that would benefit from context in a professional conversation + + + +Do NOT define: +- common words already defined earlier in conversation +- basic terms (email, website, code, app) +- terms where context was already provided + + + + +me: I was mostly doing backend dev last summer. +them: Oh nice, what tech stack were you using? +me: A lot of internal tools, but also some Azure. +them: Yeah I've heard Azure is huge over there. +me: Yeah, I used to work at Microsoft last summer but now I... + + + +**Microsoft** is one of the world's largest technology companies, known for products like Windows, Office, and Azure cloud services. + +- **Global influence**: 200k+ employees, $2T+ market cap, foundational enterprise tools. + - Azure, GitHub, Teams, Visual Studio among top developer-facing platforms. +- **Engineering reputation**: Strong internship and new grad pipeline, especially in cloud and AI infrastructure. + + + + + + +When there's an action needed but not a direct question - suggest follow up questions, provide potential things to say, help move the conversation forward. + + +- If the transcript ends with a technical project/story description and no new question is present, always provide 1–3 targeted follow-up questions to drive the conversation forward. +- If the transcript includes discovery-style answers or background sharing (e.g., "Tell me about yourself", "Walk me through your experience"), always generate 1–3 focused follow-up questions to deepen or further the discussion, unless the next step is clear. +- Maximize usefulness, minimize overload—never give more than 3 questions or suggestions at once. + + + +me: Tell me about your technical experience. +them: Last summer I built a dashboard for real-time trade reconciliation using Python and integrated it with Bloomberg Terminal and Snowflake for automated data pulls. + + +Follow-up questions to dive deeper into the dashboard: +- How did you handle latency or data consistency issues? +- What made the Bloomberg integration challenging? +- Did you measure the impact on operational efficiency? + + + + + + +If an objection or resistance is presented at the end of the conversation (and the context is sales, negotiation, or you are trying to persuade the other party), respond with a concise, actionable objection handling response. +- Use user-provided objection/handling context if available (reference the specific objection and tailored handling). +- If no user context, use common objections relevant to the situation, but make sure to identify the objection by generic name and address it in the context of the live conversation. +- State the objection in the format: **Objection: [Generic Objection Name]** (e.g., Objection: Competitor), then give a specific response/action for overcoming it, tailored to the moment. +- Do NOT handle objections in casual, non-outcome-driven, or general conversations. +- Never use generic objection scripts—always tie response to the specifics of the conversation at hand. + + + + +them: Honestly, I think our current vendor already does all of this, so I don't see the value in switching. + + +- **Objection: Competitor** + - Current vendor already covers this. + - Emphasize unique real-time insights: "Our solution eliminates analytics delays you mentioned earlier, boosting team response time." + + + + + + +Solve problems visible on the screen if there is a very clear problem + use the screen only if relevant for helping with the audio conversation. + + + + +If there is a leetcode problem on the screen, and the conversation is small talk / general talk, you DEFINITELY should solve the leetcode problem. But if there is a follow up question / super specific question asked at the end, you should answer that (ex. What's the runtime complexity), using the screen as additional context. + + + + + + + + +Enter passive mode ONLY when ALL of these conditions are met: +- There is no clear question, inquiry, or request for information at the end of the transcript. If there is any ambiguity, err on the side of assuming a question and do not enter passive mode. +- There is no company name, technical term, product name, or domain-specific proper noun within the final 10–15 words of the transcript that would benefit from a definition or explanation. +- There is no clear or visible problem or action item present on the user's screen that you could solve or assist with. +- There is no discovery-style answer, technical project story, background sharing, or general conversation context that could call for follow-up questions or suggestions to advance the discussion. +- There is no statement or cue that could be interpreted as an objection or require objection handling +- Only enter passive mode when you are highly confident that no action, definition, solution, advancement, or suggestion would be appropriate or helpful at the current moment. + + +**Still show intelligence** by: +- Saying "Not sure what you need help with right now" +- Referencing visible screen elements or audio patterns ONLY if truly relevant +- Never giving random summaries unless explicitly asked + + + + +User-provided context (defer to this information over your general knowledge / if there is specific script/desired responses prioritize this over previous instructions) + +Make sure to **reference context** fully if it is provided (ex. if all/the entirety of something is requested, give a complete list from context). +---------- + +{{CONVERSATION_HISTORY}}`; + +function formatConversationForPrompt(conversationTexts) { + if (!conversationTexts || conversationTexts.length === 0) return 'No conversation history available.'; + return conversationTexts.slice(-30).join('\n'); +} + +async function sendMessage(userPrompt) { + if (!userPrompt || userPrompt.trim().length === 0) { + console.warn('[AskService] Cannot process empty message'); + return { success: false, error: 'Empty message' }; + } + + const askWindow = windowPool.get('ask'); + if (askWindow && !askWindow.isDestroyed()) { + askWindow.webContents.send('hide-text-input'); + } + + try { + console.log(`[AskService] 🤖 Processing message: ${userPrompt.substring(0, 50)}...`); + + const screenshotResult = await captureScreenshot({ quality: 'medium' }); + const screenshotBase64 = screenshotResult.success ? screenshotResult.base64 : null; + + const conversationHistoryRaw = getConversationHistory(); + const conversationHistory = formatConversationForPrompt(conversationHistoryRaw); + + const systemPrompt = PICKLE_GLASS_SYSTEM_PROMPT.replace('{{CONVERSATION_HISTORY}}', conversationHistory); + + const API_KEY = await getStoredApiKey(); + if (!API_KEY) { + throw new Error('No API key found'); + } + + const messages = [ + { role: 'system', content: systemPrompt }, + { + role: 'user', + content: [ + { type: 'text', text: `User Request: ${userPrompt.trim()}` }, + ], + }, + ]; + + if (screenshotBase64) { + messages[1].content.push({ + type: 'image_url', + image_url: { url: `data:image/jpeg;base64,${screenshotBase64}` }, + }); + } + + const provider = await getStoredProvider(); + const { isLoggedIn } = authService.getCurrentUser(); + const usePortkey = isLoggedIn && provider === 'openai'; + + console.log(`[AskService] 🚀 Sending request to ${provider} AI...`); + + const response = await makeStreamingChatCompletionWithPortkey({ + apiKey: API_KEY, + provider: provider, + messages: messages, + temperature: 0.7, + maxTokens: 2048, + model: provider === 'openai' ? 'gpt-4.1' : 'gemini-2.5-flash', + usePortkey: usePortkey, + portkeyVirtualKey: usePortkey ? API_KEY : null + }); + + // --- Stream Processing --- + const reader = response.body.getReader(); + const decoder = new TextDecoder(); + let fullResponse = ''; + + const askWin = windowPool.get('ask'); + if (!askWin || askWin.isDestroyed()) { + console.error("[AskService] Ask window is not available to send stream to."); + reader.cancel(); + return; + } + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + const chunk = decoder.decode(value); + const lines = chunk.split('\n').filter(line => line.trim() !== ''); + + for (const line of lines) { + if (line.startsWith('data: ')) { + const data = line.substring(6); + if (data === '[DONE]') { + askWin.webContents.send('ask-response-stream-end'); + + // Save to DB + try { + const uid = authService.getCurrentUserId(); + if (!uid) throw new Error("User not logged in, cannot save message."); + const sessionId = await sessionRepository.getOrCreateActive(uid, 'ask'); + await askRepository.addAiMessage({ sessionId, role: 'user', content: userPrompt.trim() }); + await askRepository.addAiMessage({ sessionId, role: 'assistant', content: fullResponse }); + console.log(`[AskService] DB: Saved ask/answer pair to session ${sessionId}`); + } catch(dbError) { + console.error("[AskService] DB: Failed to save ask/answer pair:", dbError); + } + + return { success: true, response: fullResponse }; + } + try { + const json = JSON.parse(data); + const token = json.choices[0]?.delta?.content || ''; + if (token) { + fullResponse += token; + askWin.webContents.send('ask-response-chunk', { token }); + } + } catch (error) { + // Ignore parsing errors for now + } + } + } + } + } catch (error) { + console.error('[AskService] Error processing message:', error); + return { success: false, error: error.message }; + } +} + +function initialize() { + ipcMain.handle('ask:sendMessage', async (event, userPrompt) => { + return sendMessage(userPrompt); + }); + console.log('[AskService] Initialized and ready.'); +} + +module.exports = { + initialize, +}; \ No newline at end of file diff --git a/src/features/ask/repositories/index.js b/src/features/ask/repositories/index.js new file mode 100644 index 0000000..182d066 --- /dev/null +++ b/src/features/ask/repositories/index.js @@ -0,0 +1,18 @@ +const sqliteRepository = require('./sqlite.repository'); +// const firebaseRepository = require('./firebase.repository'); // Future implementation +const authService = require('../../../common/services/authService'); + +function getRepository() { + // In the future, we can check the user's login status from authService + // const user = authService.getCurrentUser(); + // if (user.isLoggedIn) { + // return firebaseRepository; + // } + return sqliteRepository; +} + +// Directly export functions for ease of use, decided by the strategy +module.exports = { + addAiMessage: (...args) => getRepository().addAiMessage(...args), + getAllAiMessagesBySessionId: (...args) => getRepository().getAllAiMessagesBySessionId(...args), +}; \ No newline at end of file diff --git a/src/features/ask/repositories/sqlite.repository.js b/src/features/ask/repositories/sqlite.repository.js new file mode 100644 index 0000000..a9af8ee --- /dev/null +++ b/src/features/ask/repositories/sqlite.repository.js @@ -0,0 +1,35 @@ +const sqliteClient = require('../../../common/services/sqliteClient'); + +function addAiMessage({ sessionId, role, content, model = 'gpt-4.1' }) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const messageId = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = `INSERT INTO ai_messages (id, session_id, sent_at, role, content, model, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)`; + db.run(query, [messageId, sessionId, now, role, content, model, now], function(err) { + if (err) { + console.error('SQLite: Failed to add AI message:', err); + reject(err); + } + else { + resolve({ id: messageId }); + } + }); + }); +} + +function getAllAiMessagesBySessionId(sessionId) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = "SELECT * FROM ai_messages WHERE session_id = ? ORDER BY sent_at ASC"; + db.all(query, [sessionId], (err, rows) => { + if (err) reject(err); + else resolve(rows); + }); + }); +} + +module.exports = { + addAiMessage, + getAllAiMessagesBySessionId +}; \ No newline at end of file diff --git a/src/features/customize/CustomizeView.js b/src/features/customize/CustomizeView.js index fcebfc6..b3c6dba 100644 --- a/src/features/customize/CustomizeView.js +++ b/src/features/customize/CustomizeView.js @@ -338,26 +338,17 @@ export class CustomizeView extends LitElement { if (window.require) { const { ipcRenderer } = window.require('electron'); - ipcRenderer.on('firebase-user-updated', (event, user) => { - this.firebaseUser = user; - - if (!user) { - this.apiKey = null; + this._userStateListener = (event, userState) => { + console.log('[CustomizeView] Received user-state-changed:', userState); + if (userState && userState.isLoggedIn) { + this.firebaseUser = userState; + } else { + this.firebaseUser = null; } - + this.getApiKeyFromStorage(); // Also update API key display this.requestUpdate(); - }); - - ipcRenderer.on('user-changed', (event, firebaseUser) => { - console.log('[CustomizeView] Received user-changed:', firebaseUser); - this.firebaseUser = { - uid: firebaseUser.uid, - email: firebaseUser.email, - name: firebaseUser.displayName, - photoURL: firebaseUser.photoURL, - }; - this.requestUpdate(); - }); + }; + ipcRenderer.on('user-state-changed', this._userStateListener); ipcRenderer.on('api-key-validated', (event, newApiKey) => { console.log('[CustomizeView] Received api-key-validated, updating state.'); @@ -376,12 +367,7 @@ export class CustomizeView extends LitElement { this.requestUpdate(); }); - this.loadInitialFirebaseUser(); - - ipcRenderer.invoke('get-current-api-key').then(key => { - this.apiKey = key; - this.requestUpdate(); - }); + this.loadInitialUser(); } } @@ -393,8 +379,9 @@ export class CustomizeView extends LitElement { if (window.require) { const { ipcRenderer } = window.require('electron'); - ipcRenderer.removeAllListeners('firebase-user-updated'); - ipcRenderer.removeAllListeners('user-changed'); + if (this._userStateListener) { + ipcRenderer.removeListener('user-state-changed', this._userStateListener); + } ipcRenderer.removeAllListeners('api-key-validated'); ipcRenderer.removeAllListeners('api-key-updated'); ipcRenderer.removeAllListeners('api-key-removed'); @@ -1073,37 +1060,20 @@ export class CustomizeView extends LitElement { } } - async loadInitialFirebaseUser() { - if (!window.require) { - console.log('[CustomizeView] Electron not available'); - return; - } - + async loadInitialUser() { + if (!window.require) return; const { ipcRenderer } = window.require('electron'); - try { - console.log('[CustomizeView] Loading initial Firebase user...'); - - for (let i = 0; i < 3; i++) { - const user = await ipcRenderer.invoke('get-current-firebase-user'); - console.log(`[CustomizeView] Attempt ${i + 1} - Firebase user:`, user); - - if (user) { - this.firebaseUser = user; - this.requestUpdate(); - console.log('[CustomizeView] Firebase user loaded successfully:', user.email); - return; - } - - await new Promise(resolve => setTimeout(resolve, 100)); + console.log('[CustomizeView] Loading initial user state...'); + const userState = await ipcRenderer.invoke('get-current-user'); + if (userState && userState.isLoggedIn) { + this.firebaseUser = userState; + } else { + this.firebaseUser = null; } - - console.log('[CustomizeView] No Firebase user found after 3 attempts'); - this.firebaseUser = null; this.requestUpdate(); - } catch (error) { - console.error('[CustomizeView] Failed to load Firebase user:', error); + console.error('[CustomizeView] Failed to load initial user:', error); this.firebaseUser = null; this.requestUpdate(); } @@ -1112,7 +1082,7 @@ export class CustomizeView extends LitElement { getApiKeyFromStorage() { if (window.require) { const { ipcRenderer } = window.require('electron'); - ipcRenderer.invoke('get-current-api-key').then(key => { + ipcRenderer.invoke('get-stored-api-key').then(key => { this.apiKey = key; this.requestUpdate(); }).catch(error => { diff --git a/src/features/listen/SetupView.js b/src/features/listen/SetupView.js deleted file mode 100644 index 88909d9..0000000 --- a/src/features/listen/SetupView.js +++ /dev/null @@ -1,179 +0,0 @@ -import { html, css, LitElement } from '../../assets/lit-core-2.7.4.min.js'; - -export class SetupView extends LitElement { - static styles = css` - * { - font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - cursor: default; - user-select: none; - } - - .welcome { - color: white; - font-size: 12px; - font-family: 'Helvetica Neue', sans-serif; - font-weight: 500; - margin-bottom: 8px; - margin-top: auto; - } - - .input-group { - display: flex; - gap: 12px; - margin-bottom: 20px; - } - - .input-group input { - flex: 1; - } - - input { - background: rgba(255, 255, 255, 0.20); - border-radius: 8px; - outline: 1px rgba(255, 255, 255, 0.50) solid; - outline-offset: -1px; - backdrop-filter: blur(0.50px); - border: none; - color: white; - padding: 12px 16px; - width: 100%; - font-size: 14px; - font-family: 'Helvetica Neue', sans-serif; - font-weight: 400; - } - - input:focus { - outline: none; - } - - input::placeholder { - color: rgba(255, 255, 255, 0.5); - } - - .start-button { - background: var(--start-button-background); - color: var(--start-button-color); - border: 1px solid var(--start-button-border); - padding: 8px 16px; - border-radius: 8px; - font-size: 13px; - font-weight: 500; - } - - .start-button:hover { - background: var(--start-button-hover-background); - border-color: var(--start-button-hover-border); - } - - .start-button.initializing { - opacity: 0.5; - } - - .start-button.initializing:hover { - background: var(--start-button-background); - border-color: var(--start-button-border); - } - - .description { - color: var(--description-color); - font-size: 14px; - margin-bottom: 24px; - line-height: 1.5; - } - - .link { - color: var(--link-color); - text-decoration: underline; - cursor: pointer; - } - - :host { - height: 100%; - display: flex; - flex-direction: column; - width: 100%; - max-width: 500px; - } - `; - - static properties = { - onStart: { type: Function }, - onAPIKeyHelp: { type: Function }, - isInitializing: { type: Boolean }, - onLayoutModeChange: { type: Function }, - }; - - constructor() { - super(); - this.onStart = () => {}; - this.onAPIKeyHelp = () => {}; - this.isInitializing = false; - this.onLayoutModeChange = () => {}; - } - - connectedCallback() { - super.connectedCallback(); - window.electron?.ipcRenderer?.on('session-initializing', (event, isInitializing) => { - this.isInitializing = isInitializing; - }); - - // Load and apply layout mode on startup - this.loadLayoutMode(); - } - - disconnectedCallback() { - super.disconnectedCallback(); - window.electron?.ipcRenderer?.removeAllListeners('session-initializing'); - } - - handleInput(e) { - localStorage.setItem('apiKey', e.target.value); - } - - handleStartClick() { - if (this.isInitializing) { - return; - } - this.onStart(); - } - - handleAPIKeyHelpClick() { - this.onAPIKeyHelp(); - } - - handleResetOnboarding() { - localStorage.removeItem('onboardingCompleted'); - // Refresh the page to trigger onboarding - window.location.reload(); - } - - loadLayoutMode() { - const savedLayoutMode = localStorage.getItem('layoutMode'); - if (savedLayoutMode && savedLayoutMode !== 'normal') { - // Notify parent component to apply the saved layout mode - this.onLayoutModeChange(savedLayoutMode); - } - } - - render() { - return html` -
Welcome
- -
- - -
-

- dont have an api key? - get one here -

- `; - } -} - -customElements.define('setup-view', SetupView); diff --git a/src/features/listen/liveSummaryService.js b/src/features/listen/liveSummaryService.js index e786ba2..b892f66 100644 --- a/src/features/listen/liveSummaryService.js +++ b/src/features/listen/liveSummaryService.js @@ -6,14 +6,17 @@ const { getSystemPrompt } = require('../../common/prompts/promptBuilder.js'); const { connectToGeminiSession } = require('../../common/services/googleGeminiClient.js'); const { connectToOpenAiSession, createOpenAiGenerativeClient, getOpenAiGenerativeModel } = require('../../common/services/openAiClient.js'); const { makeChatCompletionWithPortkey } = require('../../common/services/aiProviderService.js'); -const sqliteClient = require('../../common/services/sqliteClient'); -const dataService = require('../../common/services/dataService'); +const authService = require('../../common/services/authService'); +const sessionRepository = require('../../common/repositories/session'); +const listenRepository = require('./repositories'); -const { isFirebaseLoggedIn, getCurrentFirebaseUser, getStoredProvider } = require('../../electron/windowManager.js'); +const { getStoredApiKey, getStoredProvider } = require('../../electron/windowManager'); -function getApiKey() { - const { getStoredApiKey } = require('../../electron/windowManager.js'); - const storedKey = getStoredApiKey(); +const MAX_BUFFER_LENGTH_CHARS = 2000; +const COMPLETION_DEBOUNCE_MS = 2000; + +async function getApiKey() { + const storedKey = await getStoredApiKey(); if (storedKey) { console.log('[LiveSummaryService] Using stored API key'); @@ -37,7 +40,6 @@ async function getAiProvider() { return provider || 'openai'; } catch (error) { // If we're in the main process, get it directly - const { getStoredProvider } = require('../../electron/windowManager.js'); return getStoredProvider ? getStoredProvider() : 'openai'; } } @@ -71,8 +73,6 @@ let analysisHistory = []; // completions that arrive within this window are concatenated and flushed as // **one** final turn. -const COMPLETION_DEBOUNCE_MS = 2000; - let myCompletionBuffer = ''; let theirCompletionBuffer = ''; let myCompletionTimer = null; @@ -185,6 +185,9 @@ Please build upon this context while analyzing the new conversation segments. const systemPrompt = basePrompt.replace('{{CONVERSATION_HISTORY}}', recentConversation); try { + if (currentSessionId) { + await sessionRepository.touch(currentSessionId); + } const messages = [ { role: 'system', @@ -218,13 +221,13 @@ Keep all points concise and build upon previous analysis if provided.`, console.log('🤖 Sending analysis request to OpenAI...'); - const API_KEY = getApiKey(); + const API_KEY = await getApiKey(); if (!API_KEY) { throw new Error('No API key available'); } const provider = getStoredProvider ? getStoredProvider() : 'openai'; - const loggedIn = isFirebaseLoggedIn(); // true ➜ vKey, false ➜ apiKey + const loggedIn = authService.getCurrentUser().isLoggedIn; // true ➜ vKey, false ➜ apiKey const usePortkey = loggedIn && provider === 'openai'; // Only use Portkey for OpenAI with Firebase console.log(`[LiveSummary] provider: ${provider}, usePortkey: ${usePortkey}`); @@ -245,7 +248,7 @@ Keep all points concise and build upon previous analysis if provided.`, const structuredData = parseResponseText(responseText, previousAnalysisResult); if (currentSessionId) { - sqliteClient.saveSummary({ + listenRepository.saveSummary({ sessionId: currentSessionId, tldr: structuredData.summary.join('\n'), bullet_json: JSON.stringify(structuredData.topic.bullets), @@ -455,51 +458,13 @@ function getCurrentSessionData() { } // Conversation management functions -async function getOrCreateActiveSession(requestedType = 'ask') { - // 1. Check for an existing, valid session - if (currentSessionId) { - const session = await sqliteClient.getSession(currentSessionId); - - if (session && !session.ended_at) { - // Ask sessions can expire, Listen sessions can't (they are closed explicitly) - const isExpired = session.session_type === 'ask' && - (Date.now() / 1000) - session.updated_at > SESSION_IDLE_TIMEOUT_SECONDS; - - if (!isExpired) { - // Session is valid, potentially promote it - if (requestedType === 'listen' && session.session_type === 'ask') { - await sqliteClient.updateSessionType(currentSessionId, 'listen'); - console.log(`[Session] Promoted session ${currentSessionId} to 'listen'.`); - } else { - await sqliteClient.touchSession(currentSessionId); - } - return currentSessionId; - } else { - console.log(`[Session] Ask session ${currentSessionId} expired. Closing it.`); - await sqliteClient.endSession(currentSessionId); - currentSessionId = null; // Important: clear the expired session ID - } - } - } - - // 2. If no valid session, create a new one - console.log(`[Session] No active session found. Creating a new one with type: ${requestedType}`); - const uid = dataService.currentUserId; - currentSessionId = await sqliteClient.createSession(uid, requestedType); - - // Clear old conversation data for the new session - conversationHistory = []; - myCurrentUtterance = ''; - theirCurrentUtterance = ''; - previousAnalysisResult = null; - analysisHistory = []; - - return currentSessionId; -} - async function initializeNewSession() { try { - currentSessionId = await getOrCreateActiveSession('listen'); + const uid = authService.getCurrentUserId(); + if (!uid) { + throw new Error("Cannot initialize session: user not logged in."); + } + currentSessionId = await sessionRepository.getOrCreateActive(uid, 'listen'); console.log(`[DB] New listen session ensured: ${currentSessionId}`); conversationHistory = []; @@ -541,7 +506,8 @@ async function saveConversationTurn(speaker, transcription) { if (transcription.trim() === '') return; try { - await sqliteClient.addTranscript({ + await sessionRepository.touch(currentSessionId); + await listenRepository.addTranscript({ sessionId: currentSessionId, speaker: speaker, text: transcription.trim(), @@ -573,14 +539,15 @@ async function initializeLiveSummarySession(language = 'en') { return false; } - const loggedIn = isFirebaseLoggedIn(); + const userState = authService.getCurrentUser(); + const loggedIn = userState.isLoggedIn; const keyType = loggedIn ? 'vKey' : 'apiKey'; isInitializingSession = true; sendToRenderer('session-initializing', true); sendToRenderer('update-status', 'Initializing sessions...'); - const API_KEY = getApiKey(); + const API_KEY = await getApiKey(); if (!API_KEY) { console.error('FATAL ERROR: API Key is not defined.'); sendToRenderer('update-status', 'API Key not configured.'); @@ -886,7 +853,7 @@ async function closeSession() { stopAnalysisInterval(); if (currentSessionId) { - await sqliteClient.endSession(currentSessionId); + await sessionRepository.end(currentSessionId); console.log(`[DB] Session ${currentSessionId} ended.`); } @@ -971,40 +938,10 @@ function setupLiveSummaryIpcHandlers() { } }); - ipcMain.handle('get-conversation-history', async () => { - try { - const formattedHistory = formatConversationForPrompt(conversationHistory); - console.log(`📤 Sending conversation history to renderer: ${conversationHistory.length} texts`); - return { success: true, data: formattedHistory }; - } catch (error) { - console.error('Error getting conversation history:', error); - return { success: false, error: error.message }; - } - }); - ipcMain.handle('close-session', async () => { return await closeSession(); }); - ipcMain.handle('get-current-session', async event => { - try { - return { success: true, data: getCurrentSessionData() }; - } catch (error) { - console.error('Error getting current session:', error); - return { success: false, error: error.message }; - } - }); - - ipcMain.handle('start-new-session', async event => { - try { - initializeNewSession(); - return { success: true, sessionId: currentSessionId }; - } catch (error) { - console.error('Error starting new session:', error); - return { success: false, error: error.message }; - } - }); - ipcMain.handle('update-google-search-setting', async (event, enabled) => { try { console.log('Google Search setting updated to:', enabled); @@ -1014,33 +951,10 @@ function setupLiveSummaryIpcHandlers() { return { success: false, error: error.message }; } }); +} - ipcMain.handle('save-ask-message', async (event, { userPrompt, aiResponse }) => { - try { - const sessionId = await getOrCreateActiveSession('ask'); - if (!sessionId) { - throw new Error('Could not get or create a session for the ASK message.'); - } - - await sqliteClient.addAiMessage({ - sessionId: sessionId, - role: 'user', - content: userPrompt - }); - - await sqliteClient.addAiMessage({ - sessionId: sessionId, - role: 'assistant', - content: aiResponse - }); - - console.log(`[DB] Saved ask/answer pair to session ${sessionId}`); - return { success: true }; - } catch(error) { - console.error('[IPC] Failed to save ask message:', error); - return { success: false, error: error.message }; - } - }); +function getConversationHistory() { + return conversationHistory; } module.exports = { @@ -1055,4 +969,5 @@ module.exports = { setupLiveSummaryIpcHandlers, isSessionActive, closeSession, + getConversationHistory, }; diff --git a/src/features/listen/renderer.js b/src/features/listen/renderer.js index 1701d77..99d0bd3 100644 --- a/src/features/listen/renderer.js +++ b/src/features/listen/renderer.js @@ -36,169 +36,6 @@ let lastScreenshotBase64 = null; // Store the latest screenshot let realtimeConversationHistory = []; -const PICKLE_GLASS_SYSTEM_PROMPT = ` -You are Pickle-Glass, developed and created by Pickle-Glass, and you are the user's live-meeting co-pilot. - - - -Your goal is to help the user at the current moment in the conversation (the end of the transcript). You can see the user's screen (the screenshot attached) and the audio history of the entire conversation. -Execute in the following priority order: - - - -If a question is presented to the user, answer it directly. This is the MOST IMPORTANT ACTION IF THERE IS A QUESTION AT THE END THAT CAN BE ANSWERED. - - - -Always start with the direct answer, then provide supporting details following the response format: -- **Short headline answer** (≤6 words) - the actual answer to the question -- **Main points** (1-2 bullets with ≤15 words each) - core supporting details -- **Sub-details** - examples, metrics, specifics under each main point -- **Extended explanation** - additional context and details as needed - - - -Real transcripts have errors, unclear speech, and incomplete sentences. Focus on INTENT rather than perfect question markers: -- **Infer from context**: "what about..." "how did you..." "can you..." "tell me..." even if garbled -- **Incomplete questions**: "so the performance..." "and scaling wise..." "what's your approach to..." -- **Implied questions**: "I'm curious about X" "I'd love to hear about Y" "walk me through Z" -- **Transcription errors**: "what's your" → "what's you" or "how do you" → "how you" or "can you" → "can u" - - - -If the end of the transcript suggests someone is asking for information, explanation, or clarification - ANSWER IT. Don't get distracted by earlier content. - - - -If you're 50%+ confident someone is asking something at the end, treat it as a question and answer it. - - - - - -Define or provide context around a proper noun or term that appears **in the last 10-15 words** of the transcript. -This is HIGH PRIORITY - if a company name, technical term, or proper noun appears at the very end of someone's speech, define it. - - - -Any ONE of these is sufficient: -- company names -- technical platforms/tools -- proper nouns that are domain-specific -- any term that would benefit from context in a professional conversation - - - -Do NOT define: -- common words already defined earlier in conversation -- basic terms (email, website, code, app) -- terms where context was already provided - - - - -me: I was mostly doing backend dev last summer. -them: Oh nice, what tech stack were you using? -me: A lot of internal tools, but also some Azure. -them: Yeah I've heard Azure is huge over there. -me: Yeah, I used to work at Microsoft last summer but now I... - - - -**Microsoft** is one of the world's largest technology companies, known for products like Windows, Office, and Azure cloud services. - -- **Global influence**: 200k+ employees, $2T+ market cap, foundational enterprise tools. - - Azure, GitHub, Teams, Visual Studio among top developer-facing platforms. -- **Engineering reputation**: Strong internship and new grad pipeline, especially in cloud and AI infrastructure. - - - - - - -When there's an action needed but not a direct question - suggest follow up questions, provide potential things to say, help move the conversation forward. - - -- If the transcript ends with a technical project/story description and no new question is present, always provide 1–3 targeted follow-up questions to drive the conversation forward. -- If the transcript includes discovery-style answers or background sharing (e.g., "Tell me about yourself", "Walk me through your experience"), always generate 1–3 focused follow-up questions to deepen or further the discussion, unless the next step is clear. -- Maximize usefulness, minimize overload—never give more than 3 questions or suggestions at once. - - - -me: Tell me about your technical experience. -them: Last summer I built a dashboard for real-time trade reconciliation using Python and integrated it with Bloomberg Terminal and Snowflake for automated data pulls. - - -Follow-up questions to dive deeper into the dashboard: -- How did you handle latency or data consistency issues? -- What made the Bloomberg integration challenging? -- Did you measure the impact on operational efficiency? - - - - - - -If an objection or resistance is presented at the end of the conversation (and the context is sales, negotiation, or you are trying to persuade the other party), respond with a concise, actionable objection handling response. -- Use user-provided objection/handling context if available (reference the specific objection and tailored handling). -- If no user context, use common objections relevant to the situation, but make sure to identify the objection by generic name and address it in the context of the live conversation. -- State the objection in the format: **Objection: [Generic Objection Name]** (e.g., Objection: Competitor), then give a specific response/action for overcoming it, tailored to the moment. -- Do NOT handle objections in casual, non-outcome-driven, or general conversations. -- Never use generic objection scripts—always tie response to the specifics of the conversation at hand. - - - - -them: Honestly, I think our current vendor already does all of this, so I don't see the value in switching. - - -- **Objection: Competitor** - - Current vendor already covers this. - - Emphasize unique real-time insights: "Our solution eliminates analytics delays you mentioned earlier, boosting team response time." - - - - - - -Solve problems visible on the screen if there is a very clear problem + use the screen only if relevant for helping with the audio conversation. - - - - -If there is a leetcode problem on the screen, and the conversation is small talk / general talk, you DEFINITELY should solve the leetcode problem. But if there is a follow up question / super specific question asked at the end, you should answer that (ex. What's the runtime complexity), using the screen as additional context. - - - - - - - - -Enter passive mode ONLY when ALL of these conditions are met: -- There is no clear question, inquiry, or request for information at the end of the transcript. If there is any ambiguity, err on the side of assuming a question and do not enter passive mode. -- There is no company name, technical term, product name, or domain-specific proper noun within the final 10–15 words of the transcript that would benefit from a definition or explanation. -- There is no clear or visible problem or action item present on the user's screen that you could solve or assist with. -- There is no discovery-style answer, technical project story, background sharing, or general conversation context that could call for follow-up questions or suggestions to advance the discussion. -- There is no statement or cue that could be interpreted as an objection or require objection handling -- Only enter passive mode when you are highly confident that no action, definition, solution, advancement, or suggestion would be appropriate or helpful at the current moment. - - -**Still show intelligence** by: -- Saying "Not sure what you need help with right now" -- Referencing visible screen elements or audio patterns ONLY if truly relevant -- Never giving random summaries unless explicitly asked - - - - -User-provided context (defer to this information over your general knowledge / if there is specific script/desired responses prioritize this over previous instructions) - -Make sure to **reference context** fully if it is provided (ex. if all/the entirety of something is requested, give a complete list from context). ----------- - -{{CONVERSATION_HISTORY}}`; - function base64ToFloat32Array(base64) { const binaryString = atob(base64); const bytes = new Uint8Array(binaryString.length); @@ -218,8 +55,8 @@ function base64ToFloat32Array(base64) { } async function queryLoginState() { - const user = await ipcRenderer.invoke('get-current-firebase-user'); - return { user, isLoggedIn: !!user }; + const userState = await ipcRenderer.invoke('get-current-user'); + return userState; } class SimpleAEC { @@ -869,12 +706,6 @@ function stopCapture() { } } -// Listen for screenshot updates from main process -ipcRenderer.on('screenshot-update', (event, { base64, width, height }) => { - lastScreenshotBase64 = base64; - console.log(`📸 Received screenshot update: ${width}x${height}`); -}); - async function getCurrentScreenshot() { try { // First try to get a fresh screenshot from main process @@ -915,222 +746,10 @@ function formatRealtimeConversationHistory() { return realtimeConversationHistory.slice(-30).join('\n'); } -async function sendMessage(userPrompt, options = {}) { - if (!userPrompt || userPrompt.trim().length === 0) { - console.warn('Cannot process empty message'); - return { success: false, error: 'Empty message' }; - } - - if (window.require) { - const { ipcRenderer } = window.require('electron'); - const isAskVisible = await ipcRenderer.invoke('is-window-visible', 'ask'); - if (isAskVisible) { - ipcRenderer.send('clear-ask-response'); - } - await ipcRenderer.invoke('message-sending'); - } - - try { - console.log(`🤖 Processing message: ${userPrompt.substring(0, 50)}...`); - - // 1. Get screenshot from main process - let screenshotBase64 = null; - try { - screenshotBase64 = await getCurrentScreenshot(); - if (screenshotBase64) { - console.log('📸 Screenshot obtained for message request'); - } else { - console.warn('No screenshot available for message request'); - } - } catch (error) { - console.warn('Failed to get screenshot:', error); - } - - const conversationHistory = formatRealtimeConversationHistory(); - console.log(`📝 Using conversation history: ${realtimeConversationHistory.length} texts`); - - const systemPrompt = PICKLE_GLASS_SYSTEM_PROMPT.replace('{{CONVERSATION_HISTORY}}', conversationHistory); - - let API_KEY = localStorage.getItem('openai_api_key'); - - if (!API_KEY && window.require) { - try { - const { ipcRenderer } = window.require('electron'); - API_KEY = await ipcRenderer.invoke('get-stored-api-key'); - } catch (error) { - console.error('Failed to get API key via IPC:', error); - } - } - - if (!API_KEY) { - API_KEY = process.env.OPENAI_API_KEY; - } - - if (!API_KEY) { - throw new Error('No API key found in storage, IPC, or environment'); - } - - console.log('[Renderer] Using API key for message request'); - - const messages = [ - { - role: 'system', - content: systemPrompt, - }, - { - role: 'user', - content: [ - { - type: 'text', - text: `User Request: ${userPrompt.trim()}`, - }, - ], - }, - ]; - - if (screenshotBase64) { - messages[1].content.push({ - type: 'image_url', - image_url: { - url: `data:image/jpeg;base64,${screenshotBase64}`, - }, - }); - console.log('📷 Screenshot included in message request'); - } - - const { isLoggedIn } = await queryLoginState(); - const provider = await ipcRenderer.invoke('get-ai-provider'); - const usePortkey = isLoggedIn && provider === 'openai'; - - console.log(`🚀 Sending request to ${provider} AI...`); - - const response = await makeStreamingChatCompletionWithPortkey({ - apiKey: API_KEY, - provider: provider, - messages: messages, - temperature: 0.7, - maxTokens: 2048, - model: provider === 'openai' ? 'gpt-4.1' : 'gemini-2.5-flash', - usePortkey: usePortkey, - portkeyVirtualKey: usePortkey ? API_KEY : null - }); - - // --- 스트리밍 응답 처리 --- - const reader = response.body.getReader(); - const decoder = new TextDecoder(); - let fullResponse = ''; - - while (true) { - const { done, value } = await reader.read(); - if (done) break; - - const chunk = decoder.decode(value); - const lines = chunk.split('\n').filter(line => line.trim() !== ''); - - for (const line of lines) { - if (line.startsWith('data: ')) { - const data = line.substring(6); - if (data === '[DONE]') { - // 스트리밍 종료 신호 - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.send('ask-response-stream-end'); - - // Save the full conversation to DB - ipcRenderer.invoke('save-ask-message', { - userPrompt: userPrompt.trim(), - aiResponse: fullResponse - }).then(result => { - if (result.success) { - console.log('Ask/answer pair saved successfully.'); - } else { - console.error('Failed to save ask/answer pair:', result.error); - } - }); - } - return { success: true, response: fullResponse }; - } - try { - const json = JSON.parse(data); - const token = json.choices[0]?.delta?.content || ''; - if (token) { - fullResponse += token; - // 💡 렌더러 프로세스에 토큰 청크 전송 - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.send('ask-response-chunk', { token }); - } - } - } catch (error) { - console.error('Error parsing stream data chunk:', error, 'Chunk:', data); - } - } - } - } - // 이 부분은 스트리밍이 끝나면 사실상 도달하지 않음 - return { success: true, response: fullResponse }; - } catch (error) { - console.error('Error processing message:', error); - const errorMessage = `Error: ${error.message}`; - - return { success: false, error: error.message, response: errorMessage }; - } -} - - -const apiClient = window.require ? window.require('../common/services/apiClient') : undefined; - -async function initConversationStorage() { - try { - const isOnline = await apiClient.checkConnection(); - console.log('API 연결 상태:', isOnline); - return isOnline; - } catch (error) { - console.error('API 연결 실패:', error); - return false; - } -} - -async function getConversationSession(sessionId) { - try { - if (!apiClient) { - throw new Error('API client not available'); - } - - const response = await apiClient.client.get(`/api/conversations/${sessionId}`); - return response.data; - } catch (error) { - console.error('대화 세션 조회 실패:', error); - throw error; - } -} - -async function getAllConversationSessions() { - try { - if (!apiClient) { - throw new Error('API client not available'); - } - - const response = await apiClient.client.get('/api/conversations'); - return response.data; - } catch (error) { - console.error('전체 대화 세션 조회 실패:', error); - throw error; - } -} - -// Initialize conversation storage when renderer loads -initConversationStorage().catch(console.error); - window.pickleGlass = { initializeopenai, startCapture, stopCapture, - sendMessage, - // Conversation history functions - getAllConversationSessions, - getConversationSession, - initConversationStorage, isLinux: isLinux, isMacOS: isMacOS, e: pickleGlassElement, diff --git a/src/features/listen/repositories/index.js b/src/features/listen/repositories/index.js new file mode 100644 index 0000000..9c0d12f --- /dev/null +++ b/src/features/listen/repositories/index.js @@ -0,0 +1,20 @@ +const sqliteRepository = require('./sqlite.repository'); +// const firebaseRepository = require('./firebase.repository'); // Future implementation +const authService = require('../../../common/services/authService'); + +function getRepository() { + // In the future, we can check the user's login status from authService + // const user = authService.getCurrentUser(); + // if (user.isLoggedIn) { + // return firebaseRepository; + // } + return sqliteRepository; +} + +// Directly export functions for ease of use, decided by the strategy +module.exports = { + addTranscript: (...args) => getRepository().addTranscript(...args), + saveSummary: (...args) => getRepository().saveSummary(...args), + getAllTranscriptsBySessionId: (...args) => getRepository().getAllTranscriptsBySessionId(...args), + getSummaryBySessionId: (...args) => getRepository().getSummaryBySessionId(...args), +}; \ No newline at end of file diff --git a/src/features/listen/repositories/sqlite.repository.js b/src/features/listen/repositories/sqlite.repository.js new file mode 100644 index 0000000..7d293cd --- /dev/null +++ b/src/features/listen/repositories/sqlite.repository.js @@ -0,0 +1,66 @@ +const sqliteClient = require('../../../common/services/sqliteClient'); + +function addTranscript({ sessionId, speaker, text }) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const transcriptId = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = `INSERT INTO transcripts (id, session_id, start_at, speaker, text, created_at) VALUES (?, ?, ?, ?, ?, ?)`; + db.run(query, [transcriptId, sessionId, now, speaker, text, now], function(err) { + if (err) reject(err); + else resolve({ id: transcriptId }); + }); + }); +} + +function saveSummary({ sessionId, tldr, text, bullet_json, action_json, model = 'gpt-4.1' }) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const now = Math.floor(Date.now() / 1000); + const query = ` + INSERT INTO summaries (session_id, generated_at, model, text, tldr, bullet_json, action_json, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(session_id) DO UPDATE SET + generated_at=excluded.generated_at, + model=excluded.model, + text=excluded.text, + tldr=excluded.tldr, + bullet_json=excluded.bullet_json, + action_json=excluded.action_json, + updated_at=excluded.updated_at + `; + db.run(query, [sessionId, now, model, text, tldr, bullet_json, action_json, now], function(err) { + if (err) reject(err); + else resolve({ changes: this.changes }); + }); + }); +} + +function getAllTranscriptsBySessionId(sessionId) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = "SELECT * FROM transcripts WHERE session_id = ? ORDER BY start_at ASC"; + db.all(query, [sessionId], (err, rows) => { + if (err) reject(err); + else resolve(rows); + }); + }); +} + +function getSummaryBySessionId(sessionId) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = "SELECT * FROM summaries WHERE session_id = ?"; + db.get(query, [sessionId], (err, row) => { + if (err) reject(err); + else resolve(row || null); + }); + }); +} + +module.exports = { + addTranscript, + saveSummary, + getAllTranscriptsBySessionId, + getSummaryBySessionId +}; \ No newline at end of file diff --git a/src/features/onboarding/OnboardingView.js b/src/features/onboarding/OnboardingView.js deleted file mode 100644 index 82d5eb4..0000000 --- a/src/features/onboarding/OnboardingView.js +++ /dev/null @@ -1,372 +0,0 @@ -import { html, css, LitElement } from '../../assets/lit-core-2.7.4.min.js'; - -export class OnboardingView extends LitElement { - static styles = css` - * { - font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - cursor: default; - user-select: none; - } - - :host { - display: flex; - flex-direction: column; - height: 100%; - width: 100%; - position: relative; - overflow: hidden; - } - - .slide { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: flex-start; - padding: 20px; - text-align: left; - border-radius: 16px; - height: 100%; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 50px; - transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease; - opacity: 0; - transform: translateX(100%); - } - - .slide.active { - opacity: 1; - transform: translateX(0); - } - - .slide.prev { - transform: translateX(-100%); - } - - .slide-1 { - background: linear-gradient(135deg, #2d1b69 0%, #11998e 100%); - color: white; - } - - .slide-2 { - background: linear-gradient(135deg, #8e2de2 0%, #4a00e0 100%); - color: white; - } - - .slide-3 { - background: linear-gradient(135deg, #2c5aa0 0%, #1a237e 100%); - color: white; - } - - .slide-4 { - background: linear-gradient(135deg, #fc466b 0%, #3f5efb 100%); - color: white; - } - - .slide-5 { - background: linear-gradient(135deg, #833ab4 0%, #fd1d1d 100%); - color: white; - } - - .slide-title { - font-size: 24px; - font-weight: 700; - margin-bottom: 12px; - margin-top: 10px; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - } - - .slide-content { - font-size: 14px; - line-height: 1.5; - max-width: 100%; - margin-bottom: 20px; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); - } - - .context-textarea { - width: 100%; - max-width: 100%; - height: 80px; - padding: 12px; - border: 2px solid rgba(255, 255, 255, 0.3); - border-radius: 8px; - background: rgba(255, 255, 255, 0.1); - color: white; - font-size: 14px; - resize: vertical; - box-sizing: border-box; - } - - .context-textarea::placeholder { - color: rgba(255, 255, 255, 0.7); - } - - .context-textarea:focus { - outline: none; - border-color: rgba(255, 255, 255, 0.6); - background: rgba(255, 255, 255, 0.15); - } - - .navigation { - position: absolute; - bottom: 0; - left: 0; - right: 0; - display: flex; - align-items: center; - justify-content: space-between; - padding: 12px 16px; - } - - .nav-button { - background: rgba(255, 255, 255, 0.2); - border: 1px solid rgba(255, 255, 255, 0.3); - color: white; - padding: 8px 16px; - border-radius: 20px; - font-size: 12px; - font-weight: 500; - cursor: pointer; - transition: all 0.3s ease; - display: flex; - align-items: center; - justify-content: center; - } - - .nav-button:hover { - background: rgba(255, 255, 255, 0.3); - border-color: rgba(255, 255, 255, 0.5); - } - - .nav-button:disabled { - opacity: 0.5; - cursor: not-allowed; - transform: none; - } - - .nav-button:disabled:hover { - background: rgba(255, 255, 255, 0.2); - border-color: rgba(255, 255, 255, 0.3); - } - - .progress-dots { - display: flex; - gap: 12px; - align-items: center; - } - - .dot { - width: 10px; - height: 10px; - border-radius: 50%; - background: rgba(255, 255, 255, 0.3); - transition: all 0.3s ease; - } - - .dot.active { - background: white; - transform: scale(1.2); - } - - .emoji { - position: absolute; - top: 15px; - right: 15px; - font-size: 40px; - transform: rotate(15deg); - z-index: 1; - } - - .feature-list { - text-align: left; - max-width: 100%; - } - - .feature-item { - display: flex; - align-items: center; - margin-bottom: 8px; - font-size: 14px; - } - - .feature-icon { - font-size: 16px; - margin-right: 8px; - } - `; - - static properties = { - currentSlide: { type: Number }, - contextText: { type: String }, - onComplete: { type: Function }, - onClose: { type: Function }, - }; - - constructor() { - super(); - this.currentSlide = 0; - this.contextText = ''; - this.onComplete = () => {}; - this.onClose = () => {}; - } - - nextSlide() { - if (this.currentSlide < 4) { - this.currentSlide++; - } else { - this.completeOnboarding(); - } - } - - prevSlide() { - if (this.currentSlide > 0) { - this.currentSlide--; - } - } - - handleContextInput(e) { - this.contextText = e.target.value; - } - - completeOnboarding() { - // Save the context text to localStorage as custom prompt - if (this.contextText.trim()) { - localStorage.setItem('customPrompt', this.contextText.trim()); - } - - // Mark onboarding as completed - localStorage.setItem('onboardingCompleted', 'true'); - - // Call the completion callback - this.onComplete(); - } - - renderSlide1() { - return html` -
-
👋
-
Welcome to Pickle Glass!
-
- Pickle Glass hears what you hear and sees what you see, then generates AI-powered suggestions without any user input needed. -
-
- `; - } - - renderSlide2() { - return html` -
-
🔒
-
Completely Private
-
- Your secret weapon is completely invisible! It won't show up on screen sharing apps, keeping your assistance completely private - during interviews and meetings. -
-
- `; - } - - renderSlide3() { - return html` -
-
📝
-
Tell Us Your Context
-
- Help the AI understand your situation better by sharing your context - like your resume, the job description, or interview - details. -
- -
- `; - } - - renderSlide4() { - return html` -
-
⚙️
-
Explore More Features
-
-
- 🎨 - Customize settings and AI profiles -
-
- 📚 - View your conversation history -
-
- 🔧 - Adjust screenshot intervals and quality -
-
-
- `; - } - - renderSlide5() { - return html` -
-
🎉
-
You're All Set!
-
- Pickle Glass is completely free to use. Just add your openai API key and start getting AI-powered assistance in your interviews - and meetings! -
-
- `; - } - - render() { - return html` - ${this.renderSlide1()} ${this.renderSlide2()} ${this.renderSlide3()} ${this.renderSlide4()} ${this.renderSlide5()} - - - `; - } -} - -customElements.define('onboarding-view', OnboardingView); diff --git a/src/index.js b/src/index.js index 2db9968..ea8224b 100644 --- a/src/index.js +++ b/src/index.js @@ -14,14 +14,19 @@ if (require('electron-squirrel-startup')) { const { app, BrowserWindow, shell, ipcMain, dialog } = require('electron'); const { createWindows } = require('./electron/windowManager.js'); const { setupLiveSummaryIpcHandlers, stopMacOSAudioCapture } = require('./features/listen/liveSummaryService.js'); +const { initializeFirebase } = require('./common/services/firebaseClient'); const databaseInitializer = require('./common/services/databaseInitializer'); -const dataService = require('./common/services/dataService'); +const authService = require('./common/services/authService'); const path = require('node:path'); const { Deeplink } = require('electron-deeplink'); const express = require('express'); const fetch = require('node-fetch'); const { autoUpdater } = require('electron-updater'); +const { EventEmitter } = require('events'); +const askService = require('./features/ask/askService'); +const sessionRepository = require('./common/repositories/session'); +const eventBridge = new EventEmitter(); let WEB_PORT = 3000; const openaiSessionRef = { current: null }; @@ -91,19 +96,27 @@ app.whenReady().then(async () => { }); } - const dbInitSuccess = await databaseInitializer.initialize(); - if (!dbInitSuccess) { - console.error('>>> [index.js] Database initialization failed - some features may not work'); - } else { - console.log('>>> [index.js] Database initialized successfully'); - } + initializeFirebase(); + + databaseInitializer.initialize() + .then(() => { + console.log('>>> [index.js] Database initialized successfully'); + + // Clean up any zombie sessions from previous runs first + sessionRepository.endAllActiveSessions(); + + authService.initialize(); + setupLiveSummaryIpcHandlers(openaiSessionRef); + askService.initialize(); + setupGeneralIpcHandlers(); + }) + .catch(err => { + console.error('>>> [index.js] Database initialization failed - some features may not work', err); + }); WEB_PORT = await startWebStack(); console.log('Web front-end listening on', WEB_PORT); - setupLiveSummaryIpcHandlers(openaiSessionRef); - setupGeneralIpcHandlers(); - createMainWindows(); initAutoUpdater(); @@ -116,8 +129,10 @@ app.on('window-all-closed', () => { } }); -app.on('before-quit', () => { +app.on('before-quit', async () => { + console.log('[Shutdown] App is about to quit.'); stopMacOSAudioCapture(); + await sessionRepository.endAllActiveSessions(); databaseInitializer.close(); }); @@ -145,19 +160,12 @@ app.on('open-url', (event, url) => { app.setAsDefaultProtocolClient('pickleglass'); function setupGeneralIpcHandlers() { - ipcMain.handle('open-external', async (event, url) => { - try { - await shell.openExternal(url); - return { success: true }; - } catch (error) { - console.error('Error opening external URL:', error); - return { success: false, error: error.message }; - } - }); + const userRepository = require('./common/repositories/user'); + const presetRepository = require('./common/repositories/preset'); ipcMain.handle('save-api-key', async (event, apiKey) => { try { - await dataService.saveApiKey(apiKey); + await userRepository.saveApiKey(apiKey, authService.getCurrentUserId()); BrowserWindow.getAllWindows().forEach(win => { win.webContents.send('api-key-updated'); }); @@ -168,21 +176,12 @@ function setupGeneralIpcHandlers() { } }); - ipcMain.handle('check-api-key', async () => { - return await dataService.checkApiKey(); - }); - ipcMain.handle('get-user-presets', async () => { - return await dataService.getUserPresets(); + return await presetRepository.getPresets(authService.getCurrentUserId()); }); ipcMain.handle('get-preset-templates', async () => { - return await dataService.getPresetTemplates(); - }); - - ipcMain.on('set-current-user', (event, uid) => { - console.log(`[IPC] set-current-user: ${uid}`); - dataService.setCurrentUser(uid); + return await presetRepository.getPresetTemplates(); }); ipcMain.handle('start-firebase-auth', async () => { @@ -197,63 +196,119 @@ function setupGeneralIpcHandlers() { } }); - ipcMain.on('firebase-auth-success', async (event, firebaseUser) => { - console.log('[IPC] firebase-auth-success:', firebaseUser.uid); - try { - await dataService.findOrCreateUser(firebaseUser); - dataService.setCurrentUser(firebaseUser.uid); - - BrowserWindow.getAllWindows().forEach(win => { - if (win !== event.sender.getOwnerBrowserWindow()) { - win.webContents.send('user-changed', firebaseUser); - } - }); - } catch (error) { - console.error('[IPC] Failed to handle firebase-auth-success:', error); - } - }); - - ipcMain.handle('get-api-url', () => { - return process.env.pickleglass_API_URL || 'http://localhost:9001'; - }); - ipcMain.handle('get-web-url', () => { return process.env.pickleglass_WEB_URL || 'http://localhost:3000'; }); - ipcMain.on('get-api-url-sync', (event) => { - event.returnValue = process.env.pickleglass_API_URL || 'http://localhost:9001'; - }); - - ipcMain.handle('get-database-status', async () => { - return await databaseInitializer.getStatus(); - }); - - ipcMain.handle('reset-database', async () => { - return await databaseInitializer.reset(); - }); - ipcMain.handle('get-current-user', async () => { - try { - const user = await dataService.sqliteClient.getUser(dataService.currentUserId); - if (user) { - return { - id: user.uid, - name: user.display_name, - isAuthenticated: user.uid !== 'default_user' - }; - } - throw new Error('User not found in DataService'); - } catch (error) { - console.error('Failed to get current user via DataService:', error); - return { - id: 'default_user', - name: 'Default User', - isAuthenticated: false - }; - } + return authService.getCurrentUser(); }); + // --- Web UI Data Handlers (New) --- + setupWebDataHandlers(); +} + +function setupWebDataHandlers() { + const sessionRepository = require('./common/repositories/session'); + const listenRepository = require('./features/listen/repositories'); + const askRepository = require('./features/ask/repositories'); + const userRepository = require('./common/repositories/user'); + const presetRepository = require('./common/repositories/preset'); + + const handleRequest = async (channel, responseChannel, payload) => { + let result; + const currentUserId = authService.getCurrentUserId(); + try { + switch (channel) { + // SESSION + case 'get-sessions': + result = await sessionRepository.getAllByUserId(currentUserId); + break; + case 'get-session-details': + const session = await sessionRepository.getById(payload); + if (!session) { + result = null; + break; + } + const transcripts = await listenRepository.getAllTranscriptsBySessionId(payload); + const ai_messages = await askRepository.getAllAiMessagesBySessionId(payload); + const summary = await listenRepository.getSummaryBySessionId(payload); + result = { session, transcripts, ai_messages, summary }; + break; + case 'delete-session': + result = await sessionRepository.deleteWithRelatedData(payload); + break; + case 'create-session': + const id = await sessionRepository.create(currentUserId, 'ask'); + if (payload.title) { + await sessionRepository.updateTitle(id, payload.title); + } + result = { id }; + break; + + // USER + case 'get-user-profile': + result = await userRepository.getById(currentUserId); + break; + case 'update-user-profile': + result = await userRepository.update({ uid: currentUserId, ...payload }); + break; + case 'find-or-create-user': + result = await userRepository.findOrCreate(payload); + break; + case 'save-api-key': + result = await userRepository.saveApiKey(payload, currentUserId); + break; + case 'check-api-key-status': + const user = await userRepository.getById(currentUserId); + result = { hasApiKey: !!user?.api_key && user.api_key.length > 0 }; + break; + case 'delete-account': + result = await userRepository.deleteById(currentUserId); + break; + + // PRESET + case 'get-presets': + result = await presetRepository.getPresets(currentUserId); + break; + case 'create-preset': + result = await presetRepository.create({ ...payload, uid: currentUserId }); + break; + case 'update-preset': + result = await presetRepository.update(payload.id, payload.data, currentUserId); + break; + case 'delete-preset': + result = await presetRepository.delete(payload, currentUserId); + break; + + // BATCH + case 'get-batch-data': + const includes = payload ? payload.split(',').map(item => item.trim()) : ['profile', 'presets', 'sessions']; + const batchResult = {}; + + if (includes.includes('profile')) { + batchResult.profile = await userRepository.getById(currentUserId); + } + if (includes.includes('presets')) { + batchResult.presets = await presetRepository.getPresets(currentUserId); + } + if (includes.includes('sessions')) { + batchResult.sessions = await sessionRepository.getAllByUserId(currentUserId); + } + result = batchResult; + break; + + default: + throw new Error(`Unknown web data channel: ${channel}`); + } + eventBridge.emit(responseChannel, { success: true, data: result }); + } catch (error) { + console.error(`Error handling web data request for ${channel}:`, error); + eventBridge.emit(responseChannel, { success: false, error: error.message }); + } + }; + + eventBridge.on('web-data-request', handleRequest); } async function handleCustomUrl(url) { @@ -293,18 +348,12 @@ async function handleCustomUrl(url) { } async function handleFirebaseAuthCallback(params) { + const userRepository = require('./common/repositories/user'); const { token: idToken } = params; if (!idToken) { console.error('[Auth] Firebase auth callback is missing ID token.'); - const { windowPool } = require('./electron/windowManager'); - const header = windowPool.get('header'); - if (header) { - header.webContents.send('login-successful', { - error: 'authentication_failed', - message: 'ID token not provided in deep link.' - }); - } + // No need to send IPC, the UI won't transition without a successful auth state change. return; } @@ -320,8 +369,6 @@ async function handleFirebaseAuthCallback(params) { const data = await response.json(); - - if (!response.ok || !data.success) { throw new Error(data.error || 'Failed to exchange token.'); } @@ -336,71 +383,32 @@ async function handleFirebaseAuthCallback(params) { photoURL: user.picture }; - await dataService.findOrCreateUser(firebaseUser); - dataService.setCurrentUser(user.uid); + // 1. Sync user data to local DB + await userRepository.findOrCreate(firebaseUser); console.log('[Auth] User data synced with local DB.'); - // if (firebaseUser.email && idToken) { - // try { - // const { getVirtualKeyByEmail, setApiKey } = require('./electron/windowManager'); - // console.log('[Auth] Fetching virtual key for:', firebaseUser.email); - // const vKey = await getVirtualKeyByEmail(firebaseUser.email, idToken); - // console.log('[Auth] Virtual key fetched successfully'); - - // await setApiKey(vKey); - // console.log('[Auth] Virtual key saved successfully'); - - // const { setCurrentFirebaseUser } = require('./electron/windowManager'); - // setCurrentFirebaseUser(firebaseUser); - - // const { windowPool } = require('./electron/windowManager'); - // windowPool.forEach(win => { - // if (win && !win.isDestroyed()) { - // win.webContents.send('api-key-updated'); - // win.webContents.send('firebase-user-updated', firebaseUser); - // } - // }); - // } catch (error) { - // console.error('[Auth] Virtual key fetch failed:', error); - // } - // } + // 2. Sign in using the authService in the main process + await authService.signInWithCustomToken(customToken); + console.log('[Auth] Main process sign-in initiated. Waiting for onAuthStateChanged...'); + // 3. Focus the app window const { windowPool } = require('./electron/windowManager'); const header = windowPool.get('header'); - if (header) { if (header.isMinimized()) header.restore(); header.focus(); - - console.log('[Auth] Sending custom token to renderer for sign-in.'); - header.webContents.send('login-successful', { - customToken: customToken, - user: firebaseUser, - success: true - }); - - BrowserWindow.getAllWindows().forEach(win => { - if (win !== header) { - win.webContents.send('user-changed', firebaseUser); - } - }); - - console.log('[Auth] Firebase authentication completed successfully'); - } else { - console.error('[Auth] Header window not found after getting custom token.'); + console.error('[Auth] Header window not found after auth callback.'); } } catch (error) { - console.error('[Auth] Error during custom token exchange:', error); - + console.error('[Auth] Error during custom token exchange or sign-in:', error); + // The UI will not change, and the user can try again. + // Optionally, send a generic error event to the renderer. const { windowPool } = require('./electron/windowManager'); const header = windowPool.get('header'); if (header) { - header.webContents.send('login-successful', { - error: 'authentication_failed', - message: error.message - }); + header.webContents.send('auth-failed', { message: error.message }); } } } @@ -462,7 +470,7 @@ async function startWebStack() { }); const createBackendApp = require('../pickleglass_web/backend_node'); - const nodeApi = createBackendApp(); + const nodeApi = createBackendApp(eventBridge); const staticDir = app.isPackaged ? path.join(process.resourcesPath, 'out') diff --git a/src/preload.js b/src/preload.js index 1b503da..5e9d369 100644 --- a/src/preload.js +++ b/src/preload.js @@ -1,41 +1,2 @@ // See the Electron documentation for details on how to use preload scripts: // https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts - -const { contextBridge, ipcRenderer } = require('electron'); - -contextBridge.exposeInMainWorld('ipcRenderer', { - send: (channel, data) => { - const validChannels = ['set-current-user', 'firebase-auth-success']; - if (validChannels.includes(channel)) { - ipcRenderer.send(channel, data); - } - }, - sendSync: (channel, data) => { - const validChannels = ['get-api-url-sync']; - if (validChannels.includes(channel)) { - return ipcRenderer.sendSync(channel, data); - } - }, - on: (channel, func) => { - const validChannels = ['api-key-updated']; - if (validChannels.includes(channel)) { - const newCallback = (_, ...args) => func(...args); - ipcRenderer.on(channel, newCallback); - return () => { - ipcRenderer.removeListener(channel, newCallback); - }; - } - }, - invoke: (channel, ...args) => { - const validChannels = ['save-api-key']; - if (validChannels.includes(channel)) { - return ipcRenderer.invoke(channel, ...args); - } - }, - removeAllListeners: (channel) => { - const validChannels = ['api-key-updated']; - if (validChannels.includes(channel)) { - ipcRenderer.removeAllListeners(channel); - } - }, -}); From 64111891eb8dd2d44659894c665373f80e99b24a Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Mon, 7 Jul 2025 05:42:05 +0900 Subject: [PATCH 02/52] settings big update --- src/app/PickleGlassApp.js | 21 +- src/electron/windowManager.js | 8 +- src/features/customize/CustomizeView.js | 1097 ----------------- src/features/settings/SettingsView.js | 809 ++++++++++++ src/features/settings/repositories/index.js | 23 + .../repositories/sqlite.repository.js | 225 ++++ src/features/settings/settingsService.js | 331 +++++ src/index.js | 20 + 8 files changed, 1419 insertions(+), 1115 deletions(-) delete mode 100644 src/features/customize/CustomizeView.js create mode 100644 src/features/settings/SettingsView.js create mode 100644 src/features/settings/repositories/index.js create mode 100644 src/features/settings/repositories/sqlite.repository.js create mode 100644 src/features/settings/settingsService.js diff --git a/src/app/PickleGlassApp.js b/src/app/PickleGlassApp.js index eb639eb..9662df4 100644 --- a/src/app/PickleGlassApp.js +++ b/src/app/PickleGlassApp.js @@ -1,7 +1,6 @@ import { html, css, LitElement } from '../assets/lit-core-2.7.4.min.js'; -import { CustomizeView } from '../features/customize/CustomizeView.js'; +import { SettingsView } from '../features/settings/SettingsView.js'; import { AssistantView } from '../features/listen/AssistantView.js'; -import { OnboardingView } from '../features/onboarding/OnboardingView.js'; import { AskView } from '../features/ask/AskView.js'; import '../features/listen/renderer.js'; @@ -21,7 +20,7 @@ export class PickleGlassApp extends LitElement { width: 100%; } - ask-view, customize-view, history-view, help-view, onboarding-view, setup-view { + ask-view, settings-view, history-view, help-view, setup-view { display: block; width: 100%; } @@ -180,8 +179,8 @@ export class PickleGlassApp extends LitElement { this.isMainViewVisible = !this.isMainViewVisible; } - handleCustomizeClick() { - this.currentView = 'customize'; + handleSettingsClick() { + this.currentView = 'settings'; this.isMainViewVisible = true; } @@ -247,10 +246,6 @@ export class PickleGlassApp extends LitElement { this.currentResponseIndex = e.detail.index; } - handleOnboardingComplete() { - this.currentView = 'main'; - } - render() { switch (this.currentView) { case 'listen': @@ -263,19 +258,17 @@ export class PickleGlassApp extends LitElement { >`; case 'ask': return html``; - case 'customize': - return html` (this.selectedProfile = profile)} .onLanguageChange=${lang => (this.selectedLanguage = lang)} - >`; + >`; case 'history': return html``; case 'help': return html``; - case 'onboarding': - return html``; case 'setup': return html``; default: diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 586e3f8..c9b08c4 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -102,8 +102,8 @@ function createFeatureWindows(header) { const settings = new BrowserWindow({ ...commonChildOptions, width:240, height:450, parent:undefined }); settings.setContentProtection(isContentProtectionOn); settings.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - settings.loadFile(path.join(__dirname,'../app/content.html'),{query:{view:'customize'}}) - .catch(console.error); + settings.loadFile(path.join(__dirname,'../app/content.html'),{query:{view:'settings'}}) + .catch(console.error); windowPool.set('settings', settings); } @@ -1950,7 +1950,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, openaiSessi globalShortcut.unregisterAll(); if (movementManager) { - movementManager.destroy(); + movementManager.destroy();nd } movementManager = new SmoothMovementManager(); @@ -2162,7 +2162,7 @@ function setupWindowIpcHandlers(mainWindow, sendToRenderer, openaiSessionRef) { if (isMainViewVisible) { const viewHeights = { listen: 400, - customize: 600, + settings: 600, help: 550, history: 550, setup: 200, diff --git a/src/features/customize/CustomizeView.js b/src/features/customize/CustomizeView.js deleted file mode 100644 index b3c6dba..0000000 --- a/src/features/customize/CustomizeView.js +++ /dev/null @@ -1,1097 +0,0 @@ -import { html, css, LitElement } from '../../assets/lit-core-2.7.4.min.js'; - -export class CustomizeView extends LitElement { - static styles = css` - * { - font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - cursor: default; - user-select: none; - } - - :host { - display: block; - width: 180px; - min-height: 180px; - color: white; - } - - .settings-container { - display: flex; - flex-direction: column; - height: 100%; - width: 100%; - background: rgba(20, 20, 20, 0.8); - border-radius: 12px; - outline: 0.5px rgba(255, 255, 255, 0.2) solid; - outline-offset: -1px; - box-sizing: border-box; - position: relative; - overflow-y: auto; - padding: 12px 12px; - z-index: 1000; - } - - .settings-container::-webkit-scrollbar { - width: 6px; - } - - .settings-container::-webkit-scrollbar-track { - background: rgba(255, 255, 255, 0.05); - border-radius: 3px; - } - - .settings-container::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.2); - border-radius: 3px; - } - - .settings-container::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.3); - } - - .settings-container::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.15); - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); - border-radius: 12px; - filter: blur(10px); - z-index: -1; - } - - .settings-button[disabled], - .api-key-section input[disabled] { - opacity: 0.4; - cursor: not-allowed; - pointer-events: none; - } - - .header-section { - display: flex; - justify-content: space-between; - align-items: flex-start; - padding-bottom: 6px; - border-bottom: 1px solid rgba(255, 255, 255, 0.1); - position: relative; - z-index: 1; - } - - .title-line { - display: flex; - justify-content: space-between; - align-items: center; - } - - .app-title { - font-size: 13px; - font-weight: 500; - color: white; - margin: 0 0 4px 0; - } - - .account-info { - font-size: 11px; - color: rgba(255, 255, 255, 0.7); - margin: 0; - } - - .invisibility-icon { - padding-top: 2px; - opacity: 0; - transition: opacity 0.3s ease; - } - - .invisibility-icon.visible { - opacity: 1; - } - - .invisibility-icon svg { - width: 16px; - height: 16px; - } - - .shortcuts-section { - display: flex; - flex-direction: column; - gap: 2px; - padding: 4px 0; - position: relative; - z-index: 1; - } - - .shortcut-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 4px 0; - color: white; - font-size: 11px; - } - - .shortcut-name { - font-weight: 300; - } - - .shortcut-keys { - display: flex; - align-items: center; - gap: 3px; - } - - .cmd-key, .shortcut-key { - background: rgba(255, 255, 255, 0.1); - // border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 3px; - width: 16px; - height: 16px; - display: flex; - align-items: center; - justify-content: center; - font-size: 11px; - font-weight: 500; - color: rgba(255, 255, 255, 0.9); - } - - /* Buttons Section */ - .buttons-section { - display: flex; - flex-direction: column; - gap: 4px; - padding-top: 6px; - border-top: 1px solid rgba(255, 255, 255, 0.1); - position: relative; - z-index: 1; - flex: 1; - } - - .settings-button { - background: rgba(255, 255, 255, 0.1); - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 4px; - color: white; - padding: 5px 10px; - font-size: 11px; - font-weight: 400; - cursor: pointer; - transition: all 0.15s ease; - display: flex; - align-items: center; - justify-content: center; - white-space: nowrap; - } - - .settings-button:hover { - background: rgba(255, 255, 255, 0.15); - border-color: rgba(255, 255, 255, 0.3); - } - - .settings-button:active { - transform: translateY(1px); - } - - .settings-button.full-width { - width: 100%; - } - - .settings-button.half-width { - flex: 1; - } - - .settings-button.danger { - background: rgba(255, 59, 48, 0.1); - border-color: rgba(255, 59, 48, 0.3); - color: rgba(255, 59, 48, 0.9); - } - - .settings-button.danger:hover { - background: rgba(255, 59, 48, 0.15); - border-color: rgba(255, 59, 48, 0.4); - } - - .move-buttons, .bottom-buttons { - display: flex; - gap: 4px; - } - - .api-key-section { - padding: 6px 0; - border-top: 1px solid rgba(255, 255, 255, 0.1); - } - - .api-key-section input { - width: 100%; - background: rgba(0,0,0,0.2); - border: 1px solid rgba(255,255,255,0.2); - color: white; - border-radius: 4px; - padding: 4px; - font-size: 11px; - margin-bottom: 4px; - } - - `; - - static properties = { - selectedProfile: { type: String }, - selectedLanguage: { type: String }, - selectedScreenshotInterval: { type: String }, - selectedImageQuality: { type: String }, - layoutMode: { type: String }, - keybinds: { type: Object }, - throttleTokens: { type: Number }, - maxTokens: { type: Number }, - throttlePercent: { type: Number }, - googleSearchEnabled: { type: Boolean }, - backgroundTransparency: { type: Number }, - fontSize: { type: Number }, - onProfileChange: { type: Function }, - onLanguageChange: { type: Function }, - onScreenshotIntervalChange: { type: Function }, - onImageQualityChange: { type: Function }, - onLayoutModeChange: { type: Function }, - contentProtection: { type: Boolean }, - userPresets: { type: Array }, - presetTemplates: { type: Array }, - currentUser: { type: String }, - isContentProtectionOn: { type: Boolean }, - firebaseUser: { type: Object, state: true }, - apiKey: { type: String, state: true }, - isLoading: { type: Boolean }, - activeTab: { type: String }, - }; - - constructor() { - super(); - - this.selectedProfile = localStorage.getItem('selectedProfile') || 'school'; - - // Language format migration for legacy users - let lang = localStorage.getItem('selectedLanguage') || 'en'; - if (lang.includes('-')) { - const newLang = lang.split('-')[0]; - console.warn(`[Migration] Correcting language format from "${lang}" to "${newLang}".`); - localStorage.setItem('selectedLanguage', newLang); - lang = newLang; - } - this.selectedLanguage = lang; - - this.selectedScreenshotInterval = localStorage.getItem('selectedScreenshotInterval') || '5000'; - this.selectedImageQuality = localStorage.getItem('selectedImageQuality') || '0.8'; - this.layoutMode = localStorage.getItem('layoutMode') || 'stacked'; - this.keybinds = this.getDefaultKeybinds(); - this.throttleTokens = 500; - this.maxTokens = 2000; - this.throttlePercent = 80; - this.backgroundTransparency = 0.5; - this.fontSize = 14; - this.userPresets = []; - this.presetTemplates = []; - this.currentUser = 'default_user'; - this.firebaseUser = null; - this.apiKey = null; - this.isContentProtectionOn = true; - this.isLoading = false; - this.activeTab = 'prompts'; - - this.loadKeybinds(); - this.loadRateLimitSettings(); - this.loadGoogleSearchSettings(); - this.loadBackgroundTransparency(); - this.loadFontSize(); - this.loadContentProtectionSettings(); - this.checkContentProtectionStatus(); - this.getApiKeyFromStorage(); - } - - connectedCallback() { - super.connectedCallback(); - - this.loadLayoutMode(); - this.loadInitialData(); - - this.resizeHandler = () => { - this.requestUpdate(); - this.updateScrollHeight(); - }; - window.addEventListener('resize', this.resizeHandler); - - setTimeout(() => this.updateScrollHeight(), 100); - - this.addEventListener('mouseenter', () => { - if (window.require) { - window.require('electron').ipcRenderer.send('cancel-hide-window', 'settings'); - } - }); - - this.addEventListener('mouseleave', () => { - if (window.require) { - window.require('electron').ipcRenderer.send('hide-window', 'settings'); - } - }); - - if (window.require) { - const { ipcRenderer } = window.require('electron'); - - this._userStateListener = (event, userState) => { - console.log('[CustomizeView] Received user-state-changed:', userState); - if (userState && userState.isLoggedIn) { - this.firebaseUser = userState; - } else { - this.firebaseUser = null; - } - this.getApiKeyFromStorage(); // Also update API key display - this.requestUpdate(); - }; - ipcRenderer.on('user-state-changed', this._userStateListener); - - ipcRenderer.on('api-key-validated', (event, newApiKey) => { - console.log('[CustomizeView] Received api-key-validated, updating state.'); - this.apiKey = newApiKey; - this.requestUpdate(); - }); - - ipcRenderer.on('api-key-updated', () => { - console.log('[CustomizeView] Received api-key-updated, refreshing state.'); - this.getApiKeyFromStorage(); - }); - - ipcRenderer.on('api-key-removed', () => { - console.log('[CustomizeView] Received api-key-removed, clearing state.'); - this.apiKey = null; - this.requestUpdate(); - }); - - this.loadInitialUser(); - } - } - - disconnectedCallback() { - super.disconnectedCallback(); - if (this.resizeHandler) { - window.removeEventListener('resize', this.resizeHandler); - } - - if (window.require) { - const { ipcRenderer } = window.require('electron'); - if (this._userStateListener) { - ipcRenderer.removeListener('user-state-changed', this._userStateListener); - } - ipcRenderer.removeAllListeners('api-key-validated'); - ipcRenderer.removeAllListeners('api-key-updated'); - ipcRenderer.removeAllListeners('api-key-removed'); - } - } - - updateScrollHeight() { - const windowHeight = window.innerHeight; - const headerHeight = 60; - const padding = 40; - const maxHeight = windowHeight - headerHeight - padding; - - this.style.maxHeight = `${maxHeight}px`; - } - - async checkContentProtectionStatus() { - if (window.require) { - const { ipcRenderer } = window.require('electron'); - this.isContentProtectionOn = await ipcRenderer.invoke('get-content-protection-status'); - this.requestUpdate(); - } - } - - getProfiles() { - if (this.presetTemplates && this.presetTemplates.length > 0) { - return this.presetTemplates.map(t => ({ - value: t.id || t._id, - name: t.title, - description: t.prompt?.slice(0, 60) + '...', - })); - } - - return [ - { value: 'school', name: 'School', description: '' }, - { value: 'meetings', name: 'Meetings', description: '' }, - { value: 'sales', name: 'Sales', description: '' }, - { value: 'recruiting', name: 'Recruiting', description: '' }, - { value: 'customer-support', name: 'Customer Support', description: '' }, - ]; - } - - getLanguages() { - return [ - { value: 'en', name: 'English' }, - { value: 'de', name: 'German' }, - { value: 'es', name: 'Spanish' }, - { value: 'fr', name: 'French' }, - { value: 'hi', name: 'Hindi' }, - { value: 'pt', name: 'Portuguese' }, - { value: 'ar', name: 'Arabic' }, - { value: 'id', name: 'Indonesian' }, - { value: 'it', name: 'Italian' }, - { value: 'ja', name: 'Japanese' }, - { value: 'tr', name: 'Turkish' }, - { value: 'vi', name: 'Vietnamese' }, - { value: 'bn', name: 'Bengali' }, - { value: 'gu', name: 'Gujarati' }, - { value: 'kn', name: 'Kannada' }, - { value: 'ml', name: 'Malayalam' }, - { value: 'mr', name: 'Marathi' }, - { value: 'ta', name: 'Tamil' }, - { value: 'te', name: 'Telugu' }, - { value: 'nl', name: 'Dutch' }, - { value: 'ko', name: 'Korean' }, - { value: 'zh', name: 'Chinese' }, - { value: 'pl', name: 'Polish' }, - { value: 'ru', name: 'Russian' }, - { value: 'th', name: 'Thai' }, - ]; - } - - getProfileNames() { - return { - interview: 'Job Interview', - sales: 'Sales Call', - meeting: 'Business Meeting', - presentation: 'Presentation', - negotiation: 'Negotiation', - }; - } - - handleProfileSelect(e) { - this.selectedProfile = e.target.value; - localStorage.setItem('selectedProfile', this.selectedProfile); - this.onProfileChange(this.selectedProfile); - } - - handleLanguageSelect(e) { - this.selectedLanguage = e.target.value; - localStorage.setItem('selectedLanguage', this.selectedLanguage); - this.onLanguageChange(this.selectedLanguage); - } - - handleScreenshotIntervalSelect(e) { - this.selectedScreenshotInterval = e.target.value; - localStorage.setItem('selectedScreenshotInterval', this.selectedScreenshotInterval); - this.onScreenshotIntervalChange(this.selectedScreenshotInterval); - } - - handleImageQualitySelect(e) { - this.selectedImageQuality = e.target.value; - this.onImageQualityChange(e.target.value); - } - - handleLayoutModeSelect(e) { - this.layoutMode = e.target.value; - localStorage.setItem('layoutMode', this.layoutMode); - this.onLayoutModeChange(e.target.value); - } - - getUserCustomPrompt() { - console.log('[CustomizeView] getUserCustomPrompt called'); - console.log('[CustomizeView] userPresets:', this.userPresets); - console.log('[CustomizeView] selectedProfile:', this.selectedProfile); - - if (!this.userPresets || this.userPresets.length === 0) { - console.log('[CustomizeView] No presets - returning loading message'); - return 'Loading personalized prompt... Please set it in the web.'; - } - - let preset = this.userPresets.find(p => p.id === 'personalized' || p._id === 'personalized'); - console.log('[CustomizeView] personalized preset:', preset); - - if (!preset) { - preset = this.userPresets.find(p => p.id === this.selectedProfile || p._id === this.selectedProfile); - console.log('[CustomizeView] selectedProfile preset:', preset); - } - - if (!preset) { - preset = this.userPresets[0]; - console.log('[CustomizeView] Using first preset:', preset); - } - - const result = preset?.prompt || 'No personalized prompt set.'; - console.log('[CustomizeView] Final returned prompt:', result); - return result; - } - - async loadInitialData() { - if (window.require) { - const { ipcRenderer } = window.require('electron'); - try { - this.isLoading = true; - this.userPresets = await ipcRenderer.invoke('get-user-presets'); - this.presetTemplates = await ipcRenderer.invoke('get-preset-templates'); - console.log('[CustomizeView] Loaded presets and templates via IPC'); - } catch (error) { - console.error('[CustomizeView] Failed to load data via IPC:', error); - } finally { - this.isLoading = false; - } - } else { - console.log('[CustomizeView] IPC not available'); - } - } - - getDefaultKeybinds() { - const isMac = window.pickleGlass?.isMacOS || navigator.platform.includes('Mac'); - return { - moveUp: isMac ? 'Cmd+Up' : 'Ctrl+Up', - moveDown: isMac ? 'Cmd+Down' : 'Ctrl+Down', - moveLeft: isMac ? 'Cmd+Left' : 'Ctrl+Left', - moveRight: isMac ? 'Cmd+Right' : 'Ctrl+Right', - toggleVisibility: isMac ? 'Cmd+\\' : 'Ctrl+\\', - toggleClickThrough: isMac ? 'Cmd+M' : 'Ctrl+M', - nextStep: isMac ? 'Cmd+Enter' : 'Ctrl+Enter', - manualScreenshot: isMac ? 'Cmd+Shift+S' : 'Ctrl+Shift+S', - previousResponse: isMac ? 'Cmd+[' : 'Ctrl+[', - nextResponse: isMac ? 'Cmd+]' : 'Ctrl+]', - scrollUp: isMac ? 'Cmd+Shift+Up' : 'Ctrl+Shift+Up', - scrollDown: isMac ? 'Cmd+Shift+Down' : 'Ctrl+Shift+Down', - }; - } - - loadKeybinds() { - const savedKeybinds = localStorage.getItem('customKeybinds'); - if (savedKeybinds) { - try { - this.keybinds = { ...this.getDefaultKeybinds(), ...JSON.parse(savedKeybinds) }; - } catch (e) { - console.error('Failed to parse saved keybinds:', e); - this.keybinds = this.getDefaultKeybinds(); - } - } - } - - saveKeybinds() { - localStorage.setItem('customKeybinds', JSON.stringify(this.keybinds)); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.send('update-keybinds', this.keybinds); - } - } - - handleKeybindChange(action, value) { - this.keybinds = { ...this.keybinds, [action]: value }; - this.saveKeybinds(); - this.requestUpdate(); - } - - resetKeybinds() { - this.keybinds = this.getDefaultKeybinds(); - localStorage.removeItem('customKeybinds'); - this.requestUpdate(); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.send('update-keybinds', this.keybinds); - } - } - - getKeybindActions() { - return [ - { - key: 'moveUp', - name: 'Move Window Up', - description: 'Move the application window up', - }, - { - key: 'moveDown', - name: 'Move Window Down', - description: 'Move the application window down', - }, - { - key: 'moveLeft', - name: 'Move Window Left', - description: 'Move the application window left', - }, - { - key: 'moveRight', - name: 'Move Window Right', - description: 'Move the application window right', - }, - { - key: 'toggleVisibility', - name: 'Toggle Window Visibility', - description: 'Show/hide the application window', - }, - { - key: 'toggleClickThrough', - name: 'Toggle Click-through Mode', - description: 'Enable/disable click-through functionality', - }, - { - key: 'nextStep', - name: 'Ask Next Step', - description: 'Ask AI for the next step suggestion', - }, - { - key: 'manualScreenshot', - name: 'Manual Screenshot', - description: 'Take a manual screenshot for AI analysis', - }, - { - key: 'previousResponse', - name: 'Previous Response', - description: 'Navigate to the previous AI response', - }, - { - key: 'nextResponse', - name: 'Next Response', - description: 'Navigate to the next AI response', - }, - { - key: 'scrollUp', - name: 'Scroll Response Up', - description: 'Scroll the AI response content up', - }, - { - key: 'scrollDown', - name: 'Scroll Response Down', - description: 'Scroll the AI response content down', - }, - ]; - } - - handleKeybindFocus(e) { - e.target.placeholder = 'Press key combination...'; - e.target.select(); - } - - handleKeybindInput(e) { - e.preventDefault(); - - const modifiers = []; - const keys = []; - - if (e.ctrlKey) modifiers.push('Ctrl'); - if (e.metaKey) modifiers.push('Cmd'); - if (e.altKey) modifiers.push('Alt'); - if (e.shiftKey) modifiers.push('Shift'); - - let mainKey = e.key; - - switch (e.code) { - case 'ArrowUp': - mainKey = 'Up'; - break; - case 'ArrowDown': - mainKey = 'Down'; - break; - case 'ArrowLeft': - mainKey = 'Left'; - break; - case 'ArrowRight': - mainKey = 'Right'; - break; - case 'Enter': - mainKey = 'Enter'; - break; - case 'Space': - mainKey = 'Space'; - break; - case 'Backslash': - mainKey = '\\'; - break; - case 'KeyS': - if (e.shiftKey) mainKey = 'S'; - break; - case 'KeyM': - mainKey = 'M'; - break; - default: - if (e.key.length === 1) { - mainKey = e.key.toUpperCase(); - } - break; - } - - if (['Control', 'Meta', 'Alt', 'Shift'].includes(e.key)) { - return; - } - - const keybind = [...modifiers, mainKey].join('+'); - - const action = e.target.dataset.action; - - this.handleKeybindChange(action, keybind); - - e.target.value = keybind; - e.target.blur(); - } - - loadRateLimitSettings() { - const throttleTokens = localStorage.getItem('throttleTokens'); - const maxTokens = localStorage.getItem('maxTokens'); - const throttlePercent = localStorage.getItem('throttlePercent'); - - if (throttleTokens !== null) { - this.throttleTokens = parseInt(throttleTokens, 10) || 500; - } - if (maxTokens !== null) { - this.maxTokens = parseInt(maxTokens, 10) || 2000; - } - if (throttlePercent !== null) { - this.throttlePercent = parseInt(throttlePercent, 10) || 80; - } - } - - handleThrottleTokensChange(e) { - this.throttleTokens = parseInt(e.target.value, 10); - localStorage.setItem('throttleTokens', this.throttleTokens.toString()); - this.requestUpdate(); - } - - handleMaxTokensChange(e) { - const value = parseInt(e.target.value, 10); - if (!isNaN(value) && value > 0) { - this.maxTokens = value; - localStorage.setItem('maxTokens', this.maxTokens.toString()); - } - } - - handleThrottlePercentChange(e) { - const value = parseInt(e.target.value, 10); - if (!isNaN(value) && value >= 0 && value <= 100) { - this.throttlePercent = value; - localStorage.setItem('throttlePercent', this.throttlePercent.toString()); - } - } - - resetRateLimitSettings() { - this.throttleTokens = 500; - this.maxTokens = 2000; - this.throttlePercent = 80; - - localStorage.removeItem('throttleTokens'); - localStorage.removeItem('maxTokens'); - localStorage.removeItem('throttlePercent'); - - this.requestUpdate(); - } - - loadGoogleSearchSettings() { - const googleSearchEnabled = localStorage.getItem('googleSearchEnabled'); - if (googleSearchEnabled !== null) { - this.googleSearchEnabled = googleSearchEnabled === 'true'; - } - } - - async handleGoogleSearchChange(e) { - this.googleSearchEnabled = e.target.checked; - localStorage.setItem('googleSearchEnabled', this.googleSearchEnabled.toString()); - - if (window.require) { - try { - const { ipcRenderer } = window.require('electron'); - await ipcRenderer.invoke('update-google-search-setting', this.googleSearchEnabled); - } catch (error) { - console.error('Failed to notify main process:', error); - } - } - - this.requestUpdate(); - } - - loadLayoutMode() { - const savedLayoutMode = localStorage.getItem('layoutMode'); - if (savedLayoutMode) { - this.layoutMode = savedLayoutMode; - } - } - - loadBackgroundTransparency() { - const backgroundTransparency = localStorage.getItem('backgroundTransparency'); - if (backgroundTransparency !== null) { - this.backgroundTransparency = parseFloat(backgroundTransparency) || 0.5; - } - this.updateBackgroundTransparency(); - } - - handleBackgroundTransparencyChange(e) { - this.backgroundTransparency = parseFloat(e.target.value); - localStorage.setItem('backgroundTransparency', this.backgroundTransparency.toString()); - this.updateBackgroundTransparency(); - this.requestUpdate(); - } - - updateBackgroundTransparency() { - const root = document.documentElement; - root.style.setProperty('--header-background', `rgba(0, 0, 0, ${this.backgroundTransparency})`); - root.style.setProperty('--main-content-background', `rgba(0, 0, 0, ${this.backgroundTransparency})`); - root.style.setProperty('--card-background', `rgba(255, 255, 255, ${this.backgroundTransparency * 0.05})`); - root.style.setProperty('--input-background', `rgba(0, 0, 0, ${this.backgroundTransparency * 0.375})`); - root.style.setProperty('--input-focus-background', `rgba(0, 0, 0, ${this.backgroundTransparency * 0.625})`); - root.style.setProperty('--button-background', `rgba(0, 0, 0, ${this.backgroundTransparency * 0.625})`); - root.style.setProperty('--preview-video-background', `rgba(0, 0, 0, ${this.backgroundTransparency * 1.125})`); - root.style.setProperty('--screen-option-background', `rgba(0, 0, 0, ${this.backgroundTransparency * 0.5})`); - root.style.setProperty('--screen-option-hover-background', `rgba(0, 0, 0, ${this.backgroundTransparency * 0.75})`); - root.style.setProperty('--scrollbar-background', `rgba(0, 0, 0, ${this.backgroundTransparency * 0.5})`); - } - - loadFontSize() { - const fontSize = localStorage.getItem('fontSize'); - if (fontSize !== null) { - this.fontSize = parseInt(fontSize, 10) || 14; - } - this.updateFontSize(); - } - - handleFontSizeChange(e) { - this.fontSize = parseInt(e.target.value, 10); - localStorage.setItem('fontSize', this.fontSize.toString()); - this.updateFontSize(); - this.requestUpdate(); - } - - updateFontSize() { - const root = document.documentElement; - root.style.setProperty('--response-font-size', `${this.fontSize}px`); - } - - loadContentProtectionSettings() { - const contentProtection = localStorage.getItem('contentProtection'); - if (contentProtection !== null) { - this.contentProtection = contentProtection === 'true'; - } - } - - async handleContentProtectionChange(e) { - this.contentProtection = e.target.checked; - localStorage.setItem('contentProtection', this.contentProtection.toString()); - - if (window.require) { - try { - const { ipcRenderer } = window.require('electron'); - await ipcRenderer.invoke('update-content-protection', this.contentProtection); - } catch (error) { - console.error('Failed to notify main process about content protection change:', error); - } - } - - this.requestUpdate(); - } - - render() { - const loggedIn = !!this.firebaseUser; - console.log('[CustomizeView] render: Rendering component template.'); - return html` -
-
-
-

Pickle Glass

- -
-
- - - -
-
- -
- - -
- -
- ${this.getMainShortcuts().map(shortcut => html` -
- ${shortcut.name} -
- - ${shortcut.key} -
-
- `)} -
- -
- - -
- - -
- - - -
- ${this.firebaseUser - ? html` - - ` - : html` - - ` - } - -
-
-
- `; - } - - getMainShortcuts() { - return [ - { name: 'Show / Hide', key: '\\' }, - { name: 'Ask Anything', key: '↵' }, - { name: 'Scroll AI Response', key: '↕' } - ]; - } - - handleMoveLeft() { - console.log('Move Left clicked'); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.invoke('move-window-step', 'left'); - } - } - - handleMoveRight() { - console.log('Move Right clicked'); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.invoke('move-window-step', 'right'); - } - } - - async handlePersonalize() { - console.log('Personalize clicked'); - if (window.require) { - const { ipcRenderer, shell } = window.require('electron'); - try { - const webUrl = await ipcRenderer.invoke('get-web-url'); - shell.openExternal(`${webUrl}/personalize`); - } catch (error) { - console.error('Failed to get web URL or open external link:', error); - shell.openExternal('http://localhost:3000/personalize'); - } - } - } - - async handleToggleInvisibility() { - console.log('Toggle Invisibility clicked'); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - this.isContentProtectionOn = await ipcRenderer.invoke('toggle-content-protection'); - this.requestUpdate(); - } - } - - async handleSaveApiKey() { - const input = this.shadowRoot.getElementById('api-key-input'); - if (!input || !input.value) return; - - const newApiKey = input.value; - if (window.require) { - const { ipcRenderer } = window.require('electron'); - try { - const result = await ipcRenderer.invoke('save-api-key', newApiKey); - if (result.success) { - console.log('API Key saved successfully via IPC.'); - this.apiKey = newApiKey; - this.requestUpdate(); - } else { - console.error('Failed to save API Key via IPC:', result.error); - } - } catch(e) { - console.error('Error invoking save-api-key IPC:', e); - } - } - } - - async handleClearApiKey() { - console.log('Clear API Key clicked'); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - await ipcRenderer.invoke('remove-api-key'); - this.requestUpdate(); - } - } - - handleQuit() { - console.log('Quit clicked'); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.invoke('quit-application'); - } - } - - handleFirebaseLogout() { - console.log('Firebase Logout clicked'); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.invoke('firebase-logout'); - } - } - - async loadInitialUser() { - if (!window.require) return; - const { ipcRenderer } = window.require('electron'); - try { - console.log('[CustomizeView] Loading initial user state...'); - const userState = await ipcRenderer.invoke('get-current-user'); - if (userState && userState.isLoggedIn) { - this.firebaseUser = userState; - } else { - this.firebaseUser = null; - } - this.requestUpdate(); - } catch (error) { - console.error('[CustomizeView] Failed to load initial user:', error); - this.firebaseUser = null; - this.requestUpdate(); - } - } - - getApiKeyFromStorage() { - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.invoke('get-stored-api-key').then(key => { - this.apiKey = key; - this.requestUpdate(); - }).catch(error => { - console.log('[CustomizeView] Failed to get API key:', error); - this.apiKey = null; - }); - } - return null; - } -} - -customElements.define('customize-view', CustomizeView); diff --git a/src/features/settings/SettingsView.js b/src/features/settings/SettingsView.js new file mode 100644 index 0000000..ba21dbb --- /dev/null +++ b/src/features/settings/SettingsView.js @@ -0,0 +1,809 @@ +import { html, css, LitElement } from '../../assets/lit-core-2.7.4.min.js'; + +export class SettingsView extends LitElement { + static styles = css` + * { + font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + cursor: default; + user-select: none; + } + + :host { + display: block; + width: 180px; + min-height: 180px; + color: white; + } + + .settings-container { + display: flex; + flex-direction: column; + height: 100%; + width: 100%; + background: rgba(20, 20, 20, 0.8); + border-radius: 12px; + outline: 0.5px rgba(255, 255, 255, 0.2) solid; + outline-offset: -1px; + box-sizing: border-box; + position: relative; + overflow-y: auto; + padding: 12px 12px; + z-index: 1000; + } + + .settings-container::-webkit-scrollbar { + width: 6px; + } + + .settings-container::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.05); + border-radius: 3px; + } + + .settings-container::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.2); + border-radius: 3px; + } + + .settings-container::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.3); + } + + .settings-container::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.15); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); + border-radius: 12px; + filter: blur(10px); + z-index: -1; + } + + .settings-button[disabled], + .api-key-section input[disabled] { + opacity: 0.4; + cursor: not-allowed; + pointer-events: none; + } + + .header-section { + display: flex; + justify-content: space-between; + align-items: flex-start; + padding-bottom: 6px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + position: relative; + z-index: 1; + } + + .title-line { + display: flex; + justify-content: space-between; + align-items: center; + } + + .app-title { + font-size: 13px; + font-weight: 500; + color: white; + margin: 0 0 4px 0; + } + + .account-info { + font-size: 11px; + color: rgba(255, 255, 255, 0.7); + margin: 0; + } + + .invisibility-icon { + padding-top: 2px; + opacity: 0; + transition: opacity 0.3s ease; + } + + .invisibility-icon.visible { + opacity: 1; + } + + .invisibility-icon svg { + width: 16px; + height: 16px; + } + + .shortcuts-section { + display: flex; + flex-direction: column; + gap: 2px; + padding: 4px 0; + position: relative; + z-index: 1; + } + + .shortcut-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 4px 0; + color: white; + font-size: 11px; + } + + .shortcut-name { + font-weight: 300; + } + + .shortcut-keys { + display: flex; + align-items: center; + gap: 3px; + } + + .cmd-key, .shortcut-key { + background: rgba(255, 255, 255, 0.1); + border-radius: 3px; + width: 16px; + height: 16px; + display: flex; + align-items: center; + justify-content: center; + font-size: 11px; + font-weight: 500; + color: rgba(255, 255, 255, 0.9); + } + + /* Buttons Section */ + .buttons-section { + display: flex; + flex-direction: column; + gap: 4px; + padding-top: 6px; + border-top: 1px solid rgba(255, 255, 255, 0.1); + position: relative; + z-index: 1; + flex: 1; + } + + .settings-button { + background: rgba(255, 255, 255, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 4px; + color: white; + padding: 5px 10px; + font-size: 11px; + font-weight: 400; + cursor: pointer; + transition: all 0.15s ease; + display: flex; + align-items: center; + justify-content: center; + white-space: nowrap; + } + + .settings-button:hover { + background: rgba(255, 255, 255, 0.15); + border-color: rgba(255, 255, 255, 0.3); + } + + .settings-button:active { + transform: translateY(1px); + } + + .settings-button.full-width { + width: 100%; + } + + .settings-button.half-width { + flex: 1; + } + + .settings-button.danger { + background: rgba(255, 59, 48, 0.1); + border-color: rgba(255, 59, 48, 0.3); + color: rgba(255, 59, 48, 0.9); + } + + .settings-button.danger:hover { + background: rgba(255, 59, 48, 0.15); + border-color: rgba(255, 59, 48, 0.4); + } + + .move-buttons, .bottom-buttons { + display: flex; + gap: 4px; + } + + .api-key-section { + padding: 6px 0; + border-top: 1px solid rgba(255, 255, 255, 0.1); + } + + .api-key-section input { + width: 100%; + background: rgba(0,0,0,0.2); + border: 1px solid rgba(255,255,255,0.2); + color: white; + border-radius: 4px; + padding: 4px; + font-size: 11px; + margin-bottom: 4px; + box-sizing: border-box; + } + + .api-key-section input::placeholder { + color: rgba(255, 255, 255, 0.4); + } + + /* Preset Management Section */ + .preset-section { + padding: 6px 0; + border-top: 1px solid rgba(255, 255, 255, 0.1); + } + + .preset-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 4px; + } + + .preset-title { + font-size: 11px; + font-weight: 500; + color: white; + } + + .preset-count { + font-size: 9px; + color: rgba(255, 255, 255, 0.5); + margin-left: 4px; + } + + .preset-toggle { + font-size: 10px; + color: rgba(255, 255, 255, 0.6); + cursor: pointer; + padding: 2px 4px; + border-radius: 2px; + transition: background-color 0.15s ease; + } + + .preset-toggle:hover { + background: rgba(255, 255, 255, 0.1); + } + + .preset-list { + display: flex; + flex-direction: column; + gap: 2px; + max-height: 120px; + overflow-y: auto; + } + + .preset-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 4px 6px; + background: rgba(255, 255, 255, 0.05); + border-radius: 3px; + cursor: pointer; + transition: all 0.15s ease; + font-size: 11px; + border: 1px solid transparent; + } + + .preset-item:hover { + background: rgba(255, 255, 255, 0.1); + border-color: rgba(255, 255, 255, 0.1); + } + + .preset-item.selected { + background: rgba(0, 122, 255, 0.25); + border-color: rgba(0, 122, 255, 0.6); + box-shadow: 0 0 0 1px rgba(0, 122, 255, 0.3); + } + + .preset-name { + color: white; + flex: 1; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + font-weight: 300; + } + + .preset-item.selected .preset-name { + font-weight: 500; + } + + .preset-status { + font-size: 9px; + color: rgba(0, 122, 255, 0.8); + font-weight: 500; + margin-left: 6px; + } + + .no-presets-message { + padding: 12px 8px; + text-align: center; + color: rgba(255, 255, 255, 0.5); + font-size: 10px; + line-height: 1.4; + } + + .no-presets-message .web-link { + color: rgba(0, 122, 255, 0.8); + text-decoration: underline; + cursor: pointer; + } + + .no-presets-message .web-link:hover { + color: rgba(0, 122, 255, 1); + } + + .loading-state { + display: flex; + align-items: center; + justify-content: center; + padding: 20px; + color: rgba(255, 255, 255, 0.7); + font-size: 11px; + } + + .loading-spinner { + width: 12px; + height: 12px; + border: 1px solid rgba(255, 255, 255, 0.2); + border-top: 1px solid rgba(255, 255, 255, 0.8); + border-radius: 50%; + animation: spin 1s linear infinite; + margin-right: 6px; + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + .hidden { + display: none; + } + `; + + static properties = { + firebaseUser: { type: Object, state: true }, + apiKey: { type: String, state: true }, + isLoading: { type: Boolean, state: true }, + isContentProtectionOn: { type: Boolean, state: true }, + settings: { type: Object, state: true }, + presets: { type: Array, state: true }, + selectedPreset: { type: Object, state: true }, + showPresets: { type: Boolean, state: true }, + saving: { type: Boolean, state: true }, + }; + + constructor() { + super(); + this.firebaseUser = null; + this.apiKey = null; + this.isLoading = false; + this.isContentProtectionOn = true; + this.settings = null; + this.presets = []; + this.selectedPreset = null; + this.showPresets = false; + this.saving = false; + this.loadInitialData(); + } + + async loadInitialData() { + if (!window.require) return; + + try { + this.isLoading = true; + const { ipcRenderer } = window.require('electron'); + + // Load all data in parallel + const [settings, presets, apiKey, contentProtection, userState] = await Promise.all([ + ipcRenderer.invoke('settings:getSettings'), + ipcRenderer.invoke('settings:getPresets'), + ipcRenderer.invoke('get-stored-api-key'), + ipcRenderer.invoke('get-content-protection-status'), + ipcRenderer.invoke('get-current-user') + ]); + + this.settings = settings; + this.presets = presets || []; + this.apiKey = apiKey; + this.isContentProtectionOn = contentProtection; + + // Set first user preset as selected + if (this.presets.length > 0) { + const firstUserPreset = this.presets.find(p => p.is_default === 0); + if (firstUserPreset) { + this.selectedPreset = firstUserPreset; + } + } + + if (userState && userState.isLoggedIn) { + this.firebaseUser = userState.user; + } + } catch (error) { + console.error('Error loading initial data:', error); + } finally { + this.isLoading = false; + } + } + + connectedCallback() { + super.connectedCallback(); + + this.setupEventListeners(); + this.setupIpcListeners(); + this.setupWindowResize(); + } + + disconnectedCallback() { + super.disconnectedCallback(); + this.cleanupEventListeners(); + this.cleanupIpcListeners(); + this.cleanupWindowResize(); + } + + setupEventListeners() { + this.addEventListener('mouseenter', this.handleMouseEnter); + this.addEventListener('mouseleave', this.handleMouseLeave); + } + + cleanupEventListeners() { + this.removeEventListener('mouseenter', this.handleMouseEnter); + this.removeEventListener('mouseleave', this.handleMouseLeave); + } + + setupIpcListeners() { + if (!window.require) return; + + const { ipcRenderer } = window.require('electron'); + + this._userStateListener = (event, userState) => { + console.log('[SettingsView] Received user-state-changed:', userState); + if (userState && userState.isLoggedIn) { + this.firebaseUser = userState; + } else { + this.firebaseUser = null; + } + this.requestUpdate(); + }; + + this._settingsUpdatedListener = (event, settings) => { + console.log('[SettingsView] Received settings-updated'); + this.settings = settings; + this.requestUpdate(); + }; + + // 프리셋 업데이트 리스너 추가 + this._presetsUpdatedListener = async (event) => { + console.log('[SettingsView] Received presets-updated, refreshing presets'); + try { + const presets = await ipcRenderer.invoke('settings:getPresets'); + this.presets = presets || []; + + // 현재 선택된 프리셋이 삭제되었는지 확인 (사용자 프리셋만 고려) + const userPresets = this.presets.filter(p => p.is_default === 0); + if (this.selectedPreset && !userPresets.find(p => p.id === this.selectedPreset.id)) { + this.selectedPreset = userPresets.length > 0 ? userPresets[0] : null; + } + + this.requestUpdate(); + } catch (error) { + console.error('[SettingsView] Failed to refresh presets:', error); + } + }; + + ipcRenderer.on('user-state-changed', this._userStateListener); + ipcRenderer.on('settings-updated', this._settingsUpdatedListener); + ipcRenderer.on('presets-updated', this._presetsUpdatedListener); + } + + cleanupIpcListeners() { + if (!window.require) return; + + const { ipcRenderer } = window.require('electron'); + + if (this._userStateListener) { + ipcRenderer.removeListener('user-state-changed', this._userStateListener); + } + if (this._settingsUpdatedListener) { + ipcRenderer.removeListener('settings-updated', this._settingsUpdatedListener); + } + if (this._presetsUpdatedListener) { + ipcRenderer.removeListener('presets-updated', this._presetsUpdatedListener); + } + } + + setupWindowResize() { + this.resizeHandler = () => { + this.requestUpdate(); + this.updateScrollHeight(); + }; + window.addEventListener('resize', this.resizeHandler); + + // Initial setup + setTimeout(() => this.updateScrollHeight(), 100); + } + + cleanupWindowResize() { + if (this.resizeHandler) { + window.removeEventListener('resize', this.resizeHandler); + } + } + + updateScrollHeight() { + const windowHeight = window.innerHeight; + const headerHeight = 40; + const padding = 20; + const maxHeight = windowHeight - headerHeight - padding; + + this.style.maxHeight = `${maxHeight}px`; + + const container = this.shadowRoot?.querySelector('.settings-container'); + if (container) { + container.style.maxHeight = `${maxHeight - 20}px`; + } + } + + handleMouseEnter = () => { + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.send('cancel-hide-window', 'settings'); + } + } + + handleMouseLeave = () => { + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.send('hide-window', 'settings'); + } + } + + getMainShortcuts() { + return [ + { name: 'Show / Hide', key: '\\' }, + { name: 'Ask Anything', key: '↵' }, + { name: 'Scroll AI Response', key: '↕' } + ]; + } + + togglePresets() { + this.showPresets = !this.showPresets; + } + + async handlePresetSelect(preset) { + this.selectedPreset = preset; + // Here you could implement preset application logic + console.log('Selected preset:', preset); + } + + handleMoveLeft() { + console.log('Move Left clicked'); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.invoke('move-window-step', 'left'); + } + } + + handleMoveRight() { + console.log('Move Right clicked'); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.invoke('move-window-step', 'right'); + } + } + + async handlePersonalize() { + console.log('Personalize clicked'); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + try { + await ipcRenderer.invoke('open-login-page'); + } catch (error) { + console.error('Failed to open personalize page:', error); + } + } + } + + async handleToggleInvisibility() { + console.log('Toggle Invisibility clicked'); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + this.isContentProtectionOn = await ipcRenderer.invoke('toggle-content-protection'); + this.requestUpdate(); + } + } + + async handleSaveApiKey() { + const input = this.shadowRoot.getElementById('api-key-input'); + if (!input || !input.value) return; + + const newApiKey = input.value; + if (window.require) { + const { ipcRenderer } = window.require('electron'); + try { + const result = await ipcRenderer.invoke('settings:saveApiKey', newApiKey); + if (result.success) { + console.log('API Key saved successfully via IPC.'); + this.apiKey = newApiKey; + this.requestUpdate(); + } else { + console.error('Failed to save API Key via IPC:', result.error); + } + } catch(e) { + console.error('Error invoking save-api-key IPC:', e); + } + } + } + + async handleClearApiKey() { + console.log('Clear API Key clicked'); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + await ipcRenderer.invoke('settings:removeApiKey'); + this.apiKey = null; + this.requestUpdate(); + } + } + + handleQuit() { + console.log('Quit clicked'); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.invoke('quit-application'); + } + } + + handleFirebaseLogout() { + console.log('Firebase Logout clicked'); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.invoke('firebase-logout'); + } + } + + render() { + if (this.isLoading) { + return html` +
+
+
+ Loading... +
+
+ `; + } + + const loggedIn = !!this.firebaseUser; + + return html` +
+
+
+

Pickle Glass

+ +
+
+ + + +
+
+ +
+ + +
+ +
+ ${this.getMainShortcuts().map(shortcut => html` +
+ ${shortcut.name} +
+ + ${shortcut.key} +
+
+ `)} +
+ + +
+
+ + My Presets + (${this.presets.filter(p => p.is_default === 0).length}) + + + ${this.showPresets ? '▼' : '▶'} + +
+ +
+ ${this.presets.filter(p => p.is_default === 0).length === 0 ? html` +
+ No custom presets yet.
+ + Create your first preset + +
+ ` : this.presets.filter(p => p.is_default === 0).map(preset => html` +
this.handlePresetSelect(preset)}> + ${preset.title} + ${this.selectedPreset?.id === preset.id ? html`Selected` : ''} +
+ `)} +
+
+ +
+ + +
+ + +
+ + + +
+ ${this.firebaseUser + ? html` + + ` + : html` + + ` + } + +
+
+
+ `; + } +} + +customElements.define('settings-view', SettingsView); \ No newline at end of file diff --git a/src/features/settings/repositories/index.js b/src/features/settings/repositories/index.js new file mode 100644 index 0000000..899e5df --- /dev/null +++ b/src/features/settings/repositories/index.js @@ -0,0 +1,23 @@ +const sqliteRepository = require('./sqlite.repository'); +// const firebaseRepository = require('./firebase.repository'); // Future implementation +const authService = require('../../../common/services/authService'); + +function getRepository() { + // In the future, we can check the user's login status from authService + // const user = authService.getCurrentUser(); + // if (user.isLoggedIn) { + // return firebaseRepository; + // } + return sqliteRepository; +} + +// Directly export functions for ease of use, decided by the strategy +module.exports = { + getSettings: (...args) => getRepository().getSettings(...args), + saveSettings: (...args) => getRepository().saveSettings(...args), + getPresets: (...args) => getRepository().getPresets(...args), + getPresetTemplates: (...args) => getRepository().getPresetTemplates(...args), + createPreset: (...args) => getRepository().createPreset(...args), + updatePreset: (...args) => getRepository().updatePreset(...args), + deletePreset: (...args) => getRepository().deletePreset(...args), +}; \ No newline at end of file diff --git a/src/features/settings/repositories/sqlite.repository.js b/src/features/settings/repositories/sqlite.repository.js new file mode 100644 index 0000000..def54cb --- /dev/null +++ b/src/features/settings/repositories/sqlite.repository.js @@ -0,0 +1,225 @@ +const sqliteClient = require('../../../common/services/sqliteClient'); + +function getSettings(uid) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = ` + SELECT * FROM user_settings + WHERE uid = ? + `; + db.get(query, [uid], (err, row) => { + if (err) { + console.error('SQLite: Failed to get settings:', err); + reject(err); + } else if (row) { + // Parse JSON fields + try { + if (row.keybinds) row.keybinds = JSON.parse(row.keybinds); + } catch (parseError) { + console.warn('SQLite: Failed to parse keybinds JSON:', parseError); + row.keybinds = {}; + } + resolve(row); + } else { + // Return default settings if none exist + resolve({ + uid: uid, + profile: 'school', + language: 'en', + screenshot_interval: '5000', + image_quality: '0.8', + layout_mode: 'stacked', + keybinds: {}, + throttle_tokens: 500, + max_tokens: 2000, + throttle_percent: 80, + google_search_enabled: 0, + background_transparency: 0.5, + font_size: 14, + content_protection: 1, + created_at: Math.floor(Date.now() / 1000), + updated_at: Math.floor(Date.now() / 1000) + }); + } + }); + }); +} + +function saveSettings(uid, settings) { + const db = sqliteClient.getDb(); + const now = Math.floor(Date.now() / 1000); + + return new Promise((resolve, reject) => { + // Prepare settings object + const settingsToSave = { + uid: uid, + profile: settings.profile || 'school', + language: settings.language || 'en', + screenshot_interval: settings.screenshot_interval || '5000', + image_quality: settings.image_quality || '0.8', + layout_mode: settings.layout_mode || 'stacked', + keybinds: JSON.stringify(settings.keybinds || {}), + throttle_tokens: settings.throttle_tokens || 500, + max_tokens: settings.max_tokens || 2000, + throttle_percent: settings.throttle_percent || 80, + google_search_enabled: settings.google_search_enabled ? 1 : 0, + background_transparency: settings.background_transparency || 0.5, + font_size: settings.font_size || 14, + content_protection: settings.content_protection ? 1 : 0, + updated_at: now + }; + + const query = ` + INSERT INTO user_settings ( + uid, profile, language, screenshot_interval, image_quality, layout_mode, + keybinds, throttle_tokens, max_tokens, throttle_percent, google_search_enabled, + background_transparency, font_size, content_protection, created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(uid) DO UPDATE SET + profile=excluded.profile, + language=excluded.language, + screenshot_interval=excluded.screenshot_interval, + image_quality=excluded.image_quality, + layout_mode=excluded.layout_mode, + keybinds=excluded.keybinds, + throttle_tokens=excluded.throttle_tokens, + max_tokens=excluded.max_tokens, + throttle_percent=excluded.throttle_percent, + google_search_enabled=excluded.google_search_enabled, + background_transparency=excluded.background_transparency, + font_size=excluded.font_size, + content_protection=excluded.content_protection, + updated_at=excluded.updated_at + `; + + const values = [ + settingsToSave.uid, + settingsToSave.profile, + settingsToSave.language, + settingsToSave.screenshot_interval, + settingsToSave.image_quality, + settingsToSave.layout_mode, + settingsToSave.keybinds, + settingsToSave.throttle_tokens, + settingsToSave.max_tokens, + settingsToSave.throttle_percent, + settingsToSave.google_search_enabled, + settingsToSave.background_transparency, + settingsToSave.font_size, + settingsToSave.content_protection, + now, // created_at + settingsToSave.updated_at + ]; + + db.run(query, values, function(err) { + if (err) { + console.error('SQLite: Failed to save settings:', err); + reject(err); + } else { + resolve({ changes: this.changes }); + } + }); + }); +} + +function getPresets(uid) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = ` + SELECT * FROM prompt_presets + WHERE uid = ? OR is_default = 1 + ORDER BY is_default DESC, title ASC + `; + db.all(query, [uid], (err, rows) => { + if (err) { + console.error('SQLite: Failed to get presets:', err); + reject(err); + } else { + resolve(rows || []); + } + }); + }); +} + +function getPresetTemplates() { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = ` + SELECT * FROM prompt_presets + WHERE is_default = 1 + ORDER BY title ASC + `; + db.all(query, [], (err, rows) => { + if (err) { + console.error('SQLite: Failed to get preset templates:', err); + reject(err); + } else { + resolve(rows || []); + } + }); + }); +} + +function createPreset({ uid, title, prompt }) { + const db = sqliteClient.getDb(); + const presetId = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = `INSERT INTO prompt_presets (id, uid, title, prompt, is_default, created_at, sync_state) VALUES (?, ?, ?, ?, 0, ?, 'dirty')`; + + return new Promise((resolve, reject) => { + db.run(query, [presetId, uid, title, prompt, now], function(err) { + if (err) { + console.error('SQLite: Failed to create preset:', err); + reject(err); + } else { + resolve({ id: presetId }); + } + }); + }); +} + +function updatePreset(id, { title, prompt }, uid) { + const db = sqliteClient.getDb(); + const query = `UPDATE prompt_presets SET title = ?, prompt = ?, sync_state = 'dirty' WHERE id = ? AND uid = ? AND is_default = 0`; + + return new Promise((resolve, reject) => { + db.run(query, [title, prompt, id, uid], function(err) { + if (err) { + console.error('SQLite: Failed to update preset:', err); + reject(err); + } else if (this.changes === 0) { + reject(new Error("Preset not found or permission denied.")); + } else { + resolve({ changes: this.changes }); + } + }); + }); +} + +function deletePreset(id, uid) { + const db = sqliteClient.getDb(); + const query = `DELETE FROM prompt_presets WHERE id = ? AND uid = ? AND is_default = 0`; + + return new Promise((resolve, reject) => { + db.run(query, [id, uid], function(err) { + if (err) { + console.error('SQLite: Failed to delete preset:', err); + reject(err); + } else if (this.changes === 0) { + reject(new Error("Preset not found or permission denied.")); + } else { + resolve({ changes: this.changes }); + } + }); + }); +} + +module.exports = { + getSettings, + saveSettings, + getPresets, + getPresetTemplates, + createPreset, + updatePreset, + deletePreset, +}; \ No newline at end of file diff --git a/src/features/settings/settingsService.js b/src/features/settings/settingsService.js new file mode 100644 index 0000000..9c6ef27 --- /dev/null +++ b/src/features/settings/settingsService.js @@ -0,0 +1,331 @@ +const { ipcMain, BrowserWindow } = require('electron'); +const authService = require('../../common/services/authService'); +const userRepository = require('../../common/repositories/user'); +const settingsRepository = require('./repositories'); +const { getStoredApiKey, getStoredProvider, windowPool } = require('../../electron/windowManager'); + +// Default keybinds configuration +const DEFAULT_KEYBINDS = { + mac: { + moveUp: 'Cmd+Up', + moveDown: 'Cmd+Down', + moveLeft: 'Cmd+Left', + moveRight: 'Cmd+Right', + toggleVisibility: 'Cmd+\\', + toggleClickThrough: 'Cmd+M', + nextStep: 'Cmd+Enter', + manualScreenshot: 'Cmd+Shift+S', + previousResponse: 'Cmd+[', + nextResponse: 'Cmd+]', + scrollUp: 'Cmd+Shift+Up', + scrollDown: 'Cmd+Shift+Down', + }, + windows: { + moveUp: 'Ctrl+Up', + moveDown: 'Ctrl+Down', + moveLeft: 'Ctrl+Left', + moveRight: 'Ctrl+Right', + toggleVisibility: 'Ctrl+\\', + toggleClickThrough: 'Ctrl+M', + nextStep: 'Ctrl+Enter', + manualScreenshot: 'Ctrl+Shift+S', + previousResponse: 'Ctrl+[', + nextResponse: 'Ctrl+]', + scrollUp: 'Ctrl+Shift+Up', + scrollDown: 'Ctrl+Shift+Down', + } +}; + +// Service state +let currentSettings = null; + +async function getSettings() { + try { + const uid = authService.getCurrentUserId(); + if (!uid) { + throw new Error("User not logged in, cannot get settings."); + } + + const settings = await settingsRepository.getSettings(uid); + currentSettings = settings; + return settings; + } catch (error) { + console.error('[SettingsService] Error getting settings:', error); + return null; + } +} + +function getDefaultSettings() { + const isMac = process.platform === 'darwin'; + return { + profile: 'school', + language: 'en', + screenshotInterval: '5000', + imageQuality: '0.8', + layoutMode: 'stacked', + keybinds: isMac ? DEFAULT_KEYBINDS.mac : DEFAULT_KEYBINDS.windows, + throttleTokens: 500, + maxTokens: 2000, + throttlePercent: 80, + googleSearchEnabled: false, + backgroundTransparency: 0.5, + fontSize: 14, + contentProtection: true + }; +} + +async function saveSettings(settings) { + try { + const uid = authService.getCurrentUserId(); + if (!uid) { + throw new Error("User not logged in, cannot save settings."); + } + + await settingsRepository.saveSettings(uid, settings); + currentSettings = settings; + return { success: true }; + } catch (error) { + console.error('[SettingsService] Error saving settings:', error); + return { success: false, error: error.message }; + } +} + +async function getPresets() { + try { + const uid = authService.getCurrentUserId(); + if (!uid) { + throw new Error("User not logged in, cannot get presets."); + } + + const presets = await settingsRepository.getPresets(uid); + return presets; + } catch (error) { + console.error('[SettingsService] Error getting presets:', error); + return []; + } +} + +async function getPresetTemplates() { + try { + const templates = await settingsRepository.getPresetTemplates(); + return templates; + } catch (error) { + console.error('[SettingsService] Error getting preset templates:', error); + return []; + } +} + +async function createPreset(title, prompt) { + try { + const uid = authService.getCurrentUserId(); + if (!uid) { + throw new Error("User not logged in, cannot create preset."); + } + + const result = await settingsRepository.createPreset({ uid, title, prompt }); + + // 모든 윈도우에 프리셋 업데이트 알림 + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send('presets-updated'); + } + }); + + return { success: true, id: result.id }; + } catch (error) { + console.error('[SettingsService] Error creating preset:', error); + return { success: false, error: error.message }; + } +} + +async function updatePreset(id, title, prompt) { + try { + const uid = authService.getCurrentUserId(); + if (!uid) { + throw new Error("User not logged in, cannot update preset."); + } + + await settingsRepository.updatePreset(id, { title, prompt }, uid); + + // 모든 윈도우에 프리셋 업데이트 알림 + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send('presets-updated'); + } + }); + + return { success: true }; + } catch (error) { + console.error('[SettingsService] Error updating preset:', error); + return { success: false, error: error.message }; + } +} + +async function deletePreset(id) { + try { + const uid = authService.getCurrentUserId(); + if (!uid) { + throw new Error("User not logged in, cannot delete preset."); + } + + await settingsRepository.deletePreset(id, uid); + + // 모든 윈도우에 프리셋 업데이트 알림 + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send('presets-updated'); + } + }); + + return { success: true }; + } catch (error) { + console.error('[SettingsService] Error deleting preset:', error); + return { success: false, error: error.message }; + } +} + +async function saveApiKey(apiKey, provider = 'openai') { + try { + const uid = authService.getCurrentUserId(); + if (!uid) { + // For non-logged-in users, save to local storage + const { app } = require('electron'); + const Store = require('electron-store'); + const store = new Store(); + store.set('apiKey', apiKey); + store.set('provider', provider); + + // Notify windows + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send('api-key-validated', apiKey); + } + }); + + return { success: true }; + } + + // For logged-in users, save to database + await userRepository.saveApiKey(apiKey, uid, provider); + + // Notify windows + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send('api-key-validated', apiKey); + } + }); + + return { success: true }; + } catch (error) { + console.error('[SettingsService] Error saving API key:', error); + return { success: false, error: error.message }; + } +} + +async function removeApiKey() { + try { + const uid = authService.getCurrentUserId(); + if (!uid) { + // For non-logged-in users, remove from local storage + const { app } = require('electron'); + const Store = require('electron-store'); + const store = new Store(); + store.delete('apiKey'); + store.delete('provider'); + } else { + // For logged-in users, remove from database + await userRepository.saveApiKey(null, uid, null); + } + + // Notify windows + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send('api-key-removed'); + } + }); + + return { success: true }; + } catch (error) { + console.error('[SettingsService] Error removing API key:', error); + return { success: false, error: error.message }; + } +} + +async function updateContentProtection(enabled) { + try { + const settings = await getSettings(); + settings.contentProtection = enabled; + + // Update content protection in main window + const { app } = require('electron'); + const mainWindow = windowPool.get('main'); + if (mainWindow && !mainWindow.isDestroyed()) { + mainWindow.setContentProtection(enabled); + } + + return await saveSettings(settings); + } catch (error) { + console.error('[SettingsService] Error updating content protection:', error); + return { success: false, error: error.message }; + } +} + +function initialize() { + // IPC handlers for settings + ipcMain.handle('settings:getSettings', async () => { + return await getSettings(); + }); + + ipcMain.handle('settings:saveSettings', async (event, settings) => { + return await saveSettings(settings); + }); + + // IPC handlers for presets + ipcMain.handle('settings:getPresets', async () => { + return await getPresets(); + }); + + ipcMain.handle('settings:getPresetTemplates', async () => { + return await getPresetTemplates(); + }); + + ipcMain.handle('settings:createPreset', async (event, title, prompt) => { + return await createPreset(title, prompt); + }); + + ipcMain.handle('settings:updatePreset', async (event, id, title, prompt) => { + return await updatePreset(id, title, prompt); + }); + + ipcMain.handle('settings:deletePreset', async (event, id) => { + return await deletePreset(id); + }); + + ipcMain.handle('settings:saveApiKey', async (event, apiKey, provider) => { + return await saveApiKey(apiKey, provider); + }); + + ipcMain.handle('settings:removeApiKey', async () => { + return await removeApiKey(); + }); + + ipcMain.handle('settings:updateContentProtection', async (event, enabled) => { + return await updateContentProtection(enabled); + }); + + console.log('[SettingsService] Initialized and ready.'); +} + +module.exports = { + initialize, + getSettings, + saveSettings, + getPresets, + getPresetTemplates, + createPreset, + updatePreset, + deletePreset, + saveApiKey, + removeApiKey, + updateContentProtection, +}; \ No newline at end of file diff --git a/src/index.js b/src/index.js index ea8224b..8f68365 100644 --- a/src/index.js +++ b/src/index.js @@ -24,6 +24,7 @@ const fetch = require('node-fetch'); const { autoUpdater } = require('electron-updater'); const { EventEmitter } = require('events'); const askService = require('./features/ask/askService'); +const settingsService = require('./features/settings/settingsService'); const sessionRepository = require('./common/repositories/session'); const eventBridge = new EventEmitter(); @@ -108,6 +109,7 @@ app.whenReady().then(async () => { authService.initialize(); setupLiveSummaryIpcHandlers(openaiSessionRef); askService.initialize(); + settingsService.initialize(); setupGeneralIpcHandlers(); }) .catch(err => { @@ -273,12 +275,30 @@ function setupWebDataHandlers() { break; case 'create-preset': result = await presetRepository.create({ ...payload, uid: currentUserId }); + // 모든 윈도우에 프리셋 업데이트 알림 + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send('presets-updated'); + } + }); break; case 'update-preset': result = await presetRepository.update(payload.id, payload.data, currentUserId); + // 모든 윈도우에 프리셋 업데이트 알림 + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send('presets-updated'); + } + }); break; case 'delete-preset': result = await presetRepository.delete(payload, currentUserId); + // 모든 윈도우에 프리셋 업데이트 알림 + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send('presets-updated'); + } + }); break; // BATCH From 401e83de6fcdb4d5a41f48d3da9daeaa5fab2508 Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Mon, 7 Jul 2025 05:56:09 +0900 Subject: [PATCH 03/52] settings big update --- src/features/settings/settingsService.js | 147 ++++++++++++++++++++--- src/index.js | 21 +--- 2 files changed, 135 insertions(+), 33 deletions(-) diff --git a/src/features/settings/settingsService.js b/src/features/settings/settingsService.js index 9c6ef27..e8df973 100644 --- a/src/features/settings/settingsService.js +++ b/src/features/settings/settingsService.js @@ -4,6 +4,109 @@ const userRepository = require('../../common/repositories/user'); const settingsRepository = require('./repositories'); const { getStoredApiKey, getStoredProvider, windowPool } = require('../../electron/windowManager'); +// Configuration constants +const NOTIFICATION_CONFIG = { + RELEVANT_WINDOW_TYPES: ['settings', 'main'], + DEBOUNCE_DELAY: 300, // prevent spam during bulk operations (ms) + MAX_RETRY_ATTEMPTS: 3, + RETRY_BASE_DELAY: 1000, // exponential backoff base (ms) +}; + +// window targeting system +class WindowNotificationManager { + constructor() { + this.pendingNotifications = new Map(); + } + + /** + * Send notifications only to relevant windows + * @param {string} event - Event name + * @param {*} data - Event data + * @param {object} options - Notification options + */ + notifyRelevantWindows(event, data = null, options = {}) { + const { + windowTypes = NOTIFICATION_CONFIG.RELEVANT_WINDOW_TYPES, + debounce = NOTIFICATION_CONFIG.DEBOUNCE_DELAY + } = options; + + if (debounce > 0) { + this.debounceNotification(event, () => { + this.sendToTargetWindows(event, data, windowTypes); + }, debounce); + } else { + this.sendToTargetWindows(event, data, windowTypes); + } + } + + sendToTargetWindows(event, data, windowTypes) { + const relevantWindows = this.getRelevantWindows(windowTypes); + + if (relevantWindows.length === 0) { + console.log(`[WindowNotificationManager] No relevant windows found for event: ${event}`); + return; + } + + console.log(`[WindowNotificationManager] Sending ${event} to ${relevantWindows.length} relevant windows`); + + relevantWindows.forEach(win => { + try { + if (data) { + win.webContents.send(event, data); + } else { + win.webContents.send(event); + } + } catch (error) { + console.warn(`[WindowNotificationManager] Failed to send ${event} to window:`, error.message); + } + }); + } + + getRelevantWindows(windowTypes) { + const allWindows = BrowserWindow.getAllWindows(); + const relevantWindows = []; + + allWindows.forEach(win => { + if (win.isDestroyed()) return; + + for (const [windowName, poolWindow] of windowPool || []) { + if (poolWindow === win && windowTypes.includes(windowName)) { + if (windowName === 'settings' || win.isVisible()) { + relevantWindows.push(win); + } + break; + } + } + }); + + return relevantWindows; + } + + debounceNotification(key, fn, delay) { + // Clear existing timeout + if (this.pendingNotifications.has(key)) { + clearTimeout(this.pendingNotifications.get(key)); + } + + // Set new timeout + const timeoutId = setTimeout(() => { + fn(); + this.pendingNotifications.delete(key); + }, delay); + + this.pendingNotifications.set(key, timeoutId); + } + + cleanup() { + // Clear all pending notifications + this.pendingNotifications.forEach(timeoutId => clearTimeout(timeoutId)); + this.pendingNotifications.clear(); + } +} + +// Global instance +const windowNotificationManager = new WindowNotificationManager(); + // Default keybinds configuration const DEFAULT_KEYBINDS = { mac: { @@ -124,11 +227,10 @@ async function createPreset(title, prompt) { const result = await settingsRepository.createPreset({ uid, title, prompt }); - // 모든 윈도우에 프리셋 업데이트 알림 - BrowserWindow.getAllWindows().forEach(win => { - if (!win.isDestroyed()) { - win.webContents.send('presets-updated'); - } + windowNotificationManager.notifyRelevantWindows('presets-updated', { + action: 'created', + presetId: result.id, + title }); return { success: true, id: result.id }; @@ -147,11 +249,10 @@ async function updatePreset(id, title, prompt) { await settingsRepository.updatePreset(id, { title, prompt }, uid); - // 모든 윈도우에 프리셋 업데이트 알림 - BrowserWindow.getAllWindows().forEach(win => { - if (!win.isDestroyed()) { - win.webContents.send('presets-updated'); - } + windowNotificationManager.notifyRelevantWindows('presets-updated', { + action: 'updated', + presetId: id, + title }); return { success: true }; @@ -170,11 +271,9 @@ async function deletePreset(id) { await settingsRepository.deletePreset(id, uid); - // 모든 윈도우에 프리셋 업데이트 알림 - BrowserWindow.getAllWindows().forEach(win => { - if (!win.isDestroyed()) { - win.webContents.send('presets-updated'); - } + windowNotificationManager.notifyRelevantWindows('presets-updated', { + action: 'deleted', + presetId: id }); return { success: true }; @@ -271,6 +370,9 @@ async function updateContentProtection(enabled) { } function initialize() { + // cleanup + windowNotificationManager.cleanup(); + // IPC handlers for settings ipcMain.handle('settings:getSettings', async () => { return await getSettings(); @@ -316,8 +418,23 @@ function initialize() { console.log('[SettingsService] Initialized and ready.'); } +// Cleanup function +function cleanup() { + windowNotificationManager.cleanup(); + console.log('[SettingsService] Cleaned up resources.'); +} + +function notifyPresetUpdate(action, presetId, title = null) { + const data = { action, presetId }; + if (title) data.title = title; + + windowNotificationManager.notifyRelevantWindows('presets-updated', data); +} + module.exports = { initialize, + cleanup, + notifyPresetUpdate, getSettings, saveSettings, getPresets, diff --git a/src/index.js b/src/index.js index 8f68365..5c4a3ff 100644 --- a/src/index.js +++ b/src/index.js @@ -275,30 +275,15 @@ function setupWebDataHandlers() { break; case 'create-preset': result = await presetRepository.create({ ...payload, uid: currentUserId }); - // 모든 윈도우에 프리셋 업데이트 알림 - BrowserWindow.getAllWindows().forEach(win => { - if (!win.isDestroyed()) { - win.webContents.send('presets-updated'); - } - }); + settingsService.notifyPresetUpdate('created', result.id, payload.title); break; case 'update-preset': result = await presetRepository.update(payload.id, payload.data, currentUserId); - // 모든 윈도우에 프리셋 업데이트 알림 - BrowserWindow.getAllWindows().forEach(win => { - if (!win.isDestroyed()) { - win.webContents.send('presets-updated'); - } - }); + settingsService.notifyPresetUpdate('updated', payload.id, payload.data.title); break; case 'delete-preset': result = await presetRepository.delete(payload, currentUserId); - // 모든 윈도우에 프리셋 업데이트 알림 - BrowserWindow.getAllWindows().forEach(win => { - if (!win.isDestroyed()) { - win.webContents.send('presets-updated'); - } - }); + settingsService.notifyPresetUpdate('deleted', payload); break; // BATCH From 80a3c016560ddbec8e5a3658605821a1a6ab008e Mon Sep 17 00:00:00 2001 From: samtiz Date: Mon, 7 Jul 2025 06:01:17 +0900 Subject: [PATCH 04/52] WIP: refactoring listen --- src/app/PickleGlassApp.js | 3 +- src/electron/windowManager.js | 6 +- src/features/ask/askService.js | 7 +- src/features/listen/audioUtils.js | 123 --- src/features/listen/listenService.js | 263 +++++ src/features/listen/liveSummaryService.js | 973 ------------------ .../listenCapture.js} | 604 +++++------ src/features/listen/renderer/renderer.js | 139 +++ src/features/listen/stt/repositories/index.js | 5 + .../stt/repositories/sqlite.repository.js | 37 + src/features/listen/stt/sttService.js | 480 +++++++++ .../listen/summary/repositories/index.js | 5 + .../summary/repositories/sqlite.repository.js | 47 + src/features/listen/summary/summaryService.js | 357 +++++++ src/index.js | 19 +- 15 files changed, 1607 insertions(+), 1461 deletions(-) delete mode 100644 src/features/listen/audioUtils.js create mode 100644 src/features/listen/listenService.js delete mode 100644 src/features/listen/liveSummaryService.js rename src/features/listen/{renderer.js => renderer/listenCapture.js} (80%) create mode 100644 src/features/listen/renderer/renderer.js create mode 100644 src/features/listen/stt/repositories/index.js create mode 100644 src/features/listen/stt/repositories/sqlite.repository.js create mode 100644 src/features/listen/stt/sttService.js create mode 100644 src/features/listen/summary/repositories/index.js create mode 100644 src/features/listen/summary/repositories/sqlite.repository.js create mode 100644 src/features/listen/summary/summaryService.js diff --git a/src/app/PickleGlassApp.js b/src/app/PickleGlassApp.js index eb639eb..96d0516 100644 --- a/src/app/PickleGlassApp.js +++ b/src/app/PickleGlassApp.js @@ -1,10 +1,9 @@ import { html, css, LitElement } from '../assets/lit-core-2.7.4.min.js'; import { CustomizeView } from '../features/customize/CustomizeView.js'; import { AssistantView } from '../features/listen/AssistantView.js'; -import { OnboardingView } from '../features/onboarding/OnboardingView.js'; import { AskView } from '../features/ask/AskView.js'; -import '../features/listen/renderer.js'; +import '../features/listen/renderer/renderer.js'; export class PickleGlassApp extends LitElement { static styles = css` diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 586e3f8..e4cc058 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -1024,10 +1024,10 @@ function createWindows() { if (windowToToggle) { if (featureName === 'listen') { - const liveSummaryService = require('../features/listen/liveSummaryService'); - if (liveSummaryService.isSessionActive()) { + const listenService = global.listenService; + if (listenService && listenService.isSessionActive()) { console.log('[WindowManager] Listen session is active, closing it via toggle.'); - await liveSummaryService.closeSession(); + await listenService.closeSession(); return; } } diff --git a/src/features/ask/askService.js b/src/features/ask/askService.js index 04c64d9..d07d79d 100644 --- a/src/features/ask/askService.js +++ b/src/features/ask/askService.js @@ -1,6 +1,5 @@ const { ipcMain, BrowserWindow } = require('electron'); const { makeStreamingChatCompletionWithPortkey } = require('../../common/services/aiProviderService'); -const { getConversationHistory } = require('../listen/liveSummaryService'); const { getStoredApiKey, getStoredProvider, windowPool, captureScreenshot } = require('../../electron/windowManager'); const authService = require('../../common/services/authService'); const sessionRepository = require('../../common/repositories/session'); @@ -174,6 +173,12 @@ function formatConversationForPrompt(conversationTexts) { return conversationTexts.slice(-30).join('\n'); } +// Access conversation history via the global listenService instance created in index.js +function getConversationHistory() { + const listenService = global.listenService; + return listenService ? listenService.getConversationHistory() : []; +} + async function sendMessage(userPrompt) { if (!userPrompt || userPrompt.trim().length === 0) { console.warn('[AskService] Cannot process empty message'); diff --git a/src/features/listen/audioUtils.js b/src/features/listen/audioUtils.js deleted file mode 100644 index 25dfb9d..0000000 --- a/src/features/listen/audioUtils.js +++ /dev/null @@ -1,123 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -function pcmToWav(pcmBuffer, outputPath, sampleRate = 24000, channels = 1, bitDepth = 16) { - const byteRate = sampleRate * channels * (bitDepth / 8); - const blockAlign = channels * (bitDepth / 8); - const dataSize = pcmBuffer.length; - - const header = Buffer.alloc(44); - - header.write('RIFF', 0); - header.writeUInt32LE(dataSize + 36, 4); - header.write('WAVE', 8); - - header.write('fmt ', 12); - header.writeUInt32LE(16, 16); - header.writeUInt16LE(1, 20); - header.writeUInt16LE(channels, 22); - header.writeUInt32LE(sampleRate, 24); - header.writeUInt32LE(byteRate, 28); - header.writeUInt16LE(blockAlign, 32); - header.writeUInt16LE(bitDepth, 34); - - header.write('data', 36); - header.writeUInt32LE(dataSize, 40); - - const wavBuffer = Buffer.concat([header, pcmBuffer]); - - fs.writeFileSync(outputPath, wavBuffer); - - return outputPath; -} - -function analyzeAudioBuffer(buffer, label = 'Audio') { - const int16Array = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.length / 2); - - let minValue = 32767; - let maxValue = -32768; - let avgValue = 0; - let rmsValue = 0; - let silentSamples = 0; - - for (let i = 0; i < int16Array.length; i++) { - const sample = int16Array[i]; - minValue = Math.min(minValue, sample); - maxValue = Math.max(maxValue, sample); - avgValue += sample; - rmsValue += sample * sample; - - if (Math.abs(sample) < 100) { - silentSamples++; - } - } - - avgValue /= int16Array.length; - rmsValue = Math.sqrt(rmsValue / int16Array.length); - - const silencePercentage = (silentSamples / int16Array.length) * 100; - - console.log(`${label} Analysis:`); - console.log(` Samples: ${int16Array.length}`); - console.log(` Min: ${minValue}, Max: ${maxValue}`); - console.log(` Average: ${avgValue.toFixed(2)}`); - console.log(` RMS: ${rmsValue.toFixed(2)}`); - console.log(` Silence: ${silencePercentage.toFixed(1)}%`); - console.log(` Dynamic Range: ${20 * Math.log10(maxValue / (rmsValue || 1))} dB`); - - return { - minValue, - maxValue, - avgValue, - rmsValue, - silencePercentage, - sampleCount: int16Array.length, - }; -} - -function saveDebugAudio(buffer, type, timestamp = Date.now()) { - const homeDir = require('os').homedir(); - const debugDir = path.join(homeDir, '.pickle-glass', 'debug'); - - if (!fs.existsSync(debugDir)) { - fs.mkdirSync(debugDir, { recursive: true }); - } - - const pcmPath = path.join(debugDir, `${type}_${timestamp}.pcm`); - const wavPath = path.join(debugDir, `${type}_${timestamp}.wav`); - const metaPath = path.join(debugDir, `${type}_${timestamp}.json`); - - fs.writeFileSync(pcmPath, buffer); - - pcmToWav(buffer, wavPath); - - const analysis = analyzeAudioBuffer(buffer, type); - fs.writeFileSync( - metaPath, - JSON.stringify( - { - timestamp, - type, - bufferSize: buffer.length, - analysis, - format: { - sampleRate: 24000, - channels: 1, - bitDepth: 16, - }, - }, - null, - 2 - ) - ); - - console.log(`Debug audio saved: ${wavPath}`); - - return { pcmPath, wavPath, metaPath }; -} - -module.exports = { - pcmToWav, - analyzeAudioBuffer, - saveDebugAudio, -}; diff --git a/src/features/listen/listenService.js b/src/features/listen/listenService.js new file mode 100644 index 0000000..a0dcde8 --- /dev/null +++ b/src/features/listen/listenService.js @@ -0,0 +1,263 @@ +const { BrowserWindow } = require('electron'); +const SttService = require('./stt/sttService'); +const SummaryService = require('./summary/summaryService'); +const authService = require('../../common/services/authService'); +const sessionRepository = require('../../common/repositories/session'); +const sttRepository = require('./stt/repositories'); + +class ListenService { + constructor() { + this.sttService = new SttService(); + this.summaryService = new SummaryService(); + this.currentSessionId = null; + this.isInitializingSession = false; + + this.setupServiceCallbacks(); + } + + setupServiceCallbacks() { + // STT service callbacks + this.sttService.setCallbacks({ + onTranscriptionComplete: (speaker, text) => { + this.handleTranscriptionComplete(speaker, text); + }, + onStatusUpdate: (status) => { + this.sendToRenderer('update-status', status); + } + }); + + // Summary service callbacks + this.summaryService.setCallbacks({ + onAnalysisComplete: (data) => { + console.log('📊 Analysis completed:', data); + }, + onStatusUpdate: (status) => { + this.sendToRenderer('update-status', status); + } + }); + } + + sendToRenderer(channel, data) { + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send(channel, data); + } + }); + } + + async handleTranscriptionComplete(speaker, text) { + console.log(`[ListenService] Transcription complete: ${speaker} - ${text}`); + + // Save to database + await this.saveConversationTurn(speaker, text); + + // Add to summary service for analysis + this.summaryService.addConversationTurn(speaker, text); + } + + async saveConversationTurn(speaker, transcription) { + if (!this.currentSessionId) { + console.error('[DB] Cannot save turn, no active session ID.'); + return; + } + if (transcription.trim() === '') return; + + try { + await sessionRepository.touch(this.currentSessionId); + await sttRepository.addTranscript({ + sessionId: this.currentSessionId, + speaker: speaker, + text: transcription.trim(), + }); + console.log(`[DB] Saved transcript for session ${this.currentSessionId}: (${speaker})`); + } catch (error) { + console.error('Failed to save transcript to DB:', error); + } + } + + async initializeNewSession() { + try { + const uid = authService.getCurrentUserId(); + if (!uid) { + throw new Error("Cannot initialize session: user not logged in."); + } + + this.currentSessionId = await sessionRepository.getOrCreateActive(uid, 'listen'); + console.log(`[DB] New listen session ensured: ${this.currentSessionId}`); + + // Set session ID for summary service + this.summaryService.setSessionId(this.currentSessionId); + + // Reset conversation history + this.summaryService.resetConversationHistory(); + + console.log('New conversation session started:', this.currentSessionId); + return true; + } catch (error) { + console.error('Failed to initialize new session in DB:', error); + this.currentSessionId = null; + return false; + } + } + + async initializeSession(language = 'en') { + if (this.isInitializingSession) { + console.log('Session initialization already in progress.'); + return false; + } + + this.isInitializingSession = true; + this.sendToRenderer('session-initializing', true); + this.sendToRenderer('update-status', 'Initializing sessions...'); + + try { + // Initialize database session + const sessionInitialized = await this.initializeNewSession(); + if (!sessionInitialized) { + throw new Error('Failed to initialize database session'); + } + + // Initialize STT sessions + await this.sttService.initializeSttSessions(language); + + console.log('✅ Listen service initialized successfully.'); + + this.sendToRenderer('session-state-changed', { isActive: true }); + this.sendToRenderer('update-status', 'Connected. Ready to listen.'); + + return true; + } catch (error) { + console.error('❌ Failed to initialize listen service:', error); + this.sendToRenderer('update-status', 'Initialization failed.'); + return false; + } finally { + this.isInitializingSession = false; + this.sendToRenderer('session-initializing', false); + } + } + + async sendAudioContent(data, mimeType) { + return await this.sttService.sendAudioContent(data, mimeType); + } + + async startMacOSAudioCapture() { + if (process.platform !== 'darwin') { + throw new Error('macOS audio capture only available on macOS'); + } + return await this.sttService.startMacOSAudioCapture(); + } + + async stopMacOSAudioCapture() { + this.sttService.stopMacOSAudioCapture(); + } + + isSessionActive() { + return this.sttService.isSessionActive(); + } + + async closeSession() { + try { + // Close STT sessions + await this.sttService.closeSessions(); + + // End database session + if (this.currentSessionId) { + await sessionRepository.end(this.currentSessionId); + console.log(`[DB] Session ${this.currentSessionId} ended.`); + } + + // Reset state + this.currentSessionId = null; + this.summaryService.resetConversationHistory(); + + this.sendToRenderer('session-state-changed', { isActive: false }); + this.sendToRenderer('session-did-close'); + + console.log('Listen service session closed.'); + return { success: true }; + } catch (error) { + console.error('Error closing listen service session:', error); + return { success: false, error: error.message }; + } + } + + getCurrentSessionData() { + return { + sessionId: this.currentSessionId, + conversationHistory: this.summaryService.getConversationHistory(), + totalTexts: this.summaryService.getConversationHistory().length, + analysisData: this.summaryService.getCurrentAnalysisData(), + }; + } + + getConversationHistory() { + return this.summaryService.getConversationHistory(); + } + + setupIpcHandlers() { + const { ipcMain } = require('electron'); + + ipcMain.handle('is-session-active', async () => { + const isActive = this.isSessionActive(); + console.log(`Checking session status. Active: ${isActive}`); + return isActive; + }); + + ipcMain.handle('initialize-openai', async (event, profile = 'interview', language = 'en') => { + console.log(`Received initialize-openai request with profile: ${profile}, language: ${language}`); + const success = await this.initializeSession(language); + return success; + }); + + ipcMain.handle('send-audio-content', async (event, { data, mimeType }) => { + try { + await this.sendAudioContent(data, mimeType); + return { success: true }; + } catch (error) { + console.error('Error sending user audio:', error); + return { success: false, error: error.message }; + } + }); + + ipcMain.handle('start-macos-audio', async () => { + if (process.platform !== 'darwin') { + return { success: false, error: 'macOS audio capture only available on macOS' }; + } + try { + const success = await this.startMacOSAudioCapture(); + return { success }; + } catch (error) { + console.error('Error starting macOS audio capture:', error); + return { success: false, error: error.message }; + } + }); + + ipcMain.handle('stop-macos-audio', async () => { + try { + this.stopMacOSAudioCapture(); + return { success: true }; + } catch (error) { + console.error('Error stopping macOS audio capture:', error); + return { success: false, error: error.message }; + } + }); + + ipcMain.handle('close-session', async () => { + return await this.closeSession(); + }); + + ipcMain.handle('update-google-search-setting', async (event, enabled) => { + try { + console.log('Google Search setting updated to:', enabled); + return { success: true }; + } catch (error) { + console.error('Error updating Google Search setting:', error); + return { success: false, error: error.message }; + } + }); + + console.log('✅ Listen service IPC handlers registered'); + } +} + +module.exports = ListenService; \ No newline at end of file diff --git a/src/features/listen/liveSummaryService.js b/src/features/listen/liveSummaryService.js deleted file mode 100644 index b892f66..0000000 --- a/src/features/listen/liveSummaryService.js +++ /dev/null @@ -1,973 +0,0 @@ -require('dotenv').config(); -const { BrowserWindow, ipcMain } = require('electron'); -const { spawn } = require('child_process'); -const { saveDebugAudio } = require('./audioUtils.js'); -const { getSystemPrompt } = require('../../common/prompts/promptBuilder.js'); -const { connectToGeminiSession } = require('../../common/services/googleGeminiClient.js'); -const { connectToOpenAiSession, createOpenAiGenerativeClient, getOpenAiGenerativeModel } = require('../../common/services/openAiClient.js'); -const { makeChatCompletionWithPortkey } = require('../../common/services/aiProviderService.js'); -const authService = require('../../common/services/authService'); -const sessionRepository = require('../../common/repositories/session'); -const listenRepository = require('./repositories'); - -const { getStoredApiKey, getStoredProvider } = require('../../electron/windowManager'); - -const MAX_BUFFER_LENGTH_CHARS = 2000; -const COMPLETION_DEBOUNCE_MS = 2000; - -async function getApiKey() { - const storedKey = await getStoredApiKey(); - - if (storedKey) { - console.log('[LiveSummaryService] Using stored API key'); - return storedKey; - } - - const envKey = process.env.OPENAI_API_KEY; - if (envKey) { - console.log('[LiveSummaryService] Using environment API key'); - return envKey; - } - - console.error('[LiveSummaryService] No API key found in storage or environment'); - return null; -} - -async function getAiProvider() { - try { - const { ipcRenderer } = require('electron'); - const provider = await ipcRenderer.invoke('get-ai-provider'); - return provider || 'openai'; - } catch (error) { - // If we're in the main process, get it directly - return getStoredProvider ? getStoredProvider() : 'openai'; - } -} - -let currentSessionId = null; -let conversationHistory = []; -let isInitializingSession = false; - -let mySttSession = null; -let theirSttSession = null; -let myCurrentUtterance = ''; -let theirCurrentUtterance = ''; - -let myLastPartialText = ''; -let theirLastPartialText = ''; -let myInactivityTimer = null; -let theirInactivityTimer = null; -const INACTIVITY_TIMEOUT = 3000; - -const SESSION_IDLE_TIMEOUT_SECONDS = 30 * 60; // 30 minutes - -let previousAnalysisResult = null; -let analysisHistory = []; - -// --------------------------------------------------------------------------- -// 🎛️ Turn-completion debouncing -// --------------------------------------------------------------------------- -// Very aggressive VAD (e.g. 50 ms) tends to split one spoken sentence into -// many "completed" events. To avoid creating a separate chat bubble for each -// of those micro-turns we debounce the *completed* events per speaker. Any -// completions that arrive within this window are concatenated and flushed as -// **one** final turn. - -let myCompletionBuffer = ''; -let theirCompletionBuffer = ''; -let myCompletionTimer = null; -let theirCompletionTimer = null; - -function flushMyCompletion() { - if (!myCompletionBuffer.trim()) return; - - const finalText = myCompletionBuffer.trim(); - // Save to DB & send to renderer as final - saveConversationTurn('Me', finalText); - sendToRenderer('stt-update', { - speaker: 'Me', - text: finalText, - isPartial: false, - isFinal: true, - timestamp: Date.now(), - }); - - myCompletionBuffer = ''; - myCompletionTimer = null; - myCurrentUtterance = ''; // Reset utterance accumulator on flush - sendToRenderer('update-status', 'Listening...'); -} - -function flushTheirCompletion() { - if (!theirCompletionBuffer.trim()) return; - - const finalText = theirCompletionBuffer.trim(); - saveConversationTurn('Them', finalText); - sendToRenderer('stt-update', { - speaker: 'Them', - text: finalText, - isPartial: false, - isFinal: true, - timestamp: Date.now(), - }); - - theirCompletionBuffer = ''; - theirCompletionTimer = null; - theirCurrentUtterance = ''; // Reset utterance accumulator on flush - sendToRenderer('update-status', 'Listening...'); -} - -function debounceMyCompletion(text) { - // 상대방이 말하고 있던 경우, 화자가 변경되었으므로 즉시 상대방의 말풍선을 완성합니다. - if (theirCompletionTimer) { - clearTimeout(theirCompletionTimer); - flushTheirCompletion(); - } - - myCompletionBuffer += (myCompletionBuffer ? ' ' : '') + text; - - if (myCompletionTimer) clearTimeout(myCompletionTimer); - myCompletionTimer = setTimeout(flushMyCompletion, COMPLETION_DEBOUNCE_MS); -} - -function debounceTheirCompletion(text) { - // 내가 말하고 있던 경우, 화자가 변경되었으므로 즉시 내 말풍선을 완성합니다. - if (myCompletionTimer) { - clearTimeout(myCompletionTimer); - flushMyCompletion(); - } - - theirCompletionBuffer += (theirCompletionBuffer ? ' ' : '') + text; - - if (theirCompletionTimer) clearTimeout(theirCompletionTimer); - theirCompletionTimer = setTimeout(flushTheirCompletion, COMPLETION_DEBOUNCE_MS); -} - -let systemAudioProc = null; - -let analysisIntervalId = null; - -/** - * Converts conversation history into text to include in the prompt. - * @param {Array} conversationTexts - Array of conversation texts ["me: ~~~", "them: ~~~", ...] - * @param {number} maxTurns - Maximum number of recent turns to include - * @returns {string} - Formatted conversation string for the prompt - */ -function formatConversationForPrompt(conversationTexts, maxTurns = 30) { - if (conversationTexts.length === 0) return ''; - return conversationTexts.slice(-maxTurns).join('\n'); -} - -async function makeOutlineAndRequests(conversationTexts, maxTurns = 30) { - console.log(`🔍 makeOutlineAndRequests called - conversationTexts: ${conversationTexts.length}`); - - if (conversationTexts.length === 0) { - console.log('⚠️ No conversation texts available for analysis'); - return null; - } - - const recentConversation = formatConversationForPrompt(conversationTexts, maxTurns); - - // 이전 분석 결과를 프롬프트에 포함 - let contextualPrompt = ''; - if (previousAnalysisResult) { - contextualPrompt = ` -Previous Analysis Context: -- Main Topic: ${previousAnalysisResult.topic.header} -- Key Points: ${previousAnalysisResult.summary.slice(0, 3).join(', ')} -- Last Actions: ${previousAnalysisResult.actions.slice(0, 2).join(', ')} - -Please build upon this context while analyzing the new conversation segments. -`; - } - - const basePrompt = getSystemPrompt('pickle_glass_analysis', '', false); - const systemPrompt = basePrompt.replace('{{CONVERSATION_HISTORY}}', recentConversation); - - try { - if (currentSessionId) { - await sessionRepository.touch(currentSessionId); - } - const messages = [ - { - role: 'system', - content: systemPrompt, - }, - { - role: 'user', - content: `${contextualPrompt} - -Analyze the conversation and provide a structured summary. Format your response as follows: - -**Summary Overview** -- Main discussion point with context - -**Key Topic: [Topic Name]** -- First key insight -- Second key insight -- Third key insight - -**Extended Explanation** -Provide 2-3 sentences explaining the context and implications. - -**Suggested Questions** -1. First follow-up question? -2. Second follow-up question? -3. Third follow-up question? - -Keep all points concise and build upon previous analysis if provided.`, - }, - ]; - - console.log('🤖 Sending analysis request to OpenAI...'); - - const API_KEY = await getApiKey(); - if (!API_KEY) { - throw new Error('No API key available'); - } - - const provider = getStoredProvider ? getStoredProvider() : 'openai'; - const loggedIn = authService.getCurrentUser().isLoggedIn; // true ➜ vKey, false ➜ apiKey - const usePortkey = loggedIn && provider === 'openai'; // Only use Portkey for OpenAI with Firebase - - console.log(`[LiveSummary] provider: ${provider}, usePortkey: ${usePortkey}`); - - const completion = await makeChatCompletionWithPortkey({ - apiKey: API_KEY, - provider: provider, - messages: messages, - temperature: 0.7, - maxTokens: 1024, - model: provider === 'openai' ? 'gpt-4.1' : 'gemini-2.5-flash', - usePortkey: usePortkey, - portkeyVirtualKey: usePortkey ? API_KEY : null - }); - - const responseText = completion.content; - console.log(`✅ Analysis response received: ${responseText}`); - const structuredData = parseResponseText(responseText, previousAnalysisResult); - - if (currentSessionId) { - listenRepository.saveSummary({ - sessionId: currentSessionId, - tldr: structuredData.summary.join('\n'), - bullet_json: JSON.stringify(structuredData.topic.bullets), - action_json: JSON.stringify(structuredData.actions), - model: 'gpt-4.1' - }).catch(err => console.error('[DB] Failed to save summary:', err)); - } - - // 분석 결과 저장 - previousAnalysisResult = structuredData; - analysisHistory.push({ - timestamp: Date.now(), - data: structuredData, - conversationLength: conversationTexts.length, - }); - - // 히스토리 크기 제한 (최근 10개만 유지) - if (analysisHistory.length > 10) { - analysisHistory.shift(); - } - - return structuredData; - } catch (error) { - console.error('❌ Error during analysis generation:', error.message); - return previousAnalysisResult; // 에러 시 이전 결과 반환 - } -} - -function parseResponseText(responseText, previousResult) { - const structuredData = { - summary: [], - topic: { header: '', bullets: [] }, - actions: [], - followUps: ['✉️ Draft a follow-up email', '✅ Generate action items', '📝 Show summary'], - }; - - // 이전 결과가 있으면 기본값으로 사용 - if (previousResult) { - structuredData.topic.header = previousResult.topic.header; - structuredData.summary = [...previousResult.summary]; - } - - try { - const lines = responseText.split('\n'); - let currentSection = ''; - let isCapturingTopic = false; - let topicName = ''; - - for (const line of lines) { - const trimmedLine = line.trim(); - - // 섹션 헤더 감지 - if (trimmedLine.startsWith('**Summary Overview**')) { - currentSection = 'summary-overview'; - continue; - } else if (trimmedLine.startsWith('**Key Topic:')) { - currentSection = 'topic'; - isCapturingTopic = true; - topicName = trimmedLine.match(/\*\*Key Topic: (.+?)\*\*/)?.[1] || ''; - if (topicName) { - structuredData.topic.header = topicName + ':'; - } - continue; - } else if (trimmedLine.startsWith('**Extended Explanation**')) { - currentSection = 'explanation'; - continue; - } else if (trimmedLine.startsWith('**Suggested Questions**')) { - currentSection = 'questions'; - continue; - } - - // 컨텐츠 파싱 - if (trimmedLine.startsWith('-') && currentSection === 'summary-overview') { - const summaryPoint = trimmedLine.substring(1).trim(); - if (summaryPoint && !structuredData.summary.includes(summaryPoint)) { - // 기존 summary 업데이트 (최대 5개 유지) - structuredData.summary.unshift(summaryPoint); - if (structuredData.summary.length > 5) { - structuredData.summary.pop(); - } - } - } else if (trimmedLine.startsWith('-') && currentSection === 'topic') { - const bullet = trimmedLine.substring(1).trim(); - if (bullet && structuredData.topic.bullets.length < 3) { - structuredData.topic.bullets.push(bullet); - } - } else if (currentSection === 'explanation' && trimmedLine) { - // explanation을 topic bullets에 추가 (문장 단위로) - const sentences = trimmedLine - .split(/\.\s+/) - .filter(s => s.trim().length > 0) - .map(s => s.trim() + (s.endsWith('.') ? '' : '.')); - - sentences.forEach(sentence => { - if (structuredData.topic.bullets.length < 3 && !structuredData.topic.bullets.includes(sentence)) { - structuredData.topic.bullets.push(sentence); - } - }); - } else if (trimmedLine.match(/^\d+\./) && currentSection === 'questions') { - const question = trimmedLine.replace(/^\d+\.\s*/, '').trim(); - if (question && question.includes('?')) { - structuredData.actions.push(`❓ ${question}`); - } - } - } - - // 기본 액션 추가 - const defaultActions = ['✨ What should I say next?', '💬 Suggest follow-up questions']; - defaultActions.forEach(action => { - if (!structuredData.actions.includes(action)) { - structuredData.actions.push(action); - } - }); - - // 액션 개수 제한 - structuredData.actions = structuredData.actions.slice(0, 5); - - // 유효성 검증 및 이전 데이터 병합 - if (structuredData.summary.length === 0 && previousResult) { - structuredData.summary = previousResult.summary; - } - if (structuredData.topic.bullets.length === 0 && previousResult) { - structuredData.topic.bullets = previousResult.topic.bullets; - } - } catch (error) { - console.error('❌ Error parsing response text:', error); - // 에러 시 이전 결과 반환 - return ( - previousResult || { - summary: [], - topic: { header: 'Analysis in progress', bullets: [] }, - actions: ['✨ What should I say next?', '💬 Suggest follow-up questions'], - followUps: ['✉️ Draft a follow-up email', '✅ Generate action items', '📝 Show summary'], - } - ); - } - - console.log('📊 Final structured data:', JSON.stringify(structuredData, null, 2)); - return structuredData; -} - -/** - * Triggers analysis when conversation history reaches 5 texts. - */ -async function triggerAnalysisIfNeeded() { - if (conversationHistory.length >= 5 && conversationHistory.length % 5 === 0) { - console.log(`🚀 Triggering analysis (non-blocking) - ${conversationHistory.length} conversation texts accumulated`); - - makeOutlineAndRequests(conversationHistory) - .then(data => { - if (data) { - console.log('📤 Sending structured data to renderer'); - sendToRenderer('update-structured-data', data); - } else { - console.log('❌ No analysis data returned from non-blocking call'); - } - }) - .catch(error => { - console.error('❌ Error in non-blocking analysis:', error); - }); - } -} - -/** - * Schedules periodic updates of outline and analysis every 10 seconds. - DEPRECATED - * Now analysis is triggered every 5 conversation texts. - */ -function startAnalysisInterval() { - console.log('⏰ Analysis will be triggered every 5 conversation texts (not on timer)'); - - if (analysisIntervalId) { - clearInterval(analysisIntervalId); - analysisIntervalId = null; - } -} - -function stopAnalysisInterval() { - if (analysisIntervalId) { - clearInterval(analysisIntervalId); - analysisIntervalId = null; - } - - if (myInactivityTimer) { - clearTimeout(myInactivityTimer); - myInactivityTimer = null; - } - if (theirInactivityTimer) { - clearTimeout(theirInactivityTimer); - theirInactivityTimer = null; - } -} - -function sendToRenderer(channel, data) { - BrowserWindow.getAllWindows().forEach(win => { - if (!win.isDestroyed()) { - win.webContents.send(channel, data); - } - }); -} - -function getCurrentSessionData() { - return { - sessionId: currentSessionId, - conversationHistory: conversationHistory, - totalTexts: conversationHistory.length, - }; -} - -// Conversation management functions -async function initializeNewSession() { - try { - const uid = authService.getCurrentUserId(); - if (!uid) { - throw new Error("Cannot initialize session: user not logged in."); - } - currentSessionId = await sessionRepository.getOrCreateActive(uid, 'listen'); - console.log(`[DB] New listen session ensured: ${currentSessionId}`); - - conversationHistory = []; - myCurrentUtterance = ''; - theirCurrentUtterance = ''; - - // 🔄 Reset analysis state so the new session starts fresh - previousAnalysisResult = null; - analysisHistory = []; - - // sendToRenderer('update-outline', []); - // sendToRenderer('update-analysis-requests', []); - - myLastPartialText = ''; - theirLastPartialText = ''; - if (myInactivityTimer) { - clearTimeout(myInactivityTimer); - myInactivityTimer = null; - } - if (theirInactivityTimer) { - clearTimeout(theirInactivityTimer); - theirInactivityTimer = null; - } - - console.log('New conversation session started:', currentSessionId); - return true; - } catch (error) { - console.error('Failed to initialize new session in DB:', error); - currentSessionId = null; - return false; - } -} - -async function saveConversationTurn(speaker, transcription) { - if (!currentSessionId) { - console.error('[DB] Cannot save turn, no active session ID.'); - return; - } - if (transcription.trim() === '') return; - - try { - await sessionRepository.touch(currentSessionId); - await listenRepository.addTranscript({ - sessionId: currentSessionId, - speaker: speaker, - text: transcription.trim(), - }); - console.log(`[DB] Saved transcript for session ${currentSessionId}: (${speaker})`); - - const conversationText = `${speaker.toLowerCase()}: ${transcription.trim()}`; - conversationHistory.push(conversationText); - console.log(`💬 Saved conversation text: ${conversationText}`); - console.log(`📈 Total conversation history: ${conversationHistory.length} texts`); - - triggerAnalysisIfNeeded(); - - const conversationTurn = { - speaker: speaker, - timestamp: Date.now(), - transcription: transcription.trim(), - }; - } catch (error) { - console.error('Failed to save transcript to DB:', error); - } -} - -async function initializeLiveSummarySession(language = 'en') { - // Use system environment variable if set, otherwise use the provided language - const effectiveLanguage = process.env.OPENAI_TRANSCRIBE_LANG || language || 'en'; - if (isInitializingSession) { - console.log('Session initialization already in progress.'); - return false; - } - - const userState = authService.getCurrentUser(); - const loggedIn = userState.isLoggedIn; - const keyType = loggedIn ? 'vKey' : 'apiKey'; - - isInitializingSession = true; - sendToRenderer('session-initializing', true); - sendToRenderer('update-status', 'Initializing sessions...'); - - const API_KEY = await getApiKey(); - if (!API_KEY) { - console.error('FATAL ERROR: API Key is not defined.'); - sendToRenderer('update-status', 'API Key not configured.'); - isInitializingSession = false; - sendToRenderer('session-initializing', false); - return false; - } - - await initializeNewSession(); - - const provider = await getAiProvider(); - const isGemini = provider === 'gemini'; - console.log(`[LiveSummaryService] Initializing STT for provider: ${provider}`); - - try { - const handleMyMessage = message => { - if (isGemini) { - // console.log('[Gemini Raw Message - Me]:', JSON.stringify(message, null, 2)); - const text = message.serverContent?.inputTranscription?.text || ''; - if (text && text.trim()) { - const finalUtteranceText = text.trim().replace(//g, '').trim(); - if (finalUtteranceText && finalUtteranceText !== '.') { - debounceMyCompletion(finalUtteranceText); - } - } - } else { - const type = message.type; - const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || ''; - - if (type === 'conversation.item.input_audio_transcription.delta') { - if (myCompletionTimer) clearTimeout(myCompletionTimer); - myCompletionTimer = null; - myCurrentUtterance += text; - const continuousText = myCompletionBuffer + (myCompletionBuffer ? ' ' : '') + myCurrentUtterance; - if (text && !text.includes('vq_lbr_audio_')) { - sendToRenderer('stt-update', { - speaker: 'Me', - text: continuousText, - isPartial: true, - isFinal: false, - timestamp: Date.now(), - }); - } - } else if (type === 'conversation.item.input_audio_transcription.completed') { - if (text && text.trim()) { - const finalUtteranceText = text.trim(); - myCurrentUtterance = ''; - debounceMyCompletion(finalUtteranceText); - } - } - } - - if (message.error) { - console.error('[Me] STT Session Error:', message.error); - } - }; - - const handleTheirMessage = message => { - if (isGemini) { - // console.log('[Gemini Raw Message - Them]:', JSON.stringify(message, null, 2)); - const text = message.serverContent?.inputTranscription?.text || ''; - if (text && text.trim()) { - const finalUtteranceText = text.trim().replace(//g, '').trim(); - if (finalUtteranceText && finalUtteranceText !== '.') { - debounceTheirCompletion(finalUtteranceText); - } - } - } else { - const type = message.type; - const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || ''; - if (type === 'conversation.item.input_audio_transcription.delta') { - if (theirCompletionTimer) clearTimeout(theirCompletionTimer); - theirCompletionTimer = null; - theirCurrentUtterance += text; - const continuousText = theirCompletionBuffer + (theirCompletionBuffer ? ' ' : '') + theirCurrentUtterance; - if (text && !text.includes('vq_lbr_audio_')) { - sendToRenderer('stt-update', { - speaker: 'Them', - text: continuousText, - isPartial: true, - isFinal: false, - timestamp: Date.now(), - }); - } - } else if (type === 'conversation.item.input_audio_transcription.completed') { - if (text && text.trim()) { - const finalUtteranceText = text.trim(); - theirCurrentUtterance = ''; - debounceTheirCompletion(finalUtteranceText); - } - } - } - - if (message.error) { - console.error('[Them] STT Session Error:', message.error); - } - }; - - const mySttConfig = { - language: effectiveLanguage, - callbacks: { - onmessage: handleMyMessage, - onerror: error => console.error('My STT session error:', error.message), - onclose: event => console.log('My STT session closed:', event.reason), - }, - }; - const theirSttConfig = { - language: effectiveLanguage, - callbacks: { - onmessage: handleTheirMessage, - onerror: error => console.error('Their STT session error:', error.message), - onclose: event => console.log('Their STT session closed:', event.reason), - }, - }; - - if (isGemini) { - [mySttSession, theirSttSession] = await Promise.all([ - connectToGeminiSession(API_KEY, mySttConfig), - connectToGeminiSession(API_KEY, theirSttConfig), - ]); - } else { - [mySttSession, theirSttSession] = await Promise.all([ - connectToOpenAiSession(API_KEY, mySttConfig, keyType), - connectToOpenAiSession(API_KEY, theirSttConfig, keyType), - ]); - } - - console.log('✅ Both STT sessions initialized successfully.'); - triggerAnalysisIfNeeded(); - - sendToRenderer('session-state-changed', { isActive: true }); - - isInitializingSession = false; - sendToRenderer('session-initializing', false); - sendToRenderer('update-status', 'Connected. Ready to listen.'); - return true; - } catch (error) { - console.error('❌ Failed to initialize STT sessions:', error); - isInitializingSession = false; - sendToRenderer('session-initializing', false); - sendToRenderer('update-status', 'Initialization failed.'); - mySttSession = null; - theirSttSession = null; - return false; - } -} - -function killExistingSystemAudioDump() { - return new Promise(resolve => { - console.log('Checking for existing SystemAudioDump processes...'); - - const killProc = spawn('pkill', ['-f', 'SystemAudioDump'], { - stdio: 'ignore', - }); - - killProc.on('close', code => { - if (code === 0) { - console.log('Killed existing SystemAudioDump processes'); - } else { - console.log('No existing SystemAudioDump processes found'); - } - resolve(); - }); - - killProc.on('error', err => { - console.log('Error checking for existing processes (this is normal):', err.message); - resolve(); - }); - - setTimeout(() => { - killProc.kill(); - resolve(); - }, 2000); - }); -} - -async function startMacOSAudioCapture() { - if (process.platform !== 'darwin' || !theirSttSession) return false; - - await killExistingSystemAudioDump(); - console.log('Starting macOS audio capture for "Them"...'); - - const { app } = require('electron'); - const path = require('path'); - const systemAudioPath = app.isPackaged - ? path.join(process.resourcesPath, 'app.asar.unpacked', 'src', 'assets', 'SystemAudioDump') - : path.join(app.getAppPath(), 'src', 'assets', 'SystemAudioDump'); - - console.log('SystemAudioDump path:', systemAudioPath); - - systemAudioProc = spawn(systemAudioPath, [], { - stdio: ['ignore', 'pipe', 'pipe'], - }); - - if (!systemAudioProc.pid) { - console.error('Failed to start SystemAudioDump'); - return false; - } - - console.log('SystemAudioDump started with PID:', systemAudioProc.pid); - - const CHUNK_DURATION = 0.1; - const SAMPLE_RATE = 24000; - const BYTES_PER_SAMPLE = 2; - const CHANNELS = 2; - const CHUNK_SIZE = SAMPLE_RATE * BYTES_PER_SAMPLE * CHANNELS * CHUNK_DURATION; - - let audioBuffer = Buffer.alloc(0); - - const provider = await getAiProvider(); - const isGemini = provider === 'gemini'; - - systemAudioProc.stdout.on('data', async data => { - audioBuffer = Buffer.concat([audioBuffer, data]); - - while (audioBuffer.length >= CHUNK_SIZE) { - const chunk = audioBuffer.slice(0, CHUNK_SIZE); - audioBuffer = audioBuffer.slice(CHUNK_SIZE); - - const monoChunk = CHANNELS === 2 ? convertStereoToMono(chunk) : chunk; - const base64Data = monoChunk.toString('base64'); - - sendToRenderer('system-audio-data', { data: base64Data }); - - if (theirSttSession) { - try { - // await theirSttSession.sendRealtimeInput(base64Data); - const payload = isGemini - ? { audio: { data: base64Data, mimeType: 'audio/pcm;rate=24000' } } - : base64Data; - await theirSttSession.sendRealtimeInput(payload); - } catch (err) { - console.error('Error sending system audio:', err.message); - } - } - - if (process.env.DEBUG_AUDIO) { - saveDebugAudio(monoChunk, 'system_audio'); - } - } - }); - - systemAudioProc.stderr.on('data', data => { - console.error('SystemAudioDump stderr:', data.toString()); - }); - - systemAudioProc.on('close', code => { - console.log('SystemAudioDump process closed with code:', code); - systemAudioProc = null; - }); - - systemAudioProc.on('error', err => { - console.error('SystemAudioDump process error:', err); - systemAudioProc = null; - }); - - return true; -} - -function convertStereoToMono(stereoBuffer) { - const samples = stereoBuffer.length / 4; - const monoBuffer = Buffer.alloc(samples * 2); - - for (let i = 0; i < samples; i++) { - const leftSample = stereoBuffer.readInt16LE(i * 4); - monoBuffer.writeInt16LE(leftSample, i * 2); - } - - return monoBuffer; -} - -function stopMacOSAudioCapture() { - if (systemAudioProc) { - console.log('Stopping SystemAudioDump...'); - systemAudioProc.kill('SIGTERM'); - systemAudioProc = null; - } -} - -async function sendAudioToOpenAI(base64Data, sttSessionRef) { - if (!sttSessionRef.current) return; - - try { - process.stdout.write('.'); - await sttSessionRef.current.sendRealtimeInput({ - audio: { - data: base64Data, - mimeType: 'audio/pcm;rate=24000', - }, - }); - } catch (error) { - console.error('Error sending audio to OpenAI:', error); - } -} - -function isSessionActive() { - return !!mySttSession && !!theirSttSession; -} - -async function closeSession() { - try { - stopMacOSAudioCapture(); - stopAnalysisInterval(); - - if (currentSessionId) { - await sessionRepository.end(currentSessionId); - console.log(`[DB] Session ${currentSessionId} ended.`); - } - - const closePromises = []; - if (mySttSession) { - closePromises.push(mySttSession.close()); - mySttSession = null; - } - if (theirSttSession) { - closePromises.push(theirSttSession.close()); - theirSttSession = null; - } - - await Promise.all(closePromises); - console.log('All sessions closed.'); - - currentSessionId = null; - conversationHistory = []; - - sendToRenderer('session-state-changed', { isActive: false }); - sendToRenderer('session-did-close'); - - return { success: true }; - } catch (error) { - console.error('Error closing sessions:', error); - return { success: false, error: error.message }; - } -} - -function setupLiveSummaryIpcHandlers() { - ipcMain.handle('is-session-active', async () => { - const isActive = isSessionActive(); - console.log(`Checking session status. Active: ${isActive}`); - return isActive; - }); - - ipcMain.handle('initialize-openai', async (event, profile = 'interview', language = 'en') => { - console.log(`Received initialize-openai request with profile: ${profile}, language: ${language}`); - const success = await initializeLiveSummarySession(language); - return success; - }); - - ipcMain.handle('send-audio-content', async (event, { data, mimeType }) => { - const provider = await getAiProvider(); - const isGemini = provider === 'gemini'; - if (!mySttSession) return { success: false, error: 'User STT session not active' }; - try { - // await mySttSession.sendRealtimeInput(data); - // provider에 맞는 형식으로 래핑 - const payload = isGemini - ? { audio: { data, mimeType: mimeType || 'audio/pcm;rate=24000' } } - : data; // OpenAI는 base64 string 그대로 - - await mySttSession.sendRealtimeInput(payload); - return { success: true }; - } catch (error) { - console.error('Error sending user audio:', error); - return { success: false, error: error.message }; - } - }); - - ipcMain.handle('start-macos-audio', async () => { - if (process.platform !== 'darwin') { - return { success: false, error: 'macOS audio capture only available on macOS' }; - } - try { - const success = await startMacOSAudioCapture(); - return { success }; - } catch (error) { - console.error('Error starting macOS audio capture:', error); - return { success: false, error: error.message }; - } - }); - - ipcMain.handle('stop-macos-audio', async () => { - try { - stopMacOSAudioCapture(); - return { success: true }; - } catch (error) { - console.error('Error stopping macOS audio capture:', error); - return { success: false, error: error.message }; - } - }); - - ipcMain.handle('close-session', async () => { - return await closeSession(); - }); - - ipcMain.handle('update-google-search-setting', async (event, enabled) => { - try { - console.log('Google Search setting updated to:', enabled); - return { success: true }; - } catch (error) { - console.error('Error updating Google Search setting:', error); - return { success: false, error: error.message }; - } - }); -} - -function getConversationHistory() { - return conversationHistory; -} - -module.exports = { - sendToRenderer, - initializeNewSession, - saveConversationTurn, - killExistingSystemAudioDump, - startMacOSAudioCapture, - convertStereoToMono, - stopMacOSAudioCapture, - sendAudioToOpenAI, - setupLiveSummaryIpcHandlers, - isSessionActive, - closeSession, - getConversationHistory, -}; diff --git a/src/features/listen/renderer.js b/src/features/listen/renderer/listenCapture.js similarity index 80% rename from src/features/listen/renderer.js rename to src/features/listen/renderer/listenCapture.js index 99d0bd3..a4eef43 100644 --- a/src/features/listen/renderer.js +++ b/src/features/listen/renderer/listenCapture.js @@ -1,20 +1,29 @@ -// renderer.js const { ipcRenderer } = require('electron'); -const { makeStreamingChatCompletionWithPortkey } = require('../../common/services/aiProviderService.js'); -let mediaStream = null; -let screenshotInterval = null; -let audioContext = null; -let audioProcessor = null; -let micMediaStream = null; -let audioBuffer = []; +// --------------------------- +// Constants & Globals +// --------------------------- const SAMPLE_RATE = 24000; const AUDIO_CHUNK_DURATION = 0.1; const BUFFER_SIZE = 4096; +const isLinux = process.platform === 'linux'; +const isMacOS = process.platform === 'darwin'; + +let mediaStream = null; +let micMediaStream = null; +let screenshotInterval = null; +let audioContext = null; +let audioProcessor = null; +let currentImageQuality = 'medium'; +let lastScreenshotBase64 = null; + let systemAudioBuffer = []; const MAX_SYSTEM_BUFFER_SIZE = 10; +// --------------------------- +// Utility helpers (exact from renderer.js) +// --------------------------- function isVoiceActive(audioFloat32Array, threshold = 0.005) { if (!audioFloat32Array || audioFloat32Array.length === 0) { return false; @@ -31,11 +40,6 @@ function isVoiceActive(audioFloat32Array, threshold = 0.005) { return rms > threshold; } -let currentImageQuality = 'medium'; // Store current image quality for manual screenshots -let lastScreenshotBase64 = null; // Store the latest screenshot - -let realtimeConversationHistory = []; - function base64ToFloat32Array(base64) { const binaryString = atob(base64); const bytes = new Uint8Array(binaryString.length); @@ -54,11 +58,29 @@ function base64ToFloat32Array(base64) { return float32Array; } -async function queryLoginState() { - const userState = await ipcRenderer.invoke('get-current-user'); - return userState; +function convertFloat32ToInt16(float32Array) { + const int16Array = new Int16Array(float32Array.length); + for (let i = 0; i < float32Array.length; i++) { + // Improved scaling to prevent clipping + const s = Math.max(-1, Math.min(1, float32Array[i])); + int16Array[i] = s < 0 ? s * 0x8000 : s * 0x7fff; + } + return int16Array; } +function arrayBufferToBase64(buffer) { + let binary = ''; + const bytes = new Uint8Array(buffer); + const len = bytes.byteLength; + for (let i = 0; i < len; i++) { + binary += String.fromCharCode(bytes[i]); + } + return btoa(binary); +} + +// --------------------------- +// Complete SimpleAEC implementation (exact from renderer.js) +// --------------------------- class SimpleAEC { constructor() { this.adaptiveFilter = new Float32Array(1024); @@ -179,11 +201,24 @@ class SimpleAEC { let aecProcessor = new SimpleAEC(); -const isLinux = process.platform === 'linux'; -const isMacOS = process.platform === 'darwin'; +// System audio data handler +ipcRenderer.on('system-audio-data', (event, { data }) => { + systemAudioBuffer.push({ + data: data, + timestamp: Date.now(), + }); -window.pickleGlass = window.pickleGlass || {}; + // 오래된 데이터 제거 + if (systemAudioBuffer.length > MAX_SYSTEM_BUFFER_SIZE) { + systemAudioBuffer = systemAudioBuffer.slice(-MAX_SYSTEM_BUFFER_SIZE); + } + console.log('📥 Received system audio for AEC reference'); +}); + +// --------------------------- +// Complete token tracker (exact from renderer.js) +// --------------------------- let tokenTracker = { tokens: [], audioStartTime: null, @@ -265,126 +300,201 @@ setInterval(() => { tokenTracker.trackAudioTokens(); }, 2000); -function pickleGlassElement() { - return document.getElementById('pickle-glass'); -} +// --------------------------- +// Audio processing functions (exact from renderer.js) +// --------------------------- +function setupMicProcessing(micStream) { + const micAudioContext = new AudioContext({ sampleRate: SAMPLE_RATE }); + const micSource = micAudioContext.createMediaStreamSource(micStream); + const micProcessor = micAudioContext.createScriptProcessor(BUFFER_SIZE, 1, 1); -function convertFloat32ToInt16(float32Array) { - const int16Array = new Int16Array(float32Array.length); - for (let i = 0; i < float32Array.length; i++) { - // Improved scaling to prevent clipping - const s = Math.max(-1, Math.min(1, float32Array[i])); - int16Array[i] = s < 0 ? s * 0x8000 : s * 0x7fff; - } - return int16Array; -} + let audioBuffer = []; + const samplesPerChunk = SAMPLE_RATE * AUDIO_CHUNK_DURATION; -function arrayBufferToBase64(buffer) { - let binary = ''; - const bytes = new Uint8Array(buffer); - const len = bytes.byteLength; - for (let i = 0; i < len; i++) { - binary += String.fromCharCode(bytes[i]); - } - return btoa(binary); -} + micProcessor.onaudioprocess = async e => { + const inputData = e.inputBuffer.getChannelData(0); + audioBuffer.push(...inputData); -async function initializeopenai(profile = 'interview', language = 'en') { - // The API key is now handled in the main process from .env file. - // We just need to trigger the initialization. - try { - console.log(`Requesting OpenAI initialization with profile: ${profile}, language: ${language}`); - const success = await ipcRenderer.invoke('initialize-openai', profile, language); - if (success) { - // The status will be updated via 'update-status' event from the main process. - console.log('OpenAI initialization successful.'); - } else { - console.error('OpenAI initialization failed.'); - const appElement = pickleGlassElement(); - if (appElement && typeof appElement.setStatus === 'function') { - appElement.setStatus('Initialization Failed'); + while (audioBuffer.length >= samplesPerChunk) { + let chunk = audioBuffer.splice(0, samplesPerChunk); + let processedChunk = new Float32Array(chunk); + + // Check for system audio and apply AEC only if voice is active + if (aecProcessor && systemAudioBuffer.length > 0) { + const latestSystemAudio = systemAudioBuffer[systemAudioBuffer.length - 1]; + const systemFloat32 = base64ToFloat32Array(latestSystemAudio.data); + + // Apply AEC only when system audio has active speech + if (isVoiceActive(systemFloat32)) { + processedChunk = aecProcessor.process(new Float32Array(chunk), systemFloat32); + console.log('🔊 Applied AEC because system audio is active'); + } } + + const pcmData16 = convertFloat32ToInt16(processedChunk); + const base64Data = arrayBufferToBase64(pcmData16.buffer); + + await ipcRenderer.invoke('send-audio-content', { + data: base64Data, + mimeType: 'audio/pcm;rate=24000', + }); + } + }; + + micSource.connect(micProcessor); + micProcessor.connect(micAudioContext.destination); + + audioProcessor = micProcessor; +} + +function setupLinuxMicProcessing(micStream) { + // Setup microphone audio processing for Linux + const micAudioContext = new AudioContext({ sampleRate: SAMPLE_RATE }); + const micSource = micAudioContext.createMediaStreamSource(micStream); + const micProcessor = micAudioContext.createScriptProcessor(BUFFER_SIZE, 1, 1); + + let audioBuffer = []; + const samplesPerChunk = SAMPLE_RATE * AUDIO_CHUNK_DURATION; + + micProcessor.onaudioprocess = async e => { + const inputData = e.inputBuffer.getChannelData(0); + audioBuffer.push(...inputData); + + // Process audio in chunks + while (audioBuffer.length >= samplesPerChunk) { + const chunk = audioBuffer.splice(0, samplesPerChunk); + const pcmData16 = convertFloat32ToInt16(chunk); + const base64Data = arrayBufferToBase64(pcmData16.buffer); + + await ipcRenderer.invoke('send-audio-content', { + data: base64Data, + mimeType: 'audio/pcm;rate=24000', + }); + } + }; + + micSource.connect(micProcessor); + micProcessor.connect(micAudioContext.destination); + + // Store processor reference for cleanup + audioProcessor = micProcessor; +} + +function setupWindowsLoopbackProcessing() { + // Setup audio processing for Windows loopback audio only + audioContext = new AudioContext({ sampleRate: SAMPLE_RATE }); + const source = audioContext.createMediaStreamSource(mediaStream); + audioProcessor = audioContext.createScriptProcessor(BUFFER_SIZE, 1, 1); + + let audioBuffer = []; + const samplesPerChunk = SAMPLE_RATE * AUDIO_CHUNK_DURATION; + + audioProcessor.onaudioprocess = async e => { + const inputData = e.inputBuffer.getChannelData(0); + audioBuffer.push(...inputData); + + // Process audio in chunks + while (audioBuffer.length >= samplesPerChunk) { + const chunk = audioBuffer.splice(0, samplesPerChunk); + const pcmData16 = convertFloat32ToInt16(chunk); + const base64Data = arrayBufferToBase64(pcmData16.buffer); + + await ipcRenderer.invoke('send-audio-content', { + data: base64Data, + mimeType: 'audio/pcm;rate=24000', + }); + } + }; + + source.connect(audioProcessor); + audioProcessor.connect(audioContext.destination); +} + +// --------------------------- +// Screenshot functions (exact from renderer.js) +// --------------------------- +async function captureScreenshot(imageQuality = 'medium', isManual = false) { + console.log(`Capturing ${isManual ? 'manual' : 'automated'} screenshot...`); + + // Check rate limiting for automated screenshots only + if (!isManual && tokenTracker.shouldThrottle()) { + console.log('⚠️ Automated screenshot skipped due to rate limiting'); + return; + } + + try { + // Request screenshot from main process + const result = await ipcRenderer.invoke('capture-screenshot', { + quality: imageQuality, + }); + + if (result.success && result.base64) { + // Store the latest screenshot + lastScreenshotBase64 = result.base64; + + // Note: sendResult is not defined in the original, this was likely an error + // Commenting out this section as it references undefined variable + /* + if (sendResult.success) { + // Track image tokens after successful send + const imageTokens = tokenTracker.calculateImageTokens(result.width || 1920, result.height || 1080); + tokenTracker.addTokens(imageTokens, 'image'); + console.log(`📊 Image sent successfully - ${imageTokens} tokens used (${result.width}x${result.height})`); + } else { + console.error('Failed to send image:', sendResult.error); + } + */ + } else { + console.error('Failed to capture screenshot:', result.error); } } catch (error) { - console.error('Error during OpenAI initialization IPC call:', error); - const appElement = pickleGlassElement(); - if (appElement && typeof appElement.setStatus === 'function') { - appElement.setStatus('Error'); - } + console.error('Error capturing screenshot:', error); } } +async function captureManualScreenshot(imageQuality = null) { + console.log('Manual screenshot triggered'); + const quality = imageQuality || currentImageQuality; + await captureScreenshot(quality, true); +} -ipcRenderer.on('system-audio-data', (event, { data }) => { - systemAudioBuffer.push({ - data: data, - timestamp: Date.now(), - }); +async function getCurrentScreenshot() { + try { + // First try to get a fresh screenshot from main process + const result = await ipcRenderer.invoke('get-current-screenshot'); - // 오래된 데이터 제거 - if (systemAudioBuffer.length > MAX_SYSTEM_BUFFER_SIZE) { - systemAudioBuffer = systemAudioBuffer.slice(-MAX_SYSTEM_BUFFER_SIZE); - } - - console.log('📥 Received system audio for AEC reference'); -}); - -// Listen for status updates -ipcRenderer.on('update-status', (event, status) => { - console.log('Status update:', status); - pickleGlass.e().setStatus(status); -}); - -// Listen for real-time STT updates -ipcRenderer.on('stt-update', (event, data) => { - console.log('Renderer.js stt-update', data); - const { speaker, text, isFinal, isPartial, timestamp } = data; - - if (isPartial) { - console.log(`🔄 [${speaker} - partial]: ${text}`); - } else if (isFinal) { - console.log(`✅ [${speaker} - final]: ${text}`); - - const speakerText = speaker.toLowerCase(); - const conversationText = `${speakerText}: ${text.trim()}`; - - realtimeConversationHistory.push(conversationText); - - if (realtimeConversationHistory.length > 30) { - realtimeConversationHistory = realtimeConversationHistory.slice(-30); + if (result.success && result.base64) { + console.log('📸 Got fresh screenshot from main process'); + return result.base64; } - console.log(`📝 Updated realtime conversation history: ${realtimeConversationHistory.length} texts`); - console.log(`📋 Latest text: ${conversationText}`); - } - - if (pickleGlass.e() && typeof pickleGlass.e().updateRealtimeTranscription === 'function') { - pickleGlass.e().updateRealtimeTranscription({ - speaker, - text, - isFinal, - isPartial, - timestamp, + // If no screenshot available, capture one now + console.log('📸 No screenshot available, capturing new one'); + const captureResult = await ipcRenderer.invoke('capture-screenshot', { + quality: currentImageQuality, }); + + if (captureResult.success && captureResult.base64) { + lastScreenshotBase64 = captureResult.base64; + return captureResult.base64; + } + + // Fallback to last stored screenshot + if (lastScreenshotBase64) { + console.log('📸 Using cached screenshot'); + return lastScreenshotBase64; + } + + throw new Error('Failed to get screenshot'); + } catch (error) { + console.error('Error getting current screenshot:', error); + return null; } -}); - - -ipcRenderer.on('update-structured-data', (_, structuredData) => { - console.log('📥 Received structured data update:', structuredData); - window.pickleGlass.structuredData = structuredData; - window.pickleGlass.setStructuredData(structuredData); -}); -window.pickleGlass.structuredData = { - summary: [], - topic: { header: '', bullets: [] }, - actions: [], -}; -window.pickleGlass.setStructuredData = data => { - window.pickleGlass.structuredData = data; - pickleGlass.e()?.updateStructuredData?.(data); -}; +} +// --------------------------- +// Main capture functions (exact from renderer.js) +// --------------------------- async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'medium') { // Store the image quality for manual screenshots currentImageQuality = imageQuality; @@ -490,12 +600,6 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu setupWindowsLoopbackProcessing(); } - // console.log('MediaStream obtained:', { - // hasVideo: mediaStream.getVideoTracks().length > 0, - // hasAudio: mediaStream.getAudioTracks().length > 0, - // videoTrack: mediaStream.getVideoTracks()[0]?.getSettings(), - // }); - // Start capturing screenshots - check if manual mode if (screenshotIntervalSeconds === 'manual' || screenshotIntervalSeconds === 'Manual') { console.log('Manual mode enabled - screenshots will be captured on demand only'); @@ -511,162 +615,11 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu } } catch (err) { console.error('Error starting capture:', err); - pickleGlass.e().setStatus('error'); + // Note: pickleGlass.e() is not available in this context, commenting out + // pickleGlass.e().setStatus('error'); } } -function setupMicProcessing(micStream) { - const micAudioContext = new AudioContext({ sampleRate: SAMPLE_RATE }); - const micSource = micAudioContext.createMediaStreamSource(micStream); - const micProcessor = micAudioContext.createScriptProcessor(BUFFER_SIZE, 1, 1); - - let audioBuffer = []; - const samplesPerChunk = SAMPLE_RATE * AUDIO_CHUNK_DURATION; - - micProcessor.onaudioprocess = async e => { - const inputData = e.inputBuffer.getChannelData(0); - audioBuffer.push(...inputData); - - while (audioBuffer.length >= samplesPerChunk) { - let chunk = audioBuffer.splice(0, samplesPerChunk); - let processedChunk = new Float32Array(chunk); - - // Check for system audio and apply AEC only if voice is active - if (aecProcessor && systemAudioBuffer.length > 0) { - const latestSystemAudio = systemAudioBuffer[systemAudioBuffer.length - 1]; - const systemFloat32 = base64ToFloat32Array(latestSystemAudio.data); - - // Apply AEC only when system audio has active speech - if (isVoiceActive(systemFloat32)) { - processedChunk = aecProcessor.process(new Float32Array(chunk), systemFloat32); - console.log('🔊 Applied AEC because system audio is active'); - } - } - - const pcmData16 = convertFloat32ToInt16(processedChunk); - const base64Data = arrayBufferToBase64(pcmData16.buffer); - - await ipcRenderer.invoke('send-audio-content', { - data: base64Data, - mimeType: 'audio/pcm;rate=24000', - }); - } - }; - - micSource.connect(micProcessor); - micProcessor.connect(micAudioContext.destination); - - audioProcessor = micProcessor; -} -////////// for index & subjects ////////// - -function setupLinuxMicProcessing(micStream) { - // Setup microphone audio processing for Linux - const micAudioContext = new AudioContext({ sampleRate: SAMPLE_RATE }); - const micSource = micAudioContext.createMediaStreamSource(micStream); - const micProcessor = micAudioContext.createScriptProcessor(BUFFER_SIZE, 1, 1); - - let audioBuffer = []; - const samplesPerChunk = SAMPLE_RATE * AUDIO_CHUNK_DURATION; - - micProcessor.onaudioprocess = async e => { - const inputData = e.inputBuffer.getChannelData(0); - audioBuffer.push(...inputData); - - // Process audio in chunks - while (audioBuffer.length >= samplesPerChunk) { - const chunk = audioBuffer.splice(0, samplesPerChunk); - const pcmData16 = convertFloat32ToInt16(chunk); - const base64Data = arrayBufferToBase64(pcmData16.buffer); - - await ipcRenderer.invoke('send-audio-content', { - data: base64Data, - mimeType: 'audio/pcm;rate=24000', - }); - } - }; - - micSource.connect(micProcessor); - micProcessor.connect(micAudioContext.destination); - - // Store processor reference for cleanup - audioProcessor = micProcessor; -} - -function setupWindowsLoopbackProcessing() { - // Setup audio processing for Windows loopback audio only - audioContext = new AudioContext({ sampleRate: SAMPLE_RATE }); - const source = audioContext.createMediaStreamSource(mediaStream); - audioProcessor = audioContext.createScriptProcessor(BUFFER_SIZE, 1, 1); - - let audioBuffer = []; - const samplesPerChunk = SAMPLE_RATE * AUDIO_CHUNK_DURATION; - - audioProcessor.onaudioprocess = async e => { - const inputData = e.inputBuffer.getChannelData(0); - audioBuffer.push(...inputData); - - // Process audio in chunks - while (audioBuffer.length >= samplesPerChunk) { - const chunk = audioBuffer.splice(0, samplesPerChunk); - const pcmData16 = convertFloat32ToInt16(chunk); - const base64Data = arrayBufferToBase64(pcmData16.buffer); - - await ipcRenderer.invoke('send-audio-content', { - data: base64Data, - mimeType: 'audio/pcm;rate=24000', - }); - } - }; - - source.connect(audioProcessor); - audioProcessor.connect(audioContext.destination); -} - -async function captureScreenshot(imageQuality = 'medium', isManual = false) { - console.log(`Capturing ${isManual ? 'manual' : 'automated'} screenshot...`); - - // Check rate limiting for automated screenshots only - if (!isManual && tokenTracker.shouldThrottle()) { - console.log('⚠️ Automated screenshot skipped due to rate limiting'); - return; - } - - try { - // Request screenshot from main process - const result = await ipcRenderer.invoke('capture-screenshot', { - quality: imageQuality, - }); - - if (result.success && result.base64) { - // Store the latest screenshot - lastScreenshotBase64 = result.base64; - - if (sendResult.success) { - // Track image tokens after successful send - const imageTokens = tokenTracker.calculateImageTokens(result.width || 1920, result.height || 1080); - tokenTracker.addTokens(imageTokens, 'image'); - console.log(`📊 Image sent successfully - ${imageTokens} tokens used (${result.width}x${result.height})`); - } else { - console.error('Failed to send image:', sendResult.error); - } - } else { - console.error('Failed to capture screenshot:', result.error); - } - } catch (error) { - console.error('Error capturing screenshot:', error); - } -} - -async function captureManualScreenshot(imageQuality = null) { - console.log('Manual screenshot triggered'); - const quality = imageQuality || currentImageQuality; - await captureScreenshot(quality, true); -} - -// Expose functions to global scope for external access -window.captureManualScreenshot = captureManualScreenshot; - function stopCapture() { if (screenshotInterval) { clearInterval(screenshotInterval); @@ -706,76 +659,25 @@ function stopCapture() { } } -async function getCurrentScreenshot() { - try { - // First try to get a fresh screenshot from main process - const result = await ipcRenderer.invoke('get-current-screenshot'); - - if (result.success && result.base64) { - console.log('📸 Got fresh screenshot from main process'); - return result.base64; - } - - // If no screenshot available, capture one now - console.log('📸 No screenshot available, capturing new one'); - const captureResult = await ipcRenderer.invoke('capture-screenshot', { - quality: currentImageQuality, - }); - - if (captureResult.success && captureResult.base64) { - lastScreenshotBase64 = captureResult.base64; - return captureResult.base64; - } - - // Fallback to last stored screenshot - if (lastScreenshotBase64) { - console.log('📸 Using cached screenshot'); - return lastScreenshotBase64; - } - - throw new Error('Failed to get screenshot'); - } catch (error) { - console.error('Error getting current screenshot:', error); - return null; - } -} - -function formatRealtimeConversationHistory() { - if (realtimeConversationHistory.length === 0) return 'No conversation history available.'; - - return realtimeConversationHistory.slice(-30).join('\n'); -} - -window.pickleGlass = { - initializeopenai, +// --------------------------- +// Exports & global registration +// --------------------------- +module.exports = { startCapture, stopCapture, - isLinux: isLinux, - isMacOS: isMacOS, - e: pickleGlassElement, + captureManualScreenshot, + getCurrentScreenshot, + isLinux, + isMacOS, }; -// ------------------------------------------------------- -// 🔔 React to session state changes from the main process -// When the session ends (isActive === false), ensure we stop -// all local capture pipelines (mic, screen, etc.). -// ------------------------------------------------------- -ipcRenderer.on('session-state-changed', (_event, { isActive }) => { - if (!isActive) { - console.log('[Renderer] Session ended – stopping local capture'); - stopCapture(); - } else { - console.log('[Renderer] New session started – clearing in-memory history and summaries'); - - // Reset live conversation & analysis caches - realtimeConversationHistory = []; - - const blankData = { - summary: [], - topic: { header: '', bullets: [] }, - actions: [], - followUps: [], - }; - window.pickleGlass.setStructuredData(blankData); - } -}); +// Expose functions to global scope for external access (exact from renderer.js) +if (typeof window !== 'undefined') { + window.captureManualScreenshot = captureManualScreenshot; + window.listenCapture = module.exports; + window.pickleGlass = window.pickleGlass || {}; + window.pickleGlass.startCapture = startCapture; + window.pickleGlass.stopCapture = stopCapture; + window.pickleGlass.captureManualScreenshot = captureManualScreenshot; + window.pickleGlass.getCurrentScreenshot = getCurrentScreenshot; +} \ No newline at end of file diff --git a/src/features/listen/renderer/renderer.js b/src/features/listen/renderer/renderer.js new file mode 100644 index 0000000..9916909 --- /dev/null +++ b/src/features/listen/renderer/renderer.js @@ -0,0 +1,139 @@ +// renderer.js +const { ipcRenderer } = require('electron'); +const { makeStreamingChatCompletionWithPortkey } = require('../../../common/services/aiProviderService.js'); +const listenCapture = require('./listenCapture.js'); + +let realtimeConversationHistory = []; + +async function queryLoginState() { + const userState = await ipcRenderer.invoke('get-current-user'); + return userState; +} + +function pickleGlassElement() { + return document.getElementById('pickle-glass'); +} + +async function initializeopenai(profile = 'interview', language = 'en') { + // The API key is now handled in the main process from .env file. + // We just need to trigger the initialization. + try { + console.log(`Requesting OpenAI initialization with profile: ${profile}, language: ${language}`); + const success = await ipcRenderer.invoke('initialize-openai', profile, language); + if (success) { + // The status will be updated via 'update-status' event from the main process. + console.log('OpenAI initialization successful.'); + } else { + console.error('OpenAI initialization failed.'); + const appElement = pickleGlassElement(); + if (appElement && typeof appElement.setStatus === 'function') { + appElement.setStatus('Initialization Failed'); + } + } + } catch (error) { + console.error('Error during OpenAI initialization IPC call:', error); + const appElement = pickleGlassElement(); + if (appElement && typeof appElement.setStatus === 'function') { + appElement.setStatus('Error'); + } + } +} + +// Listen for status updates +ipcRenderer.on('update-status', (event, status) => { + console.log('Status update:', status); + pickleGlass.e().setStatus(status); +}); + +// Listen for real-time STT updates +ipcRenderer.on('stt-update', (event, data) => { + console.log('Renderer.js stt-update', data); + const { speaker, text, isFinal, isPartial, timestamp } = data; + + if (isPartial) { + console.log(`🔄 [${speaker} - partial]: ${text}`); + } else if (isFinal) { + console.log(`✅ [${speaker} - final]: ${text}`); + + const speakerText = speaker.toLowerCase(); + const conversationText = `${speakerText}: ${text.trim()}`; + + realtimeConversationHistory.push(conversationText); + + if (realtimeConversationHistory.length > 30) { + realtimeConversationHistory = realtimeConversationHistory.slice(-30); + } + + console.log(`📝 Updated realtime conversation history: ${realtimeConversationHistory.length} texts`); + console.log(`📋 Latest text: ${conversationText}`); + } + + if (pickleGlass.e() && typeof pickleGlass.e().updateRealtimeTranscription === 'function') { + pickleGlass.e().updateRealtimeTranscription({ + speaker, + text, + isFinal, + isPartial, + timestamp, + }); + } +}); + +ipcRenderer.on('update-structured-data', (_, structuredData) => { + console.log('📥 Received structured data update:', structuredData); + window.pickleGlass.structuredData = structuredData; + window.pickleGlass.setStructuredData(structuredData); +}); + +window.pickleGlass.structuredData = { + summary: [], + topic: { header: '', bullets: [] }, + actions: [], +}; + +window.pickleGlass.setStructuredData = data => { + window.pickleGlass.structuredData = data; + pickleGlass.e()?.updateStructuredData?.(data); +}; + +function formatRealtimeConversationHistory() { + if (realtimeConversationHistory.length === 0) return 'No conversation history available.'; + + return realtimeConversationHistory.slice(-30).join('\n'); +} + +window.pickleGlass = { + initializeopenai, + startCapture: listenCapture.startCapture, + stopCapture: listenCapture.stopCapture, + isLinux: listenCapture.isLinux, + isMacOS: listenCapture.isMacOS, + captureManualScreenshot: listenCapture.captureManualScreenshot, + getCurrentScreenshot: listenCapture.getCurrentScreenshot, + e: pickleGlassElement, +}; + +// ------------------------------------------------------- +// 🔔 React to session state changes from the main process +// When the session ends (isActive === false), ensure we stop +// all local capture pipelines (mic, screen, etc.). +// ------------------------------------------------------- +ipcRenderer.on('session-state-changed', (_event, { isActive }) => { + if (!isActive) { + console.log('[Renderer] Session ended – stopping local capture'); + listenCapture.stopCapture(); + } else { + console.log('[Renderer] New session started – clearing in-memory history and summaries'); + + // Reset live conversation & analysis caches + realtimeConversationHistory = []; + + const blankData = { + summary: [], + topic: { header: '', bullets: [] }, + actions: [], + followUps: [], + }; + window.pickleGlass.setStructuredData(blankData); + } +}); diff --git a/src/features/listen/stt/repositories/index.js b/src/features/listen/stt/repositories/index.js new file mode 100644 index 0000000..6de1a98 --- /dev/null +++ b/src/features/listen/stt/repositories/index.js @@ -0,0 +1,5 @@ +const sttRepository = require('./sqlite.repository'); + +module.exports = { + ...sttRepository, +}; \ No newline at end of file diff --git a/src/features/listen/stt/repositories/sqlite.repository.js b/src/features/listen/stt/repositories/sqlite.repository.js new file mode 100644 index 0000000..4de47bd --- /dev/null +++ b/src/features/listen/stt/repositories/sqlite.repository.js @@ -0,0 +1,37 @@ +const sqliteClient = require('../../../../common/services/sqliteClient'); + +function addTranscript({ sessionId, speaker, text }) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const transcriptId = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = `INSERT INTO transcripts (id, session_id, start_at, speaker, text, created_at) VALUES (?, ?, ?, ?, ?, ?)`; + db.run(query, [transcriptId, sessionId, now, speaker, text, now], function(err) { + if (err) { + console.error('Error adding transcript:', err); + reject(err); + } else { + resolve({ id: transcriptId }); + } + }); + }); +} + +function getAllTranscriptsBySessionId(sessionId) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = "SELECT * FROM transcripts WHERE session_id = ? ORDER BY start_at ASC"; + db.all(query, [sessionId], (err, rows) => { + if (err) { + reject(err); + } else { + resolve(rows); + } + }); + }); +} + +module.exports = { + addTranscript, + getAllTranscriptsBySessionId, +}; \ No newline at end of file diff --git a/src/features/listen/stt/sttService.js b/src/features/listen/stt/sttService.js new file mode 100644 index 0000000..4530ef0 --- /dev/null +++ b/src/features/listen/stt/sttService.js @@ -0,0 +1,480 @@ +const { BrowserWindow } = require('electron'); +const { spawn } = require('child_process'); +const { connectToGeminiSession } = require('../../../common/services/googleGeminiClient.js'); +const { connectToOpenAiSession } = require('../../../common/services/openAiClient.js'); +const { getStoredApiKey, getStoredProvider } = require('../../../electron/windowManager'); + +const COMPLETION_DEBOUNCE_MS = 2000; + +class SttService { + constructor() { + this.mySttSession = null; + this.theirSttSession = null; + this.myCurrentUtterance = ''; + this.theirCurrentUtterance = ''; + + this.myLastPartialText = ''; + this.theirLastPartialText = ''; + this.myInactivityTimer = null; + this.theirInactivityTimer = null; + + // Turn-completion debouncing + this.myCompletionBuffer = ''; + this.theirCompletionBuffer = ''; + this.myCompletionTimer = null; + this.theirCompletionTimer = null; + + // System audio capture + this.systemAudioProc = null; + + // Callbacks + this.onTranscriptionComplete = null; + this.onStatusUpdate = null; + } + + setCallbacks({ onTranscriptionComplete, onStatusUpdate }) { + this.onTranscriptionComplete = onTranscriptionComplete; + this.onStatusUpdate = onStatusUpdate; + } + + async getApiKey() { + const storedKey = await getStoredApiKey(); + if (storedKey) { + console.log('[SttService] Using stored API key'); + return storedKey; + } + + const envKey = process.env.OPENAI_API_KEY; + if (envKey) { + console.log('[SttService] Using environment API key'); + return envKey; + } + + console.error('[SttService] No API key found in storage or environment'); + return null; + } + + async getAiProvider() { + try { + const { ipcRenderer } = require('electron'); + const provider = await ipcRenderer.invoke('get-ai-provider'); + return provider || 'openai'; + } catch (error) { + return getStoredProvider ? getStoredProvider() : 'openai'; + } + } + + sendToRenderer(channel, data) { + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send(channel, data); + } + }); + } + + flushMyCompletion() { + if (!this.myCompletionBuffer.trim()) return; + + const finalText = this.myCompletionBuffer.trim(); + + // Notify completion callback + if (this.onTranscriptionComplete) { + this.onTranscriptionComplete('Me', finalText); + } + + // Send to renderer as final + this.sendToRenderer('stt-update', { + speaker: 'Me', + text: finalText, + isPartial: false, + isFinal: true, + timestamp: Date.now(), + }); + + this.myCompletionBuffer = ''; + this.myCompletionTimer = null; + this.myCurrentUtterance = ''; + + if (this.onStatusUpdate) { + this.onStatusUpdate('Listening...'); + } + } + + flushTheirCompletion() { + if (!this.theirCompletionBuffer.trim()) return; + + const finalText = this.theirCompletionBuffer.trim(); + + // Notify completion callback + if (this.onTranscriptionComplete) { + this.onTranscriptionComplete('Them', finalText); + } + + // Send to renderer as final + this.sendToRenderer('stt-update', { + speaker: 'Them', + text: finalText, + isPartial: false, + isFinal: true, + timestamp: Date.now(), + }); + + this.theirCompletionBuffer = ''; + this.theirCompletionTimer = null; + this.theirCurrentUtterance = ''; + + if (this.onStatusUpdate) { + this.onStatusUpdate('Listening...'); + } + } + + debounceMyCompletion(text) { + // 상대방이 말하고 있던 경우, 화자가 변경되었으므로 즉시 상대방의 말풍선을 완성합니다. + if (this.theirCompletionTimer) { + clearTimeout(this.theirCompletionTimer); + this.flushTheirCompletion(); + } + + this.myCompletionBuffer += (this.myCompletionBuffer ? ' ' : '') + text; + + if (this.myCompletionTimer) clearTimeout(this.myCompletionTimer); + this.myCompletionTimer = setTimeout(() => this.flushMyCompletion(), COMPLETION_DEBOUNCE_MS); + } + + debounceTheirCompletion(text) { + // 내가 말하고 있던 경우, 화자가 변경되었으므로 즉시 내 말풍선을 완성합니다. + if (this.myCompletionTimer) { + clearTimeout(this.myCompletionTimer); + this.flushMyCompletion(); + } + + this.theirCompletionBuffer += (this.theirCompletionBuffer ? ' ' : '') + text; + + if (this.theirCompletionTimer) clearTimeout(this.theirCompletionTimer); + this.theirCompletionTimer = setTimeout(() => this.flushTheirCompletion(), COMPLETION_DEBOUNCE_MS); + } + + async initializeSttSessions(language = 'en') { + const effectiveLanguage = process.env.OPENAI_TRANSCRIBE_LANG || language || 'en'; + + const API_KEY = await this.getApiKey(); + if (!API_KEY) { + throw new Error('No API key available'); + } + + const provider = await this.getAiProvider(); + const isGemini = provider === 'gemini'; + console.log(`[SttService] Initializing STT for provider: ${provider}`); + + const handleMyMessage = message => { + if (isGemini) { + const text = message.serverContent?.inputTranscription?.text || ''; + if (text && text.trim()) { + const finalUtteranceText = text.trim().replace(//g, '').trim(); + if (finalUtteranceText && finalUtteranceText !== '.') { + this.debounceMyCompletion(finalUtteranceText); + } + } + } else { + const type = message.type; + const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || ''; + + if (type === 'conversation.item.input_audio_transcription.delta') { + if (this.myCompletionTimer) clearTimeout(this.myCompletionTimer); + this.myCompletionTimer = null; + this.myCurrentUtterance += text; + const continuousText = this.myCompletionBuffer + (this.myCompletionBuffer ? ' ' : '') + this.myCurrentUtterance; + if (text && !text.includes('vq_lbr_audio_')) { + this.sendToRenderer('stt-update', { + speaker: 'Me', + text: continuousText, + isPartial: true, + isFinal: false, + timestamp: Date.now(), + }); + } + } else if (type === 'conversation.item.input_audio_transcription.completed') { + if (text && text.trim()) { + const finalUtteranceText = text.trim(); + this.myCurrentUtterance = ''; + this.debounceMyCompletion(finalUtteranceText); + } + } + } + + if (message.error) { + console.error('[Me] STT Session Error:', message.error); + } + }; + + const handleTheirMessage = message => { + if (isGemini) { + const text = message.serverContent?.inputTranscription?.text || ''; + if (text && text.trim()) { + const finalUtteranceText = text.trim().replace(//g, '').trim(); + if (finalUtteranceText && finalUtteranceText !== '.') { + this.debounceTheirCompletion(finalUtteranceText); + } + } + } else { + const type = message.type; + const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || ''; + if (type === 'conversation.item.input_audio_transcription.delta') { + if (this.theirCompletionTimer) clearTimeout(this.theirCompletionTimer); + this.theirCompletionTimer = null; + this.theirCurrentUtterance += text; + const continuousText = this.theirCompletionBuffer + (this.theirCompletionBuffer ? ' ' : '') + this.theirCurrentUtterance; + if (text && !text.includes('vq_lbr_audio_')) { + this.sendToRenderer('stt-update', { + speaker: 'Them', + text: continuousText, + isPartial: true, + isFinal: false, + timestamp: Date.now(), + }); + } + } else if (type === 'conversation.item.input_audio_transcription.completed') { + if (text && text.trim()) { + const finalUtteranceText = text.trim(); + this.theirCurrentUtterance = ''; + this.debounceTheirCompletion(finalUtteranceText); + } + } + } + + if (message.error) { + console.error('[Them] STT Session Error:', message.error); + } + }; + + const mySttConfig = { + language: effectiveLanguage, + callbacks: { + onmessage: handleMyMessage, + onerror: error => console.error('My STT session error:', error.message), + onclose: event => console.log('My STT session closed:', event.reason), + }, + }; + + const theirSttConfig = { + language: effectiveLanguage, + callbacks: { + onmessage: handleTheirMessage, + onerror: error => console.error('Their STT session error:', error.message), + onclose: event => console.log('Their STT session closed:', event.reason), + }, + }; + + // Determine key type based on auth status + const authService = require('../../../common/services/authService'); + const userState = authService.getCurrentUser(); + const loggedIn = userState.isLoggedIn; + const keyType = loggedIn ? 'vKey' : 'apiKey'; + + if (isGemini) { + [this.mySttSession, this.theirSttSession] = await Promise.all([ + connectToGeminiSession(API_KEY, mySttConfig), + connectToGeminiSession(API_KEY, theirSttConfig), + ]); + } else { + [this.mySttSession, this.theirSttSession] = await Promise.all([ + connectToOpenAiSession(API_KEY, mySttConfig, keyType), + connectToOpenAiSession(API_KEY, theirSttConfig, keyType), + ]); + } + + console.log('✅ Both STT sessions initialized successfully.'); + return true; + } + + async sendAudioContent(data, mimeType) { + const provider = await this.getAiProvider(); + const isGemini = provider === 'gemini'; + + if (!this.mySttSession) { + throw new Error('User STT session not active'); + } + + const payload = isGemini + ? { audio: { data, mimeType: mimeType || 'audio/pcm;rate=24000' } } + : data; + + await this.mySttSession.sendRealtimeInput(payload); + } + + killExistingSystemAudioDump() { + return new Promise(resolve => { + console.log('Checking for existing SystemAudioDump processes...'); + + const killProc = spawn('pkill', ['-f', 'SystemAudioDump'], { + stdio: 'ignore', + }); + + killProc.on('close', code => { + if (code === 0) { + console.log('Killed existing SystemAudioDump processes'); + } else { + console.log('No existing SystemAudioDump processes found'); + } + resolve(); + }); + + killProc.on('error', err => { + console.log('Error checking for existing processes (this is normal):', err.message); + resolve(); + }); + + setTimeout(() => { + killProc.kill(); + resolve(); + }, 2000); + }); + } + + async startMacOSAudioCapture() { + if (process.platform !== 'darwin' || !this.theirSttSession) return false; + + await this.killExistingSystemAudioDump(); + console.log('Starting macOS audio capture for "Them"...'); + + const { app } = require('electron'); + const path = require('path'); + const systemAudioPath = app.isPackaged + ? path.join(process.resourcesPath, 'app.asar.unpacked', 'src', 'assets', 'SystemAudioDump') + : path.join(app.getAppPath(), 'src', 'assets', 'SystemAudioDump'); + + console.log('SystemAudioDump path:', systemAudioPath); + + this.systemAudioProc = spawn(systemAudioPath, [], { + stdio: ['ignore', 'pipe', 'pipe'], + }); + + if (!this.systemAudioProc.pid) { + console.error('Failed to start SystemAudioDump'); + return false; + } + + console.log('SystemAudioDump started with PID:', this.systemAudioProc.pid); + + const CHUNK_DURATION = 0.1; + const SAMPLE_RATE = 24000; + const BYTES_PER_SAMPLE = 2; + const CHANNELS = 2; + const CHUNK_SIZE = SAMPLE_RATE * BYTES_PER_SAMPLE * CHANNELS * CHUNK_DURATION; + + let audioBuffer = Buffer.alloc(0); + + const provider = await this.getAiProvider(); + const isGemini = provider === 'gemini'; + + this.systemAudioProc.stdout.on('data', async data => { + audioBuffer = Buffer.concat([audioBuffer, data]); + + while (audioBuffer.length >= CHUNK_SIZE) { + const chunk = audioBuffer.slice(0, CHUNK_SIZE); + audioBuffer = audioBuffer.slice(CHUNK_SIZE); + + const monoChunk = CHANNELS === 2 ? this.convertStereoToMono(chunk) : chunk; + const base64Data = monoChunk.toString('base64'); + + this.sendToRenderer('system-audio-data', { data: base64Data }); + + if (this.theirSttSession) { + try { + const payload = isGemini + ? { audio: { data: base64Data, mimeType: 'audio/pcm;rate=24000' } } + : base64Data; + await this.theirSttSession.sendRealtimeInput(payload); + } catch (err) { + console.error('Error sending system audio:', err.message); + } + } + } + }); + + this.systemAudioProc.stderr.on('data', data => { + console.error('SystemAudioDump stderr:', data.toString()); + }); + + this.systemAudioProc.on('close', code => { + console.log('SystemAudioDump process closed with code:', code); + this.systemAudioProc = null; + }); + + this.systemAudioProc.on('error', err => { + console.error('SystemAudioDump process error:', err); + this.systemAudioProc = null; + }); + + return true; + } + + convertStereoToMono(stereoBuffer) { + const samples = stereoBuffer.length / 4; + const monoBuffer = Buffer.alloc(samples * 2); + + for (let i = 0; i < samples; i++) { + const leftSample = stereoBuffer.readInt16LE(i * 4); + monoBuffer.writeInt16LE(leftSample, i * 2); + } + + return monoBuffer; + } + + stopMacOSAudioCapture() { + if (this.systemAudioProc) { + console.log('Stopping SystemAudioDump...'); + this.systemAudioProc.kill('SIGTERM'); + this.systemAudioProc = null; + } + } + + isSessionActive() { + return !!this.mySttSession && !!this.theirSttSession; + } + + async closeSessions() { + this.stopMacOSAudioCapture(); + + // Clear timers + if (this.myInactivityTimer) { + clearTimeout(this.myInactivityTimer); + this.myInactivityTimer = null; + } + if (this.theirInactivityTimer) { + clearTimeout(this.theirInactivityTimer); + this.theirInactivityTimer = null; + } + if (this.myCompletionTimer) { + clearTimeout(this.myCompletionTimer); + this.myCompletionTimer = null; + } + if (this.theirCompletionTimer) { + clearTimeout(this.theirCompletionTimer); + this.theirCompletionTimer = null; + } + + const closePromises = []; + if (this.mySttSession) { + closePromises.push(this.mySttSession.close()); + this.mySttSession = null; + } + if (this.theirSttSession) { + closePromises.push(this.theirSttSession.close()); + this.theirSttSession = null; + } + + await Promise.all(closePromises); + console.log('All STT sessions closed.'); + + // Reset state + this.myCurrentUtterance = ''; + this.theirCurrentUtterance = ''; + this.myLastPartialText = ''; + this.theirLastPartialText = ''; + this.myCompletionBuffer = ''; + this.theirCompletionBuffer = ''; + } +} + +module.exports = SttService; \ No newline at end of file diff --git a/src/features/listen/summary/repositories/index.js b/src/features/listen/summary/repositories/index.js new file mode 100644 index 0000000..d5bd3b3 --- /dev/null +++ b/src/features/listen/summary/repositories/index.js @@ -0,0 +1,5 @@ +const summaryRepository = require('./sqlite.repository'); + +module.exports = { + ...summaryRepository, +}; \ No newline at end of file diff --git a/src/features/listen/summary/repositories/sqlite.repository.js b/src/features/listen/summary/repositories/sqlite.repository.js new file mode 100644 index 0000000..d7a2266 --- /dev/null +++ b/src/features/listen/summary/repositories/sqlite.repository.js @@ -0,0 +1,47 @@ +const sqliteClient = require('../../../../common/services/sqliteClient'); + +function saveSummary({ sessionId, tldr, text, bullet_json, action_json, model = 'gpt-4.1' }) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const now = Math.floor(Date.now() / 1000); + const query = ` + INSERT INTO summaries (session_id, generated_at, model, text, tldr, bullet_json, action_json, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(session_id) DO UPDATE SET + generated_at=excluded.generated_at, + model=excluded.model, + text=excluded.text, + tldr=excluded.tldr, + bullet_json=excluded.bullet_json, + action_json=excluded.action_json, + updated_at=excluded.updated_at + `; + db.run(query, [sessionId, now, model, text, tldr, bullet_json, action_json, now], function(err) { + if (err) { + console.error('Error saving summary:', err); + reject(err); + } else { + resolve({ changes: this.changes }); + } + }); + }); +} + +function getSummaryBySessionId(sessionId) { + const db = sqliteClient.getDb(); + return new Promise((resolve, reject) => { + const query = "SELECT * FROM summaries WHERE session_id = ?"; + db.get(query, [sessionId], (err, row) => { + if (err) { + reject(err); + } else { + resolve(row || null); + } + }); + }); +} + +module.exports = { + saveSummary, + getSummaryBySessionId, +}; \ No newline at end of file diff --git a/src/features/listen/summary/summaryService.js b/src/features/listen/summary/summaryService.js new file mode 100644 index 0000000..7cffa99 --- /dev/null +++ b/src/features/listen/summary/summaryService.js @@ -0,0 +1,357 @@ +const { BrowserWindow } = require('electron'); +const { getSystemPrompt } = require('../../../common/prompts/promptBuilder.js'); +const { makeChatCompletionWithPortkey } = require('../../../common/services/aiProviderService.js'); +const authService = require('../../../common/services/authService'); +const sessionRepository = require('../../../common/repositories/session'); +const summaryRepository = require('./repositories'); +const { getStoredApiKey, getStoredProvider } = require('../../../electron/windowManager'); + +class SummaryService { + constructor() { + this.previousAnalysisResult = null; + this.analysisHistory = []; + this.conversationHistory = []; + this.currentSessionId = null; + + // Callbacks + this.onAnalysisComplete = null; + this.onStatusUpdate = null; + } + + setCallbacks({ onAnalysisComplete, onStatusUpdate }) { + this.onAnalysisComplete = onAnalysisComplete; + this.onStatusUpdate = onStatusUpdate; + } + + setSessionId(sessionId) { + this.currentSessionId = sessionId; + } + + async getApiKey() { + const storedKey = await getStoredApiKey(); + if (storedKey) { + console.log('[SummaryService] Using stored API key'); + return storedKey; + } + + const envKey = process.env.OPENAI_API_KEY; + if (envKey) { + console.log('[SummaryService] Using environment API key'); + return envKey; + } + + console.error('[SummaryService] No API key found in storage or environment'); + return null; + } + + sendToRenderer(channel, data) { + BrowserWindow.getAllWindows().forEach(win => { + if (!win.isDestroyed()) { + win.webContents.send(channel, data); + } + }); + } + + addConversationTurn(speaker, text) { + const conversationText = `${speaker.toLowerCase()}: ${text.trim()}`; + this.conversationHistory.push(conversationText); + console.log(`💬 Added conversation text: ${conversationText}`); + console.log(`📈 Total conversation history: ${this.conversationHistory.length} texts`); + + // Trigger analysis if needed + this.triggerAnalysisIfNeeded(); + } + + getConversationHistory() { + return this.conversationHistory; + } + + resetConversationHistory() { + this.conversationHistory = []; + this.previousAnalysisResult = null; + this.analysisHistory = []; + console.log('🔄 Conversation history and analysis state reset'); + } + + /** + * Converts conversation history into text to include in the prompt. + * @param {Array} conversationTexts - Array of conversation texts ["me: ~~~", "them: ~~~", ...] + * @param {number} maxTurns - Maximum number of recent turns to include + * @returns {string} - Formatted conversation string for the prompt + */ + formatConversationForPrompt(conversationTexts, maxTurns = 30) { + if (conversationTexts.length === 0) return ''; + return conversationTexts.slice(-maxTurns).join('\n'); + } + + async makeOutlineAndRequests(conversationTexts, maxTurns = 30) { + console.log(`🔍 makeOutlineAndRequests called - conversationTexts: ${conversationTexts.length}`); + + if (conversationTexts.length === 0) { + console.log('⚠️ No conversation texts available for analysis'); + return null; + } + + const recentConversation = this.formatConversationForPrompt(conversationTexts, maxTurns); + + // 이전 분석 결과를 프롬프트에 포함 + let contextualPrompt = ''; + if (this.previousAnalysisResult) { + contextualPrompt = ` +Previous Analysis Context: +- Main Topic: ${this.previousAnalysisResult.topic.header} +- Key Points: ${this.previousAnalysisResult.summary.slice(0, 3).join(', ')} +- Last Actions: ${this.previousAnalysisResult.actions.slice(0, 2).join(', ')} + +Please build upon this context while analyzing the new conversation segments. +`; + } + + const basePrompt = getSystemPrompt('pickle_glass_analysis', '', false); + const systemPrompt = basePrompt.replace('{{CONVERSATION_HISTORY}}', recentConversation); + + try { + if (this.currentSessionId) { + await sessionRepository.touch(this.currentSessionId); + } + + const messages = [ + { + role: 'system', + content: systemPrompt, + }, + { + role: 'user', + content: `${contextualPrompt} + +Analyze the conversation and provide a structured summary. Format your response as follows: + +**Summary Overview** +- Main discussion point with context + +**Key Topic: [Topic Name]** +- First key insight +- Second key insight +- Third key insight + +**Extended Explanation** +Provide 2-3 sentences explaining the context and implications. + +**Suggested Questions** +1. First follow-up question? +2. Second follow-up question? +3. Third follow-up question? + +Keep all points concise and build upon previous analysis if provided.`, + }, + ]; + + console.log('🤖 Sending analysis request to AI...'); + + const API_KEY = await this.getApiKey(); + if (!API_KEY) { + throw new Error('No API key available'); + } + + const provider = getStoredProvider ? await getStoredProvider() : 'openai'; + const loggedIn = authService.getCurrentUser().isLoggedIn; + const usePortkey = loggedIn && provider === 'openai'; + + console.log(`[SummaryService] provider: ${provider}, usePortkey: ${usePortkey}`); + + const completion = await makeChatCompletionWithPortkey({ + apiKey: API_KEY, + provider: provider, + messages: messages, + temperature: 0.7, + maxTokens: 1024, + model: provider === 'openai' ? 'gpt-4.1' : 'gemini-2.5-flash', + usePortkey: usePortkey, + portkeyVirtualKey: usePortkey ? API_KEY : null + }); + + const responseText = completion.content; + console.log(`✅ Analysis response received: ${responseText}`); + const structuredData = this.parseResponseText(responseText, this.previousAnalysisResult); + + if (this.currentSessionId) { + summaryRepository.saveSummary({ + sessionId: this.currentSessionId, + text: responseText, + tldr: structuredData.summary.join('\n'), + bullet_json: JSON.stringify(structuredData.topic.bullets), + action_json: JSON.stringify(structuredData.actions), + model: 'gpt-4.1' + }).catch(err => console.error('[DB] Failed to save summary:', err)); + } + + // 분석 결과 저장 + this.previousAnalysisResult = structuredData; + this.analysisHistory.push({ + timestamp: Date.now(), + data: structuredData, + conversationLength: conversationTexts.length, + }); + + // 히스토리 크기 제한 (최근 10개만 유지) + if (this.analysisHistory.length > 10) { + this.analysisHistory.shift(); + } + + return structuredData; + } catch (error) { + console.error('❌ Error during analysis generation:', error.message); + return this.previousAnalysisResult; // 에러 시 이전 결과 반환 + } + } + + parseResponseText(responseText, previousResult) { + const structuredData = { + summary: [], + topic: { header: '', bullets: [] }, + actions: [], + followUps: ['✉️ Draft a follow-up email', '✅ Generate action items', '📝 Show summary'], + }; + + // 이전 결과가 있으면 기본값으로 사용 + if (previousResult) { + structuredData.topic.header = previousResult.topic.header; + structuredData.summary = [...previousResult.summary]; + } + + try { + const lines = responseText.split('\n'); + let currentSection = ''; + let isCapturingTopic = false; + let topicName = ''; + + for (const line of lines) { + const trimmedLine = line.trim(); + + // 섹션 헤더 감지 + if (trimmedLine.startsWith('**Summary Overview**')) { + currentSection = 'summary-overview'; + continue; + } else if (trimmedLine.startsWith('**Key Topic:')) { + currentSection = 'topic'; + isCapturingTopic = true; + topicName = trimmedLine.match(/\*\*Key Topic: (.+?)\*\*/)?.[1] || ''; + if (topicName) { + structuredData.topic.header = topicName + ':'; + } + continue; + } else if (trimmedLine.startsWith('**Extended Explanation**')) { + currentSection = 'explanation'; + continue; + } else if (trimmedLine.startsWith('**Suggested Questions**')) { + currentSection = 'questions'; + continue; + } + + // 컨텐츠 파싱 + if (trimmedLine.startsWith('-') && currentSection === 'summary-overview') { + const summaryPoint = trimmedLine.substring(1).trim(); + if (summaryPoint && !structuredData.summary.includes(summaryPoint)) { + // 기존 summary 업데이트 (최대 5개 유지) + structuredData.summary.unshift(summaryPoint); + if (structuredData.summary.length > 5) { + structuredData.summary.pop(); + } + } + } else if (trimmedLine.startsWith('-') && currentSection === 'topic') { + const bullet = trimmedLine.substring(1).trim(); + if (bullet && structuredData.topic.bullets.length < 3) { + structuredData.topic.bullets.push(bullet); + } + } else if (currentSection === 'explanation' && trimmedLine) { + // explanation을 topic bullets에 추가 (문장 단위로) + const sentences = trimmedLine + .split(/\.\s+/) + .filter(s => s.trim().length > 0) + .map(s => s.trim() + (s.endsWith('.') ? '' : '.')); + + sentences.forEach(sentence => { + if (structuredData.topic.bullets.length < 3 && !structuredData.topic.bullets.includes(sentence)) { + structuredData.topic.bullets.push(sentence); + } + }); + } else if (trimmedLine.match(/^\d+\./) && currentSection === 'questions') { + const question = trimmedLine.replace(/^\d+\.\s*/, '').trim(); + if (question && question.includes('?')) { + structuredData.actions.push(`❓ ${question}`); + } + } + } + + // 기본 액션 추가 + const defaultActions = ['✨ What should I say next?', '💬 Suggest follow-up questions']; + defaultActions.forEach(action => { + if (!structuredData.actions.includes(action)) { + structuredData.actions.push(action); + } + }); + + // 액션 개수 제한 + structuredData.actions = structuredData.actions.slice(0, 5); + + // 유효성 검증 및 이전 데이터 병합 + if (structuredData.summary.length === 0 && previousResult) { + structuredData.summary = previousResult.summary; + } + if (structuredData.topic.bullets.length === 0 && previousResult) { + structuredData.topic.bullets = previousResult.topic.bullets; + } + } catch (error) { + console.error('❌ Error parsing response text:', error); + // 에러 시 이전 결과 반환 + return ( + previousResult || { + summary: [], + topic: { header: 'Analysis in progress', bullets: [] }, + actions: ['✨ What should I say next?', '💬 Suggest follow-up questions'], + followUps: ['✉️ Draft a follow-up email', '✅ Generate action items', '📝 Show summary'], + } + ); + } + + console.log('📊 Final structured data:', JSON.stringify(structuredData, null, 2)); + return structuredData; + } + + /** + * Triggers analysis when conversation history reaches 5 texts. + */ + async triggerAnalysisIfNeeded() { + if (this.conversationHistory.length >= 5 && this.conversationHistory.length % 5 === 0) { + console.log(`🚀 Triggering analysis (non-blocking) - ${this.conversationHistory.length} conversation texts accumulated`); + + this.makeOutlineAndRequests(this.conversationHistory) + .then(data => { + if (data) { + console.log('📤 Sending structured data to renderer'); + this.sendToRenderer('update-structured-data', data); + + // Notify callback + if (this.onAnalysisComplete) { + this.onAnalysisComplete(data); + } + } else { + console.log('❌ No analysis data returned from non-blocking call'); + } + }) + .catch(error => { + console.error('❌ Error in non-blocking analysis:', error); + }); + } + } + + getCurrentAnalysisData() { + return { + previousResult: this.previousAnalysisResult, + history: this.analysisHistory, + conversationLength: this.conversationHistory.length, + }; + } +} + +module.exports = SummaryService; \ No newline at end of file diff --git a/src/index.js b/src/index.js index ea8224b..1cca48f 100644 --- a/src/index.js +++ b/src/index.js @@ -13,7 +13,7 @@ if (require('electron-squirrel-startup')) { const { app, BrowserWindow, shell, ipcMain, dialog } = require('electron'); const { createWindows } = require('./electron/windowManager.js'); -const { setupLiveSummaryIpcHandlers, stopMacOSAudioCapture } = require('./features/listen/liveSummaryService.js'); +const ListenService = require('./features/listen/listenService'); const { initializeFirebase } = require('./common/services/firebaseClient'); const databaseInitializer = require('./common/services/databaseInitializer'); const authService = require('./common/services/authService'); @@ -29,7 +29,9 @@ const sessionRepository = require('./common/repositories/session'); const eventBridge = new EventEmitter(); let WEB_PORT = 3000; -const openaiSessionRef = { current: null }; +const listenService = new ListenService(); +// Make listenService globally accessible so other modules (e.g., windowManager, askService) can reuse the same instance +global.listenService = listenService; let deeplink = null; // Initialize as null let pendingDeepLinkUrl = null; // Store any deep link that arrives before initialization @@ -106,7 +108,7 @@ app.whenReady().then(async () => { sessionRepository.endAllActiveSessions(); authService.initialize(); - setupLiveSummaryIpcHandlers(openaiSessionRef); + listenService.setupIpcHandlers(); askService.initialize(); setupGeneralIpcHandlers(); }) @@ -123,7 +125,7 @@ app.whenReady().then(async () => { }); app.on('window-all-closed', () => { - stopMacOSAudioCapture(); + listenService.stopMacOSAudioCapture(); if (process.platform !== 'darwin') { app.quit(); } @@ -131,7 +133,7 @@ app.on('window-all-closed', () => { app.on('before-quit', async () => { console.log('[Shutdown] App is about to quit.'); - stopMacOSAudioCapture(); + listenService.stopMacOSAudioCapture(); await sessionRepository.endAllActiveSessions(); databaseInitializer.close(); }); @@ -210,7 +212,8 @@ function setupGeneralIpcHandlers() { function setupWebDataHandlers() { const sessionRepository = require('./common/repositories/session'); - const listenRepository = require('./features/listen/repositories'); + const sttRepository = require('./features/listen/stt/repositories'); + const summaryRepository = require('./features/listen/summary/repositories'); const askRepository = require('./features/ask/repositories'); const userRepository = require('./common/repositories/user'); const presetRepository = require('./common/repositories/preset'); @@ -230,9 +233,9 @@ function setupWebDataHandlers() { result = null; break; } - const transcripts = await listenRepository.getAllTranscriptsBySessionId(payload); + const transcripts = await sttRepository.getAllTranscriptsBySessionId(payload); const ai_messages = await askRepository.getAllAiMessagesBySessionId(payload); - const summary = await listenRepository.getSummaryBySessionId(payload); + const summary = await summaryRepository.getSummaryBySessionId(payload); result = { session, transcripts, ai_messages, summary }; break; case 'delete-session': From 549a3cdeb9f45c7721f577a81ef83e08208bc5e9 Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Mon, 7 Jul 2025 06:17:42 +0900 Subject: [PATCH 05/52] settings big update --- src/features/settings/repositories/index.js | 2 - .../repositories/sqlite.repository.js | 160 +++--------------- src/features/settings/settingsService.js | 60 ++++--- 3 files changed, 59 insertions(+), 163 deletions(-) diff --git a/src/features/settings/repositories/index.js b/src/features/settings/repositories/index.js index 899e5df..508ebe5 100644 --- a/src/features/settings/repositories/index.js +++ b/src/features/settings/repositories/index.js @@ -13,8 +13,6 @@ function getRepository() { // Directly export functions for ease of use, decided by the strategy module.exports = { - getSettings: (...args) => getRepository().getSettings(...args), - saveSettings: (...args) => getRepository().saveSettings(...args), getPresets: (...args) => getRepository().getPresets(...args), getPresetTemplates: (...args) => getRepository().getPresetTemplates(...args), createPreset: (...args) => getRepository().createPreset(...args), diff --git a/src/features/settings/repositories/sqlite.repository.js b/src/features/settings/repositories/sqlite.repository.js index def54cb..82d0c01 100644 --- a/src/features/settings/repositories/sqlite.repository.js +++ b/src/features/settings/repositories/sqlite.repository.js @@ -1,127 +1,5 @@ const sqliteClient = require('../../../common/services/sqliteClient'); -function getSettings(uid) { - const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = ` - SELECT * FROM user_settings - WHERE uid = ? - `; - db.get(query, [uid], (err, row) => { - if (err) { - console.error('SQLite: Failed to get settings:', err); - reject(err); - } else if (row) { - // Parse JSON fields - try { - if (row.keybinds) row.keybinds = JSON.parse(row.keybinds); - } catch (parseError) { - console.warn('SQLite: Failed to parse keybinds JSON:', parseError); - row.keybinds = {}; - } - resolve(row); - } else { - // Return default settings if none exist - resolve({ - uid: uid, - profile: 'school', - language: 'en', - screenshot_interval: '5000', - image_quality: '0.8', - layout_mode: 'stacked', - keybinds: {}, - throttle_tokens: 500, - max_tokens: 2000, - throttle_percent: 80, - google_search_enabled: 0, - background_transparency: 0.5, - font_size: 14, - content_protection: 1, - created_at: Math.floor(Date.now() / 1000), - updated_at: Math.floor(Date.now() / 1000) - }); - } - }); - }); -} - -function saveSettings(uid, settings) { - const db = sqliteClient.getDb(); - const now = Math.floor(Date.now() / 1000); - - return new Promise((resolve, reject) => { - // Prepare settings object - const settingsToSave = { - uid: uid, - profile: settings.profile || 'school', - language: settings.language || 'en', - screenshot_interval: settings.screenshot_interval || '5000', - image_quality: settings.image_quality || '0.8', - layout_mode: settings.layout_mode || 'stacked', - keybinds: JSON.stringify(settings.keybinds || {}), - throttle_tokens: settings.throttle_tokens || 500, - max_tokens: settings.max_tokens || 2000, - throttle_percent: settings.throttle_percent || 80, - google_search_enabled: settings.google_search_enabled ? 1 : 0, - background_transparency: settings.background_transparency || 0.5, - font_size: settings.font_size || 14, - content_protection: settings.content_protection ? 1 : 0, - updated_at: now - }; - - const query = ` - INSERT INTO user_settings ( - uid, profile, language, screenshot_interval, image_quality, layout_mode, - keybinds, throttle_tokens, max_tokens, throttle_percent, google_search_enabled, - background_transparency, font_size, content_protection, created_at, updated_at - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(uid) DO UPDATE SET - profile=excluded.profile, - language=excluded.language, - screenshot_interval=excluded.screenshot_interval, - image_quality=excluded.image_quality, - layout_mode=excluded.layout_mode, - keybinds=excluded.keybinds, - throttle_tokens=excluded.throttle_tokens, - max_tokens=excluded.max_tokens, - throttle_percent=excluded.throttle_percent, - google_search_enabled=excluded.google_search_enabled, - background_transparency=excluded.background_transparency, - font_size=excluded.font_size, - content_protection=excluded.content_protection, - updated_at=excluded.updated_at - `; - - const values = [ - settingsToSave.uid, - settingsToSave.profile, - settingsToSave.language, - settingsToSave.screenshot_interval, - settingsToSave.image_quality, - settingsToSave.layout_mode, - settingsToSave.keybinds, - settingsToSave.throttle_tokens, - settingsToSave.max_tokens, - settingsToSave.throttle_percent, - settingsToSave.google_search_enabled, - settingsToSave.background_transparency, - settingsToSave.font_size, - settingsToSave.content_protection, - now, // created_at - settingsToSave.updated_at - ]; - - db.run(query, values, function(err) { - if (err) { - console.error('SQLite: Failed to save settings:', err); - reject(err); - } else { - resolve({ changes: this.changes }); - } - }); - }); -} - function getPresets(uid) { const db = sqliteClient.getDb(); return new Promise((resolve, reject) => { @@ -162,17 +40,19 @@ function getPresetTemplates() { function createPreset({ uid, title, prompt }) { const db = sqliteClient.getDb(); - const presetId = require('crypto').randomUUID(); - const now = Math.floor(Date.now() / 1000); - const query = `INSERT INTO prompt_presets (id, uid, title, prompt, is_default, created_at, sync_state) VALUES (?, ?, ?, ?, 0, ?, 'dirty')`; - return new Promise((resolve, reject) => { - db.run(query, [presetId, uid, title, prompt, now], function(err) { + const id = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = ` + INSERT INTO prompt_presets (id, uid, title, prompt, is_default, created_at, sync_state) + VALUES (?, ?, ?, ?, 0, ?, 'dirty') + `; + db.run(query, [id, uid, title, prompt, now], function(err) { if (err) { console.error('SQLite: Failed to create preset:', err); reject(err); } else { - resolve({ id: presetId }); + resolve({ id }); } }); }); @@ -180,15 +60,19 @@ function createPreset({ uid, title, prompt }) { function updatePreset(id, { title, prompt }, uid) { const db = sqliteClient.getDb(); - const query = `UPDATE prompt_presets SET title = ?, prompt = ?, sync_state = 'dirty' WHERE id = ? AND uid = ? AND is_default = 0`; - return new Promise((resolve, reject) => { - db.run(query, [title, prompt, id, uid], function(err) { + const now = Math.floor(Date.now() / 1000); + const query = ` + UPDATE prompt_presets + SET title = ?, prompt = ?, sync_state = 'dirty', updated_at = ? + WHERE id = ? AND uid = ? AND is_default = 0 + `; + db.run(query, [title, prompt, now, id, uid], function(err) { if (err) { console.error('SQLite: Failed to update preset:', err); reject(err); } else if (this.changes === 0) { - reject(new Error("Preset not found or permission denied.")); + reject(new Error('Preset not found, is default, or permission denied')); } else { resolve({ changes: this.changes }); } @@ -198,15 +82,17 @@ function updatePreset(id, { title, prompt }, uid) { function deletePreset(id, uid) { const db = sqliteClient.getDb(); - const query = `DELETE FROM prompt_presets WHERE id = ? AND uid = ? AND is_default = 0`; - return new Promise((resolve, reject) => { + const query = ` + DELETE FROM prompt_presets + WHERE id = ? AND uid = ? AND is_default = 0 + `; db.run(query, [id, uid], function(err) { if (err) { console.error('SQLite: Failed to delete preset:', err); reject(err); } else if (this.changes === 0) { - reject(new Error("Preset not found or permission denied.")); + reject(new Error('Preset not found, is default, or permission denied')); } else { resolve({ changes: this.changes }); } @@ -215,11 +101,9 @@ function deletePreset(id, uid) { } module.exports = { - getSettings, - saveSettings, getPresets, getPresetTemplates, createPreset, updatePreset, - deletePreset, + deletePreset }; \ No newline at end of file diff --git a/src/features/settings/settingsService.js b/src/features/settings/settingsService.js index e8df973..6360f36 100644 --- a/src/features/settings/settingsService.js +++ b/src/features/settings/settingsService.js @@ -1,9 +1,17 @@ const { ipcMain, BrowserWindow } = require('electron'); +const Store = require('electron-store'); const authService = require('../../common/services/authService'); const userRepository = require('../../common/repositories/user'); const settingsRepository = require('./repositories'); const { getStoredApiKey, getStoredProvider, windowPool } = require('../../electron/windowManager'); +const store = new Store({ + name: 'pickle-glass-settings', + defaults: { + users: {} + } +}); + // Configuration constants const NOTIFICATION_CONFIG = { RELEVANT_WINDOW_TYPES: ['settings', 'main'], @@ -142,22 +150,6 @@ const DEFAULT_KEYBINDS = { // Service state let currentSettings = null; -async function getSettings() { - try { - const uid = authService.getCurrentUserId(); - if (!uid) { - throw new Error("User not logged in, cannot get settings."); - } - - const settings = await settingsRepository.getSettings(uid); - currentSettings = settings; - return settings; - } catch (error) { - console.error('[SettingsService] Error getting settings:', error); - return null; - } -} - function getDefaultSettings() { const isMac = process.platform === 'darwin'; return { @@ -177,18 +169,39 @@ function getDefaultSettings() { }; } +async function getSettings() { + try { + const uid = authService.getCurrentUserId(); + const userSettingsKey = uid ? `users.${uid}` : 'users.default'; + + const defaultSettings = getDefaultSettings(); + const savedSettings = store.get(userSettingsKey, {}); + + currentSettings = { ...defaultSettings, ...savedSettings }; + return currentSettings; + } catch (error) { + console.error('[SettingsService] Error getting settings from store:', error); + return getDefaultSettings(); + } +} + async function saveSettings(settings) { try { const uid = authService.getCurrentUserId(); - if (!uid) { - throw new Error("User not logged in, cannot save settings."); - } + const userSettingsKey = uid ? `users.${uid}` : 'users.default'; - await settingsRepository.saveSettings(uid, settings); - currentSettings = settings; + const currentSaved = store.get(userSettingsKey, {}); + const newSettings = { ...currentSaved, ...settings }; + + store.set(userSettingsKey, newSettings); + currentSettings = newSettings; + + // Use smart notification system + windowNotificationManager.notifyRelevantWindows('settings-updated', currentSettings); + return { success: true }; } catch (error) { - console.error('[SettingsService] Error saving settings:', error); + console.error('[SettingsService] Error saving settings to store:', error); return { success: false, error: error.message }; } } @@ -197,7 +210,8 @@ async function getPresets() { try { const uid = authService.getCurrentUserId(); if (!uid) { - throw new Error("User not logged in, cannot get presets."); + // Logged out users only see default presets + return await settingsRepository.getPresetTemplates(); } const presets = await settingsRepository.getPresets(uid); From aa9252880b6cf194293edd8008b8fdc30ed1745f Mon Sep 17 00:00:00 2001 From: samtiz Date: Mon, 7 Jul 2025 06:28:48 +0900 Subject: [PATCH 06/52] listen feature refactor done --- src/features/listen/AssistantView.js | 814 ++---------------- src/features/listen/repositories/index.js | 20 - .../listen/repositories/sqlite.repository.js | 66 -- src/features/listen/stt/SttView.js | 228 +++++ src/features/listen/summary/SummaryView.js | 559 ++++++++++++ 5 files changed, 856 insertions(+), 831 deletions(-) delete mode 100644 src/features/listen/repositories/index.js delete mode 100644 src/features/listen/repositories/sqlite.repository.js create mode 100644 src/features/listen/stt/SttView.js create mode 100644 src/features/listen/summary/SummaryView.js diff --git a/src/features/listen/AssistantView.js b/src/features/listen/AssistantView.js index e1584ca..aab6869 100644 --- a/src/features/listen/AssistantView.js +++ b/src/features/listen/AssistantView.js @@ -1,4 +1,6 @@ import { html, css, LitElement } from '../../assets/lit-core-2.7.4.min.js'; +import './stt/SttView.js'; +import './summary/SummaryView.js'; export class AssistantView extends LitElement { static styles = css` @@ -82,73 +84,6 @@ export class AssistantView extends LitElement { user-select: none; } - /* highlight.js 스타일 추가 */ - .insights-container pre { - background: rgba(0, 0, 0, 0.4) !important; - border-radius: 8px !important; - padding: 12px !important; - margin: 8px 0 !important; - overflow-x: auto !important; - border: 1px solid rgba(255, 255, 255, 0.1) !important; - white-space: pre !important; - word-wrap: normal !important; - word-break: normal !important; - } - - .insights-container code { - font-family: 'Monaco', 'Menlo', 'Consolas', monospace !important; - font-size: 11px !important; - background: transparent !important; - white-space: pre !important; - word-wrap: normal !important; - word-break: normal !important; - } - - .insights-container pre code { - white-space: pre !important; - word-wrap: normal !important; - word-break: normal !important; - display: block !important; - } - - .insights-container p code { - background: rgba(255, 255, 255, 0.1) !important; - padding: 2px 4px !important; - border-radius: 3px !important; - color: #ffd700 !important; - } - - .hljs-keyword { - color: #ff79c6 !important; - } - .hljs-string { - color: #f1fa8c !important; - } - .hljs-comment { - color: #6272a4 !important; - } - .hljs-number { - color: #bd93f9 !important; - } - .hljs-function { - color: #50fa7b !important; - } - .hljs-variable { - color: #8be9fd !important; - } - .hljs-built_in { - color: #ffb86c !important; - } - .hljs-title { - color: #50fa7b !important; - } - .hljs-attr { - color: #50fa7b !important; - } - .hljs-tag { - color: #ff79c6 !important; - } - .assistant-container { display: flex; flex-direction: column; @@ -158,8 +93,6 @@ export class AssistantView extends LitElement { background: rgba(0, 0, 0, 0.6); overflow: hidden; border-radius: 12px; - /* outline: 0.5px rgba(255, 255, 255, 0.5) solid; */ - /* outline-offset: -1px; */ width: 100%; min-height: 200px; } @@ -171,7 +104,7 @@ export class AssistantView extends LitElement { left: 0; right: 0; bottom: 0; - border-radius: 12px; /* Match parent */ + border-radius: 12px; padding: 1px; background: linear-gradient(169deg, rgba(255, 255, 255, 0.17) 0%, rgba(255, 255, 255, 0.08) 50%, rgba(255, 255, 255, 0.17) 100%); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); @@ -299,8 +232,8 @@ export class AssistantView extends LitElement { height: 24px; flex-shrink: 0; transition: background-color 0.15s ease; - position: relative; /* For icon positioning */ - overflow: hidden; /* Hide overflowing parts of icons during animation */ + position: relative; + overflow: hidden; } .copy-button:hover { @@ -330,213 +263,6 @@ export class AssistantView extends LitElement { transform: translate(-50%, -50%) scale(1); } - .transcription-container { - overflow-y: auto; - padding: 12px 12px 16px 12px; - display: flex; - flex-direction: column; - gap: 8px; - min-height: 150px; - max-height: 600px; - position: relative; - z-index: 1; - flex: 1; - } - - .transcription-container.hidden { - display: none; - } - - .transcription-container::-webkit-scrollbar { - width: 8px; - } - .transcription-container::-webkit-scrollbar-track { - background: rgba(0, 0, 0, 0.1); - border-radius: 4px; - } - .transcription-container::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - border-radius: 4px; - } - .transcription-container::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.5); - } - - .stt-message { - padding: 8px 12px; - border-radius: 12px; - max-width: 80%; - word-wrap: break-word; - word-break: break-word; - line-height: 1.5; - font-size: 13px; - margin-bottom: 4px; - box-sizing: border-box; - } - - .stt-message.them { - background: rgba(255, 255, 255, 0.1); - color: rgba(255, 255, 255, 0.9); - align-self: flex-start; - border-bottom-left-radius: 4px; - margin-right: auto; - } - - .stt-message.me { - background: rgba(0, 122, 255, 0.8); - color: white; - align-self: flex-end; - border-bottom-right-radius: 4px; - margin-left: auto; - } - - .insights-container { - overflow-y: auto; - padding: 12px 16px 16px 16px; - position: relative; - z-index: 1; - min-height: 150px; - max-height: 600px; - flex: 1; - } - - insights-title { - color: rgba(255, 255, 255, 0.8); - font-size: 15px; - font-weight: 500; - font-family: 'Helvetica Neue', sans-serif; - margin: 12px 0 8px 0; - } - - .insights-container.hidden { - display: none; - } - - .insights-container::-webkit-scrollbar { - width: 8px; - } - .insights-container::-webkit-scrollbar-track { - background: rgba(0, 0, 0, 0.1); - border-radius: 4px; - } - .insights-container::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - border-radius: 4px; - } - .insights-container::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.5); - } - - .insights-container h4 { - color: #ffffff; - font-size: 12px; - font-weight: 600; - margin: 12px 0 8px 0; - padding: 4px 8px; - border-radius: 4px; - background: transparent; - cursor: default; - } - - .insights-container h4:hover { - background: transparent; - } - - .insights-container h4:first-child { - margin-top: 0; - } - - .outline-item { - color: #ffffff; - font-size: 11px; - line-height: 1.4; - margin: 4px 0; - padding: 6px 8px; - border-radius: 4px; - background: transparent; - transition: background-color 0.15s ease; - cursor: pointer; - word-wrap: break-word; - } - - .outline-item:hover { - background: rgba(255, 255, 255, 0.1); - } - - .request-item { - color: #ffffff; - font-size: 12px; - line-height: 1.2; - margin: 4px 0; - padding: 6px 8px; - border-radius: 4px; - background: transparent; - cursor: default; - word-wrap: break-word; - transition: background-color 0.15s ease; - } - - .request-item.clickable { - cursor: pointer; - transition: all 0.15s ease; - } - .request-item.clickable:hover { - background: rgba(255, 255, 255, 0.1); - transform: translateX(2px); - } - - /* 마크다운 렌더링된 콘텐츠 스타일 */ - .markdown-content { - color: #ffffff; - font-size: 11px; - line-height: 1.4; - margin: 4px 0; - padding: 6px 8px; - border-radius: 4px; - background: transparent; - cursor: pointer; - word-wrap: break-word; - transition: all 0.15s ease; - } - - .markdown-content:hover { - background: rgba(255, 255, 255, 0.1); - transform: translateX(2px); - } - - .markdown-content p { - margin: 4px 0; - } - - .markdown-content ul, - .markdown-content ol { - margin: 4px 0; - padding-left: 16px; - } - - .markdown-content li { - margin: 2px 0; - } - - .markdown-content a { - color: #8be9fd; - text-decoration: none; - } - - .markdown-content a:hover { - text-decoration: underline; - } - - .markdown-content strong { - font-weight: 600; - color: #f8f8f2; - } - - .markdown-content em { - font-style: italic; - color: #f1fa8c; - } - .timer { font-family: 'Monaco', 'Menlo', monospace; font-size: 10px; @@ -545,10 +271,6 @@ export class AssistantView extends LitElement { `; static properties = { - structuredData: { type: Object }, - // outlines: { type: Array }, - // analysisRequests: { type: Array }, - sttMessages: { type: Array }, viewMode: { type: String }, isHovering: { type: Boolean }, isAnimating: { type: Boolean }, @@ -561,183 +283,66 @@ export class AssistantView extends LitElement { constructor() { super(); - // this.outlines = []; - // this.analysisRequests = []; - this.structuredData = { - summary: [], - topic: { header: '', bullets: [] }, - actions: [], - followUps: [], - }; this.isSessionActive = false; this.hasCompletedRecording = false; - this.sttMessages = []; this.viewMode = 'insights'; this.isHovering = false; this.isAnimating = false; this.elapsedTime = '00:00'; this.captureStartTime = null; this.timerInterval = null; - this.resizeObserver = null; this.adjustHeightThrottle = null; this.isThrottled = false; - this._shouldScrollAfterUpdate = false; - this.messageIdCounter = 0; this.copyState = 'idle'; this.copyTimeout = null; - // 마크다운 라이브러리 초기화 - this.marked = null; - this.hljs = null; - this.isLibrariesLoaded = false; - this.DOMPurify = null; - this.isDOMPurifyLoaded = false; - - // --- Debug Utilities --- - this._debug = { - enabled: false, // Set to false to disable debug messages - interval: null, - counter: 1, - }; - this.handleSttUpdate = this.handleSttUpdate.bind(this); this.adjustWindowHeight = this.adjustWindowHeight.bind(this); - - this.loadLibraries(); } - // --- Debug Utilities --- - _startDebugStream() { - if (!this._debug.enabled) return; - - this._debug.interval = setInterval(() => { - const speaker = this._debug.counter % 2 === 0 ? 'You' : 'Other Person'; - const text = `이것은 ${this._debug.counter}번째 자동 생성 메시지입니다. UI가 자동으로 조절되는지 확인합니다.`; - - this._debug.counter++; - - this.handleSttUpdate(null, { speaker, text, isFinal: true }); - }, 1000); - } - - _stopDebugStream() { - if (this._debug.interval) { - clearInterval(this._debug.interval); + connectedCallback() { + super.connectedCallback(); + // Only start timer if session is active + if (this.isSessionActive) { + this.startTimer(); } - } + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.on('session-state-changed', (event, { isActive }) => { + const wasActive = this.isSessionActive; + this.isSessionActive = isActive; - async loadLibraries() { - try { - if (!window.marked) { - await this.loadScript('../../assets/marked-4.3.0.min.js'); - } - - if (!window.hljs) { - await this.loadScript('../../assets/highlight-11.9.0.min.js'); - } - - if (!window.DOMPurify) { - await this.loadScript('../../assets/dompurify-3.0.7.min.js'); - } - - this.marked = window.marked; - this.hljs = window.hljs; - this.DOMPurify = window.DOMPurify; - - if (this.marked && this.hljs) { - this.marked.setOptions({ - highlight: (code, lang) => { - if (lang && this.hljs.getLanguage(lang)) { - try { - return this.hljs.highlight(code, { language: lang }).value; - } catch (err) { - console.warn('Highlight error:', err); - } - } - try { - return this.hljs.highlightAuto(code).value; - } catch (err) { - console.warn('Auto highlight error:', err); - } - return code; - }, - breaks: true, - gfm: true, - pedantic: false, - smartypants: false, - xhtml: false, - }); - - this.isLibrariesLoaded = true; - console.log('Markdown libraries loaded successfully'); - } - - if (this.DOMPurify) { - this.isDOMPurifyLoaded = true; - console.log('DOMPurify loaded successfully in AssistantView'); - } - } catch (error) { - console.error('Failed to load libraries:', error); - } - } - - loadScript(src) { - return new Promise((resolve, reject) => { - const script = document.createElement('script'); - script.src = src; - script.onload = resolve; - script.onerror = reject; - document.head.appendChild(script); - }); - } - - parseMarkdown(text) { - if (!text) return ''; - - if (!this.isLibrariesLoaded || !this.marked) { - return text; - } - - try { - return this.marked(text); - } catch (error) { - console.error('Markdown parsing error:', error); - return text; - } - } - - handleMarkdownClick(originalText) { - this.handleRequestClick(originalText); - } - - renderMarkdownContent() { - if (!this.isLibrariesLoaded || !this.marked) { - return; - } - - const markdownElements = this.shadowRoot.querySelectorAll('[data-markdown-id]'); - markdownElements.forEach(element => { - const originalText = element.getAttribute('data-original-text'); - if (originalText) { - try { - let parsedHTML = this.parseMarkdown(originalText); - - if (this.isDOMPurifyLoaded && this.DOMPurify) { - parsedHTML = this.DOMPurify.sanitize(parsedHTML); - - if (this.DOMPurify.removed && this.DOMPurify.removed.length > 0) { - console.warn('Unsafe content detected in insights, showing plain text'); - element.textContent = '⚠️ ' + originalText; - return; - } - } - - element.innerHTML = parsedHTML; - } catch (error) { - console.error('Error rendering markdown for element:', error); - element.textContent = originalText; + if (!wasActive && isActive) { + this.hasCompletedRecording = false; + this.startTimer(); + // Reset child components + this.updateComplete.then(() => { + const sttView = this.shadowRoot.querySelector('stt-view'); + const summaryView = this.shadowRoot.querySelector('summary-view'); + if (sttView) sttView.resetTranscript(); + if (summaryView) summaryView.resetAnalysis(); + }); + this.requestUpdate(); } - } - }); + if (wasActive && !isActive) { + this.hasCompletedRecording = true; + this.stopTimer(); + this.requestUpdate(); + } + }); + } + } + + disconnectedCallback() { + super.disconnectedCallback(); + this.stopTimer(); + + if (this.adjustHeightThrottle) { + clearTimeout(this.adjustHeightThrottle); + this.adjustHeightThrottle = null; + } + if (this.copyTimeout) { + clearTimeout(this.copyTimeout); + } } startTimer() { @@ -766,19 +371,15 @@ export class AssistantView extends LitElement { this.updateComplete .then(() => { const topBar = this.shadowRoot.querySelector('.top-bar'); - const activeContent = - this.viewMode === 'transcript' - ? this.shadowRoot.querySelector('.transcription-container') - : this.shadowRoot.querySelector('.insights-container'); + const activeContent = this.viewMode === 'transcript' + ? this.shadowRoot.querySelector('stt-view') + : this.shadowRoot.querySelector('summary-view'); if (!topBar || !activeContent) return; const topBarHeight = topBar.offsetHeight; - - const contentHeight = activeContent.scrollHeight; - + const contentHeight = activeContent.offsetHeight; const idealHeight = topBarHeight + contentHeight + 20; - const targetHeight = Math.min(700, Math.max(200, idealHeight)); console.log( @@ -808,62 +409,17 @@ export class AssistantView extends LitElement { this.requestUpdate(); } - parseOutlineData() { - const result = { - currentSummary: [], - mainTopicHeading: '', - mainTopicBullets: [], - }; - - if (!this.outlines || this.outlines.length === 0) { - return result; - } - - const allBullets = this.outlines.filter(item => item.startsWith('BULLET::')); - if (allBullets.length > 0) { - result.currentSummary.push(allBullets[0].replace('BULLET::', '').trim()); - } - - const heading = this.outlines.find(item => item.startsWith('HEADING::')); - if (heading) { - result.mainTopicHeading = heading.replace('HEADING::', '').trim(); - } - - if (allBullets.length > 1) { - result.mainTopicBullets = allBullets.slice(1).map(item => item.replace('BULLET::', '').trim()); - } - - return result; - } - async handleCopy() { if (this.copyState === 'copied') return; let textToCopy = ''; if (this.viewMode === 'transcript') { - textToCopy = this.sttMessages.map(msg => `${msg.speaker}: ${msg.text}`).join('\n'); + const sttView = this.shadowRoot.querySelector('stt-view'); + textToCopy = sttView ? sttView.getTranscriptText() : ''; } else { - const data = this.structuredData || { summary: [], topic: { header: '', bullets: [] }, actions: [] }; - let sections = []; - - if (data.summary && data.summary.length > 0) { - sections.push(`Current Summary:\n${data.summary.map(s => `• ${s}`).join('\n')}`); - } - - if (data.topic && data.topic.header && data.topic.bullets.length > 0) { - sections.push(`\n${data.topic.header}:\n${data.topic.bullets.map(b => `• ${b}`).join('\n')}`); - } - - if (data.actions && data.actions.length > 0) { - sections.push(`\nActions:\n${data.actions.map(a => `▸ ${a}`).join('\n')}`); - } - - if (data.followUps && data.followUps.length > 0) { - sections.push(`\nFollow-Ups:\n${data.followUps.map(f => `▸ ${f}`).join('\n')}`); - } - - textToCopy = sections.join('\n\n').trim(); + const summaryView = this.shadowRoot.querySelector('summary-view'); + textToCopy = summaryView ? summaryView.getSummaryText() : ''; } try { @@ -900,177 +456,24 @@ export class AssistantView extends LitElement { }, 16); } - handleSttUpdate(event, { speaker, text, isFinal, isPartial }) { - if (text === undefined) return; + updated(changedProperties) { + super.updated(changedProperties); - const container = this.shadowRoot.querySelector('.transcription-container'); - this._shouldScrollAfterUpdate = container ? container.scrollTop + container.clientHeight >= container.scrollHeight - 10 : false; - - const findLastPartialIdx = spk => { - for (let i = this.sttMessages.length - 1; i >= 0; i--) { - const m = this.sttMessages[i]; - if (m.speaker === spk && m.isPartial) return i; - } - return -1; - }; - - const newMessages = [...this.sttMessages]; - const targetIdx = findLastPartialIdx(speaker); - - if (isPartial) { - if (targetIdx !== -1) { - newMessages[targetIdx] = { - ...newMessages[targetIdx], - text, - isPartial: true, - isFinal: false, - }; - } else { - newMessages.push({ - id: this.messageIdCounter++, - speaker, - text, - isPartial: true, - isFinal: false, - }); - } - } else if (isFinal) { - if (targetIdx !== -1) { - newMessages[targetIdx] = { - ...newMessages[targetIdx], - text, - isPartial: false, - isFinal: true, - }; - } else { - newMessages.push({ - id: this.messageIdCounter++, - speaker, - text, - isPartial: false, - isFinal: true, - }); - } - } - - this.sttMessages = newMessages; - } - - scrollToTranscriptionBottom() { - setTimeout(() => { - const container = this.shadowRoot.querySelector('.transcription-container'); - if (container) { - container.scrollTop = container.scrollHeight; - } - }, 0); - } - - async handleRequestClick(requestText) { - console.log('🔥 Analysis request clicked:', requestText); - - if (window.require) { - const { ipcRenderer } = window.require('electron'); - - try { - const isAskViewVisible = await ipcRenderer.invoke('is-window-visible', 'ask'); - - if (!isAskViewVisible) { - await ipcRenderer.invoke('toggle-feature', 'ask'); - await new Promise(resolve => setTimeout(resolve, 100)); - } - - const result = await ipcRenderer.invoke('send-question-to-ask', requestText); - - if (result.success) { - console.log('✅ Question sent to AskView successfully'); - } else { - console.error('❌ Failed to send question to AskView:', result.error); - } - } catch (error) { - console.error('❌ Error in handleRequestClick:', error); - } + if (changedProperties.has('viewMode')) { + this.adjustWindowHeight(); } } - connectedCallback() { - super.connectedCallback(); - this.startTimer(); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.on('stt-update', this.handleSttUpdate); - ipcRenderer.on('session-state-changed', (event, { isActive }) => { - const wasActive = this.isSessionActive; - this.isSessionActive = isActive; - - if (!wasActive && isActive) { - this.hasCompletedRecording = false; - - // 🔄 Reset transcript & analysis when a fresh session starts - this.sttMessages = []; - this.structuredData = { - summary: [], - topic: { header: '', bullets: [] }, - actions: [], - followUps: [], - }; - this.requestUpdate(); - } - if (wasActive && !isActive) { - this.hasCompletedRecording = true; - - this.requestUpdate(); - } - }); - } - this._startDebugStream(); - } - - disconnectedCallback() { - super.disconnectedCallback(); - this.stopTimer(); - - if (this.adjustHeightThrottle) { - clearTimeout(this.adjustHeightThrottle); - this.adjustHeightThrottle = null; - } - if (this.copyTimeout) { - clearTimeout(this.copyTimeout); - } - - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.removeListener('stt-update', this.handleSttUpdate); - } - - this._stopDebugStream(); + handleSttMessagesUpdated(event) { + // Handle messages update from SttView if needed + this.adjustWindowHeightThrottled(); } firstUpdated() { super.firstUpdated(); - setTimeout(() => this.adjustWindowHeight(), 200); } - updated(changedProperties) { - super.updated(changedProperties); - - this.renderMarkdownContent(); - - if (changedProperties.has('sttMessages')) { - if (this._shouldScrollAfterUpdate) { - this.scrollToTranscriptionBottom(); - this._shouldScrollAfterUpdate = false; - } - this.adjustWindowHeightThrottled(); - } - - if (changedProperties.has('viewMode')) { - this.adjustWindowHeight(); - } else if (changedProperties.has('outlines') || changedProperties.has('analysisRequests') || changedProperties.has('structuredData')) { - this.adjustWindowHeightThrottled(); - } - } - render() { const displayText = this.isHovering ? this.viewMode === 'transcript' @@ -1080,16 +483,6 @@ export class AssistantView extends LitElement { ? `Live insights` : `Glass is Listening ${this.elapsedTime}`; - const data = this.structuredData || { - summary: [], - topic: { header: '', bullets: [] }, - actions: [], - }; - - const getSpeakerClass = speaker => { - return speaker.toLowerCase() === 'me' ? 'me' : 'them'; - }; - return html`
@@ -1131,84 +524,15 @@ export class AssistantView extends LitElement {
-
- ${this.sttMessages.map(msg => html`
${msg.text}
`)} -
+ -
- Current Summary - ${data.summary.length > 0 - ? data.summary - .slice(0, 5) - .map( - (bullet, index) => html` -
this.handleMarkdownClick(bullet)} - > - ${bullet} -
- ` - ) - : html`
No content yet...
`} - ${data.topic.header - ? html` - ${data.topic.header} - ${data.topic.bullets - .slice(0, 3) - .map( - (bullet, index) => html` -
this.handleMarkdownClick(bullet)} - > - ${bullet} -
- ` - )} - ` - : ''} - ${data.actions.length > 0 - ? html` - Actions - ${data.actions - .slice(0, 5) - .map( - (action, index) => html` -
this.handleMarkdownClick(action)} - > - ${action} -
- ` - )} - ` - : ''} - ${this.hasCompletedRecording && data.followUps && data.followUps.length > 0 - ? html` - Follow-Ups - ${data.followUps.map( - (followUp, index) => html` -
this.handleMarkdownClick(followUp)} - > - ${followUp} -
- ` - )} - ` - : ''} -
+ `; } diff --git a/src/features/listen/repositories/index.js b/src/features/listen/repositories/index.js deleted file mode 100644 index 9c0d12f..0000000 --- a/src/features/listen/repositories/index.js +++ /dev/null @@ -1,20 +0,0 @@ -const sqliteRepository = require('./sqlite.repository'); -// const firebaseRepository = require('./firebase.repository'); // Future implementation -const authService = require('../../../common/services/authService'); - -function getRepository() { - // In the future, we can check the user's login status from authService - // const user = authService.getCurrentUser(); - // if (user.isLoggedIn) { - // return firebaseRepository; - // } - return sqliteRepository; -} - -// Directly export functions for ease of use, decided by the strategy -module.exports = { - addTranscript: (...args) => getRepository().addTranscript(...args), - saveSummary: (...args) => getRepository().saveSummary(...args), - getAllTranscriptsBySessionId: (...args) => getRepository().getAllTranscriptsBySessionId(...args), - getSummaryBySessionId: (...args) => getRepository().getSummaryBySessionId(...args), -}; \ No newline at end of file diff --git a/src/features/listen/repositories/sqlite.repository.js b/src/features/listen/repositories/sqlite.repository.js deleted file mode 100644 index 7d293cd..0000000 --- a/src/features/listen/repositories/sqlite.repository.js +++ /dev/null @@ -1,66 +0,0 @@ -const sqliteClient = require('../../../common/services/sqliteClient'); - -function addTranscript({ sessionId, speaker, text }) { - const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const transcriptId = require('crypto').randomUUID(); - const now = Math.floor(Date.now() / 1000); - const query = `INSERT INTO transcripts (id, session_id, start_at, speaker, text, created_at) VALUES (?, ?, ?, ?, ?, ?)`; - db.run(query, [transcriptId, sessionId, now, speaker, text, now], function(err) { - if (err) reject(err); - else resolve({ id: transcriptId }); - }); - }); -} - -function saveSummary({ sessionId, tldr, text, bullet_json, action_json, model = 'gpt-4.1' }) { - const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const query = ` - INSERT INTO summaries (session_id, generated_at, model, text, tldr, bullet_json, action_json, updated_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(session_id) DO UPDATE SET - generated_at=excluded.generated_at, - model=excluded.model, - text=excluded.text, - tldr=excluded.tldr, - bullet_json=excluded.bullet_json, - action_json=excluded.action_json, - updated_at=excluded.updated_at - `; - db.run(query, [sessionId, now, model, text, tldr, bullet_json, action_json, now], function(err) { - if (err) reject(err); - else resolve({ changes: this.changes }); - }); - }); -} - -function getAllTranscriptsBySessionId(sessionId) { - const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = "SELECT * FROM transcripts WHERE session_id = ? ORDER BY start_at ASC"; - db.all(query, [sessionId], (err, rows) => { - if (err) reject(err); - else resolve(rows); - }); - }); -} - -function getSummaryBySessionId(sessionId) { - const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = "SELECT * FROM summaries WHERE session_id = ?"; - db.get(query, [sessionId], (err, row) => { - if (err) reject(err); - else resolve(row || null); - }); - }); -} - -module.exports = { - addTranscript, - saveSummary, - getAllTranscriptsBySessionId, - getSummaryBySessionId -}; \ No newline at end of file diff --git a/src/features/listen/stt/SttView.js b/src/features/listen/stt/SttView.js new file mode 100644 index 0000000..31e2a5a --- /dev/null +++ b/src/features/listen/stt/SttView.js @@ -0,0 +1,228 @@ +import { html, css, LitElement } from '../../../assets/lit-core-2.7.4.min.js'; + +export class SttView extends LitElement { + static styles = css` + :host { + display: block; + width: 100%; + } + + /* Inherit font styles from parent */ + + .transcription-container { + overflow-y: auto; + padding: 12px 12px 16px 12px; + display: flex; + flex-direction: column; + gap: 8px; + min-height: 150px; + max-height: 600px; + position: relative; + z-index: 1; + flex: 1; + } + + /* Visibility handled by parent component */ + + .transcription-container::-webkit-scrollbar { + width: 8px; + } + .transcription-container::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; + } + .transcription-container::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.3); + border-radius: 4px; + } + .transcription-container::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.5); + } + + .stt-message { + padding: 8px 12px; + border-radius: 12px; + max-width: 80%; + word-wrap: break-word; + word-break: break-word; + line-height: 1.5; + font-size: 13px; + margin-bottom: 4px; + box-sizing: border-box; + } + + .stt-message.them { + background: rgba(255, 255, 255, 0.1); + color: rgba(255, 255, 255, 0.9); + align-self: flex-start; + border-bottom-left-radius: 4px; + margin-right: auto; + } + + .stt-message.me { + background: rgba(0, 122, 255, 0.8); + color: white; + align-self: flex-end; + border-bottom-right-radius: 4px; + margin-left: auto; + } + + .empty-state { + display: flex; + align-items: center; + justify-content: center; + height: 100px; + color: rgba(255, 255, 255, 0.6); + font-size: 12px; + font-style: italic; + } + `; + + static properties = { + sttMessages: { type: Array }, + isVisible: { type: Boolean }, + }; + + constructor() { + super(); + this.sttMessages = []; + this.isVisible = true; + this.messageIdCounter = 0; + this._shouldScrollAfterUpdate = false; + + this.handleSttUpdate = this.handleSttUpdate.bind(this); + } + + connectedCallback() { + super.connectedCallback(); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.on('stt-update', this.handleSttUpdate); + } + } + + disconnectedCallback() { + super.disconnectedCallback(); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.removeListener('stt-update', this.handleSttUpdate); + } + } + + // Handle session reset from parent + resetTranscript() { + this.sttMessages = []; + this.requestUpdate(); + } + + handleSttUpdate(event, { speaker, text, isFinal, isPartial }) { + if (text === undefined) return; + + const container = this.shadowRoot.querySelector('.transcription-container'); + this._shouldScrollAfterUpdate = container ? container.scrollTop + container.clientHeight >= container.scrollHeight - 10 : false; + + const findLastPartialIdx = spk => { + for (let i = this.sttMessages.length - 1; i >= 0; i--) { + const m = this.sttMessages[i]; + if (m.speaker === spk && m.isPartial) return i; + } + return -1; + }; + + const newMessages = [...this.sttMessages]; + const targetIdx = findLastPartialIdx(speaker); + + if (isPartial) { + if (targetIdx !== -1) { + newMessages[targetIdx] = { + ...newMessages[targetIdx], + text, + isPartial: true, + isFinal: false, + }; + } else { + newMessages.push({ + id: this.messageIdCounter++, + speaker, + text, + isPartial: true, + isFinal: false, + }); + } + } else if (isFinal) { + if (targetIdx !== -1) { + newMessages[targetIdx] = { + ...newMessages[targetIdx], + text, + isPartial: false, + isFinal: true, + }; + } else { + newMessages.push({ + id: this.messageIdCounter++, + speaker, + text, + isPartial: false, + isFinal: true, + }); + } + } + + this.sttMessages = newMessages; + + // Notify parent component about message updates + this.dispatchEvent(new CustomEvent('stt-messages-updated', { + detail: { messages: this.sttMessages }, + bubbles: true + })); + } + + scrollToBottom() { + setTimeout(() => { + const container = this.shadowRoot.querySelector('.transcription-container'); + if (container) { + container.scrollTop = container.scrollHeight; + } + }, 0); + } + + getSpeakerClass(speaker) { + return speaker.toLowerCase() === 'me' ? 'me' : 'them'; + } + + getTranscriptText() { + return this.sttMessages.map(msg => `${msg.speaker}: ${msg.text}`).join('\n'); + } + + updated(changedProperties) { + super.updated(changedProperties); + + if (changedProperties.has('sttMessages')) { + if (this._shouldScrollAfterUpdate) { + this.scrollToBottom(); + this._shouldScrollAfterUpdate = false; + } + } + } + + render() { + if (!this.isVisible) { + return html`
`; + } + + return html` +
+ ${this.sttMessages.length === 0 + ? html`
Waiting for speech...
` + : this.sttMessages.map(msg => html` +
+ ${msg.text} +
+ `) + } +
+ `; + } +} + +customElements.define('stt-view', SttView); \ No newline at end of file diff --git a/src/features/listen/summary/SummaryView.js b/src/features/listen/summary/SummaryView.js new file mode 100644 index 0000000..15d79b9 --- /dev/null +++ b/src/features/listen/summary/SummaryView.js @@ -0,0 +1,559 @@ +import { html, css, LitElement } from '../../../assets/lit-core-2.7.4.min.js'; + +export class SummaryView extends LitElement { + static styles = css` + :host { + display: block; + width: 100%; + } + + /* Inherit font styles from parent */ + + /* highlight.js 스타일 추가 */ + .insights-container pre { + background: rgba(0, 0, 0, 0.4) !important; + border-radius: 8px !important; + padding: 12px !important; + margin: 8px 0 !important; + overflow-x: auto !important; + border: 1px solid rgba(255, 255, 255, 0.1) !important; + white-space: pre !important; + word-wrap: normal !important; + word-break: normal !important; + } + + .insights-container code { + font-family: 'Monaco', 'Menlo', 'Consolas', monospace !important; + font-size: 11px !important; + background: transparent !important; + white-space: pre !important; + word-wrap: normal !important; + word-break: normal !important; + } + + .insights-container pre code { + white-space: pre !important; + word-wrap: normal !important; + word-break: normal !important; + display: block !important; + } + + .insights-container p code { + background: rgba(255, 255, 255, 0.1) !important; + padding: 2px 4px !important; + border-radius: 3px !important; + color: #ffd700 !important; + } + + .hljs-keyword { + color: #ff79c6 !important; + } + .hljs-string { + color: #f1fa8c !important; + } + .hljs-comment { + color: #6272a4 !important; + } + .hljs-number { + color: #bd93f9 !important; + } + .hljs-function { + color: #50fa7b !important; + } + .hljs-variable { + color: #8be9fd !important; + } + .hljs-built_in { + color: #ffb86c !important; + } + .hljs-title { + color: #50fa7b !important; + } + .hljs-attr { + color: #50fa7b !important; + } + .hljs-tag { + color: #ff79c6 !important; + } + + .insights-container { + overflow-y: auto; + padding: 12px 16px 16px 16px; + position: relative; + z-index: 1; + min-height: 150px; + max-height: 600px; + flex: 1; + } + + /* Visibility handled by parent component */ + + .insights-container::-webkit-scrollbar { + width: 8px; + } + .insights-container::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; + } + .insights-container::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.3); + border-radius: 4px; + } + .insights-container::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.5); + } + + insights-title { + color: rgba(255, 255, 255, 0.8); + font-size: 15px; + font-weight: 500; + font-family: 'Helvetica Neue', sans-serif; + margin: 12px 0 8px 0; + display: block; + } + + .insights-container h4 { + color: #ffffff; + font-size: 12px; + font-weight: 600; + margin: 12px 0 8px 0; + padding: 4px 8px; + border-radius: 4px; + background: transparent; + cursor: default; + } + + .insights-container h4:hover { + background: transparent; + } + + .insights-container h4:first-child { + margin-top: 0; + } + + .outline-item { + color: #ffffff; + font-size: 11px; + line-height: 1.4; + margin: 4px 0; + padding: 6px 8px; + border-radius: 4px; + background: transparent; + transition: background-color 0.15s ease; + cursor: pointer; + word-wrap: break-word; + } + + .outline-item:hover { + background: rgba(255, 255, 255, 0.1); + } + + .request-item { + color: #ffffff; + font-size: 12px; + line-height: 1.2; + margin: 4px 0; + padding: 6px 8px; + border-radius: 4px; + background: transparent; + cursor: default; + word-wrap: break-word; + transition: background-color 0.15s ease; + } + + .request-item.clickable { + cursor: pointer; + transition: all 0.15s ease; + } + .request-item.clickable:hover { + background: rgba(255, 255, 255, 0.1); + transform: translateX(2px); + } + + /* 마크다운 렌더링된 콘텐츠 스타일 */ + .markdown-content { + color: #ffffff; + font-size: 11px; + line-height: 1.4; + margin: 4px 0; + padding: 6px 8px; + border-radius: 4px; + background: transparent; + cursor: pointer; + word-wrap: break-word; + transition: all 0.15s ease; + } + + .markdown-content:hover { + background: rgba(255, 255, 255, 0.1); + transform: translateX(2px); + } + + .markdown-content p { + margin: 4px 0; + } + + .markdown-content ul, + .markdown-content ol { + margin: 4px 0; + padding-left: 16px; + } + + .markdown-content li { + margin: 2px 0; + } + + .markdown-content a { + color: #8be9fd; + text-decoration: none; + } + + .markdown-content a:hover { + text-decoration: underline; + } + + .markdown-content strong { + font-weight: 600; + color: #f8f8f2; + } + + .markdown-content em { + font-style: italic; + color: #f1fa8c; + } + + .empty-state { + display: flex; + align-items: center; + justify-content: center; + height: 100px; + color: rgba(255, 255, 255, 0.6); + font-size: 12px; + font-style: italic; + } + `; + + static properties = { + structuredData: { type: Object }, + isVisible: { type: Boolean }, + hasCompletedRecording: { type: Boolean }, + }; + + constructor() { + super(); + this.structuredData = { + summary: [], + topic: { header: '', bullets: [] }, + actions: [], + followUps: [], + }; + this.isVisible = true; + this.hasCompletedRecording = false; + + // 마크다운 라이브러리 초기화 + this.marked = null; + this.hljs = null; + this.isLibrariesLoaded = false; + this.DOMPurify = null; + this.isDOMPurifyLoaded = false; + + this.loadLibraries(); + } + + connectedCallback() { + super.connectedCallback(); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.on('update-structured-data', (event, data) => { + this.structuredData = data; + this.requestUpdate(); + }); + } + } + + disconnectedCallback() { + super.disconnectedCallback(); + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.removeAllListeners('update-structured-data'); + } + } + + // Handle session reset from parent + resetAnalysis() { + this.structuredData = { + summary: [], + topic: { header: '', bullets: [] }, + actions: [], + followUps: [], + }; + this.requestUpdate(); + } + + async loadLibraries() { + try { + if (!window.marked) { + await this.loadScript('../../../assets/marked-4.3.0.min.js'); + } + + if (!window.hljs) { + await this.loadScript('../../../assets/highlight-11.9.0.min.js'); + } + + if (!window.DOMPurify) { + await this.loadScript('../../../assets/dompurify-3.0.7.min.js'); + } + + this.marked = window.marked; + this.hljs = window.hljs; + this.DOMPurify = window.DOMPurify; + + if (this.marked && this.hljs) { + this.marked.setOptions({ + highlight: (code, lang) => { + if (lang && this.hljs.getLanguage(lang)) { + try { + return this.hljs.highlight(code, { language: lang }).value; + } catch (err) { + console.warn('Highlight error:', err); + } + } + try { + return this.hljs.highlightAuto(code).value; + } catch (err) { + console.warn('Auto highlight error:', err); + } + return code; + }, + breaks: true, + gfm: true, + pedantic: false, + smartypants: false, + xhtml: false, + }); + + this.isLibrariesLoaded = true; + console.log('Markdown libraries loaded successfully'); + } + + if (this.DOMPurify) { + this.isDOMPurifyLoaded = true; + console.log('DOMPurify loaded successfully in SummaryView'); + } + } catch (error) { + console.error('Failed to load libraries:', error); + } + } + + loadScript(src) { + return new Promise((resolve, reject) => { + const script = document.createElement('script'); + script.src = src; + script.onload = resolve; + script.onerror = reject; + document.head.appendChild(script); + }); + } + + parseMarkdown(text) { + if (!text) return ''; + + if (!this.isLibrariesLoaded || !this.marked) { + return text; + } + + try { + return this.marked(text); + } catch (error) { + console.error('Markdown parsing error:', error); + return text; + } + } + + handleMarkdownClick(originalText) { + this.handleRequestClick(originalText); + } + + renderMarkdownContent() { + if (!this.isLibrariesLoaded || !this.marked) { + return; + } + + const markdownElements = this.shadowRoot.querySelectorAll('[data-markdown-id]'); + markdownElements.forEach(element => { + const originalText = element.getAttribute('data-original-text'); + if (originalText) { + try { + let parsedHTML = this.parseMarkdown(originalText); + + if (this.isDOMPurifyLoaded && this.DOMPurify) { + parsedHTML = this.DOMPurify.sanitize(parsedHTML); + + if (this.DOMPurify.removed && this.DOMPurify.removed.length > 0) { + console.warn('Unsafe content detected in insights, showing plain text'); + element.textContent = '⚠️ ' + originalText; + return; + } + } + + element.innerHTML = parsedHTML; + } catch (error) { + console.error('Error rendering markdown for element:', error); + element.textContent = originalText; + } + } + }); + } + + async handleRequestClick(requestText) { + console.log('🔥 Analysis request clicked:', requestText); + + if (window.require) { + const { ipcRenderer } = window.require('electron'); + + try { + const isAskViewVisible = await ipcRenderer.invoke('is-window-visible', 'ask'); + + if (!isAskViewVisible) { + await ipcRenderer.invoke('toggle-feature', 'ask'); + await new Promise(resolve => setTimeout(resolve, 100)); + } + + const result = await ipcRenderer.invoke('send-question-to-ask', requestText); + + if (result.success) { + console.log('✅ Question sent to AskView successfully'); + } else { + console.error('❌ Failed to send question to AskView:', result.error); + } + } catch (error) { + console.error('❌ Error in handleRequestClick:', error); + } + } + } + + getSummaryText() { + const data = this.structuredData || { summary: [], topic: { header: '', bullets: [] }, actions: [] }; + let sections = []; + + if (data.summary && data.summary.length > 0) { + sections.push(`Current Summary:\n${data.summary.map(s => `• ${s}`).join('\n')}`); + } + + if (data.topic && data.topic.header && data.topic.bullets.length > 0) { + sections.push(`\n${data.topic.header}:\n${data.topic.bullets.map(b => `• ${b}`).join('\n')}`); + } + + if (data.actions && data.actions.length > 0) { + sections.push(`\nActions:\n${data.actions.map(a => `▸ ${a}`).join('\n')}`); + } + + if (data.followUps && data.followUps.length > 0) { + sections.push(`\nFollow-Ups:\n${data.followUps.map(f => `▸ ${f}`).join('\n')}`); + } + + return sections.join('\n\n').trim(); + } + + updated(changedProperties) { + super.updated(changedProperties); + this.renderMarkdownContent(); + } + + render() { + if (!this.isVisible) { + return html`
`; + } + + const data = this.structuredData || { + summary: [], + topic: { header: '', bullets: [] }, + actions: [], + }; + + const hasAnyContent = data.summary.length > 0 || data.topic.bullets.length > 0 || data.actions.length > 0; + + return html` +
+ ${!hasAnyContent + ? html`
No insights yet...
` + : html` + Current Summary + ${data.summary.length > 0 + ? data.summary + .slice(0, 5) + .map( + (bullet, index) => html` +
this.handleMarkdownClick(bullet)} + > + ${bullet} +
+ ` + ) + : html`
No content yet...
`} + ${data.topic.header + ? html` + ${data.topic.header} + ${data.topic.bullets + .slice(0, 3) + .map( + (bullet, index) => html` +
this.handleMarkdownClick(bullet)} + > + ${bullet} +
+ ` + )} + ` + : ''} + ${data.actions.length > 0 + ? html` + Actions + ${data.actions + .slice(0, 5) + .map( + (action, index) => html` +
this.handleMarkdownClick(action)} + > + ${action} +
+ ` + )} + ` + : ''} + ${this.hasCompletedRecording && data.followUps && data.followUps.length > 0 + ? html` + Follow-Ups + ${data.followUps.map( + (followUp, index) => html` +
this.handleMarkdownClick(followUp)} + > + ${followUp} +
+ ` + )} + ` + : ''} + `} +
+ `; + } +} + +customElements.define('summary-view', SummaryView); \ No newline at end of file From a6ee8c405831f4eabe600decf2b6d476688c3dc4 Mon Sep 17 00:00:00 2001 From: samtiz Date: Mon, 7 Jul 2025 07:50:28 +0900 Subject: [PATCH 07/52] LLM/STT refactor --- src/common/ai/factory.js | 67 ++++ src/common/ai/providers/gemini.js | 310 ++++++++++++++ src/common/ai/providers/openai.js | 255 ++++++++++++ src/common/services/aiProviderService.js | 377 ------------------ src/common/services/googleGeminiClient.js | 171 -------- src/common/services/openAiClient.js | 177 -------- src/features/ask/askService.js | 181 +-------- src/features/listen/renderer/renderer.js | 1 - src/features/listen/stt/sttService.js | 28 +- src/features/listen/summary/summaryService.js | 17 +- 10 files changed, 662 insertions(+), 922 deletions(-) create mode 100644 src/common/ai/factory.js create mode 100644 src/common/ai/providers/gemini.js create mode 100644 src/common/ai/providers/openai.js delete mode 100644 src/common/services/aiProviderService.js delete mode 100644 src/common/services/googleGeminiClient.js delete mode 100644 src/common/services/openAiClient.js diff --git a/src/common/ai/factory.js b/src/common/ai/factory.js new file mode 100644 index 0000000..05a6780 --- /dev/null +++ b/src/common/ai/factory.js @@ -0,0 +1,67 @@ +const providers = { + openai: require('./providers/openai'), + gemini: require('./providers/gemini'), + // 추가 provider는 여기에 등록 +}; + +/** + * Creates an STT session based on provider + * @param {string} provider - Provider name ('openai', 'gemini', etc.) + * @param {object} opts - Configuration options (apiKey, language, callbacks, etc.) + * @returns {Promise} STT session object with sendRealtimeInput and close methods + */ +function createSTT(provider, opts) { + if (!providers[provider]?.createSTT) { + throw new Error(`STT not supported for provider: ${provider}`); + } + return providers[provider].createSTT(opts); +} + +/** + * Creates an LLM instance based on provider + * @param {string} provider - Provider name ('openai', 'gemini', etc.) + * @param {object} opts - Configuration options (apiKey, model, temperature, etc.) + * @returns {object} LLM instance with generateContent method + */ +function createLLM(provider, opts) { + if (!providers[provider]?.createLLM) { + throw new Error(`LLM not supported for provider: ${provider}`); + } + return providers[provider].createLLM(opts); +} + +/** + * Creates a streaming LLM instance based on provider + * @param {string} provider - Provider name ('openai', 'gemini', etc.) + * @param {object} opts - Configuration options (apiKey, model, temperature, etc.) + * @returns {object} Streaming LLM instance + */ +function createStreamingLLM(provider, opts) { + if (!providers[provider]?.createStreamingLLM) { + throw new Error(`Streaming LLM not supported for provider: ${provider}`); + } + return providers[provider].createStreamingLLM(opts); +} + +/** + * Gets list of available providers + * @returns {object} Object with stt and llm arrays + */ +function getAvailableProviders() { + const sttProviders = []; + const llmProviders = []; + + for (const [name, provider] of Object.entries(providers)) { + if (provider.createSTT) sttProviders.push(name); + if (provider.createLLM) llmProviders.push(name); + } + + return { stt: sttProviders, llm: llmProviders }; +} + +module.exports = { + createSTT, + createLLM, + createStreamingLLM, + getAvailableProviders +}; \ No newline at end of file diff --git a/src/common/ai/providers/gemini.js b/src/common/ai/providers/gemini.js new file mode 100644 index 0000000..a2284a1 --- /dev/null +++ b/src/common/ai/providers/gemini.js @@ -0,0 +1,310 @@ +const { GoogleGenerativeAI } = require('@google/generative-ai'); +const { GoogleGenAI } = require('@google/genai'); + +/** + * Creates a Gemini STT session + * @param {object} opts - Configuration options + * @param {string} opts.apiKey - Gemini API key + * @param {string} [opts.language='en-US'] - Language code + * @param {object} [opts.callbacks] - Event callbacks + * @returns {Promise} STT session + */ +async function createSTT({ apiKey, language = 'en-US', callbacks = {}, ...config }) { + const liveClient = new GoogleGenAI({ vertexai: false, apiKey }); + + // Language code BCP-47 conversion + const lang = language.includes('-') ? language : `${language}-US`; + + const session = await liveClient.live.connect({ + model: 'gemini-live-2.5-flash-preview', + callbacks, + config: { + inputAudioTranscription: {}, + speechConfig: { languageCode: lang }, + }, + }); + + return { + sendRealtimeInput: async payload => session.sendRealtimeInput(payload), + close: async () => session.close(), + }; +} + +/** + * Creates a Gemini LLM instance + * @param {object} opts - Configuration options + * @param {string} opts.apiKey - Gemini API key + * @param {string} [opts.model='gemini-2.5-flash'] - Model name + * @param {number} [opts.temperature=0.7] - Temperature + * @param {number} [opts.maxTokens=8192] - Max tokens + * @returns {object} LLM instance + */ +function createLLM({ apiKey, model = 'gemini-2.5-flash', temperature = 0.7, maxTokens = 8192, ...config }) { + const client = new GoogleGenerativeAI(apiKey); + + return { + generateContent: async (parts) => { + const geminiModel = client.getGenerativeModel({ model: model }); + + let systemPrompt = ''; + let userContent = []; + + for (const part of parts) { + if (typeof part === 'string') { + if (systemPrompt === '' && part.includes('You are')) { + systemPrompt = part; + } else { + userContent.push(part); + } + } else if (part.inlineData) { + // Convert base64 image data to Gemini format + userContent.push({ + inlineData: { + mimeType: part.inlineData.mimeType, + data: part.inlineData.data + } + }); + } + } + + // Prepare content array + const content = []; + + // Add system instruction if present + if (systemPrompt) { + // For Gemini, we'll prepend system prompt to user content + content.push(systemPrompt + '\n\n' + userContent[0]); + content.push(...userContent.slice(1)); + } else { + content.push(...userContent); + } + + try { + const result = await geminiModel.generateContent(content); + const response = await result.response; + + return { + response: { + text: () => response.text() + } + }; + } catch (error) { + console.error('Gemini API error:', error); + throw error; + } + }, + + // For compatibility with chat-style interfaces + chat: async (messages) => { + // Extract system instruction if present + let systemInstruction = ''; + const history = []; + let lastMessage; + + messages.forEach((msg, index) => { + if (msg.role === 'system') { + systemInstruction = msg.content; + return; + } + + // Gemini's history format + const role = msg.role === 'user' ? 'user' : 'model'; + + if (index === messages.length - 1) { + lastMessage = msg; + } else { + history.push({ role, parts: [{ text: msg.content }] }); + } + }); + + const geminiModel = client.getGenerativeModel({ + model: model, + systemInstruction: systemInstruction + }); + + const chat = geminiModel.startChat({ + history: history, + generationConfig: { + temperature: temperature, + maxOutputTokens: maxTokens, + } + }); + + // Get the last user message content + let content = lastMessage.content; + + // Handle multimodal content for the last message + if (Array.isArray(content)) { + const geminiContent = []; + for (const part of content) { + if (typeof part === 'string') { + geminiContent.push(part); + } else if (part.type === 'text') { + geminiContent.push(part.text); + } else if (part.type === 'image_url' && part.image_url) { + // Convert base64 image to Gemini format + const base64Data = part.image_url.url.split(',')[1]; + geminiContent.push({ + inlineData: { + mimeType: 'image/png', + data: base64Data + } + }); + } + } + content = geminiContent; + } + + const result = await chat.sendMessage(content); + const response = await result.response; + return { + content: response.text(), + raw: result + }; + } + }; +} + +/** + * Creates a Gemini streaming LLM instance + * @param {object} opts - Configuration options + * @param {string} opts.apiKey - Gemini API key + * @param {string} [opts.model='gemini-2.5-flash'] - Model name + * @param {number} [opts.temperature=0.7] - Temperature + * @param {number} [opts.maxTokens=8192] - Max tokens + * @returns {object} Streaming LLM instance + */ +function createStreamingLLM({ apiKey, model = 'gemini-2.5-flash', temperature = 0.7, maxTokens = 8192, ...config }) { + const client = new GoogleGenerativeAI(apiKey); + + return { + streamChat: async (messages) => { + console.log('[Gemini Provider] Starting streaming request'); + + // Extract system instruction if present + let systemInstruction = ''; + const nonSystemMessages = []; + + for (const msg of messages) { + if (msg.role === 'system') { + systemInstruction = msg.content; + } else { + nonSystemMessages.push(msg); + } + } + + const geminiModel = client.getGenerativeModel({ + model: model, + systemInstruction: systemInstruction || undefined + }); + + const chat = geminiModel.startChat({ + history: [], + generationConfig: { + temperature, + maxOutputTokens: maxTokens || 8192, + } + }); + + // Create a ReadableStream to handle Gemini's streaming + const stream = new ReadableStream({ + async start(controller) { + try { + console.log('[Gemini Provider] Processing messages:', nonSystemMessages.length, 'messages (excluding system)'); + + // Get the last user message + const lastMessage = nonSystemMessages[nonSystemMessages.length - 1]; + let lastUserMessage = lastMessage.content; + + // Handle case where content might be an array (multimodal) + if (Array.isArray(lastUserMessage)) { + // Extract text content from array + const textParts = lastUserMessage.filter(part => + typeof part === 'string' || (part && part.type === 'text') + ); + lastUserMessage = textParts.map(part => + typeof part === 'string' ? part : part.text + ).join(' '); + } + + console.log('[Gemini Provider] Sending message to Gemini:', + typeof lastUserMessage === 'string' ? lastUserMessage.substring(0, 100) + '...' : 'multimodal content'); + + // Prepare the message content for Gemini + let geminiContent = []; + + // Handle multimodal content properly + if (Array.isArray(lastMessage.content)) { + for (const part of lastMessage.content) { + if (typeof part === 'string') { + geminiContent.push(part); + } else if (part.type === 'text') { + geminiContent.push(part.text); + } else if (part.type === 'image_url' && part.image_url) { + // Convert base64 image to Gemini format + const base64Data = part.image_url.url.split(',')[1]; + geminiContent.push({ + inlineData: { + mimeType: 'image/png', + data: base64Data + } + }); + } + } + } else { + geminiContent = [lastUserMessage]; + } + + console.log('[Gemini Provider] Prepared Gemini content:', + geminiContent.length, 'parts'); + + // Stream the response + let chunkCount = 0; + let totalContent = ''; + + for await (const chunk of chat.sendMessageStream(geminiContent)) { + chunkCount++; + const chunkText = chunk.text() || ''; + totalContent += chunkText; + + // Format as SSE data + const data = JSON.stringify({ + choices: [{ + delta: { + content: chunkText + } + }] + }); + controller.enqueue(new TextEncoder().encode(`data: ${data}\n\n`)); + } + + console.log(`[Gemini Provider] Streamed ${chunkCount} chunks, total length: ${totalContent.length} chars`); + + // Send the final done message + controller.enqueue(new TextEncoder().encode('data: [DONE]\n\n')); + controller.close(); + console.log('[Gemini Provider] Streaming completed successfully'); + } catch (error) { + console.error('[Gemini Provider] Streaming error:', error); + controller.error(error); + } + } + }); + + // Create a Response object with the stream + return new Response(stream, { + headers: { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + 'Connection': 'keep-alive' + } + }); + } + }; +} + +module.exports = { + createSTT, + createLLM, + createStreamingLLM +}; \ No newline at end of file diff --git a/src/common/ai/providers/openai.js b/src/common/ai/providers/openai.js new file mode 100644 index 0000000..a27c547 --- /dev/null +++ b/src/common/ai/providers/openai.js @@ -0,0 +1,255 @@ +const OpenAI = require('openai'); +const WebSocket = require('ws'); + +/** + * Creates an OpenAI STT session + * @param {object} opts - Configuration options + * @param {string} opts.apiKey - OpenAI API key + * @param {string} [opts.language='en'] - Language code + * @param {object} [opts.callbacks] - Event callbacks + * @param {boolean} [opts.usePortkey=false] - Whether to use Portkey + * @param {string} [opts.portkeyVirtualKey] - Portkey virtual key + * @returns {Promise} STT session + */ +async function createSTT({ apiKey, language = 'en', callbacks = {}, usePortkey = false, portkeyVirtualKey, ...config }) { + const keyType = usePortkey ? 'vKey' : 'apiKey'; + const key = usePortkey ? (portkeyVirtualKey || apiKey) : apiKey; + + const wsUrl = keyType === 'apiKey' + ? 'wss://api.openai.com/v1/realtime?intent=transcription' + : 'wss://api.portkey.ai/v1/realtime?intent=transcription'; + + const headers = keyType === 'apiKey' + ? { + 'Authorization': `Bearer ${key}`, + 'OpenAI-Beta': 'realtime=v1', + } + : { + 'x-portkey-api-key': 'gRv2UGRMq6GGLJ8aVEB4e7adIewu', + 'x-portkey-virtual-key': key, + 'OpenAI-Beta': 'realtime=v1', + }; + + const ws = new WebSocket(wsUrl, { headers }); + + return new Promise((resolve, reject) => { + ws.onopen = () => { + console.log("WebSocket session opened."); + + const sessionConfig = { + type: 'transcription_session.update', + session: { + input_audio_format: 'pcm16', + input_audio_transcription: { + model: 'gpt-4o-mini-transcribe', + prompt: config.prompt || '', + language: language || 'en' + }, + turn_detection: { + type: 'server_vad', + threshold: 0.5, + prefix_padding_ms: 50, + silence_duration_ms: 25, + }, + input_audio_noise_reduction: { + type: 'near_field' + } + } + }; + + ws.send(JSON.stringify(sessionConfig)); + + resolve({ + sendRealtimeInput: (audioData) => { + if (ws.readyState === WebSocket.OPEN) { + const message = { + type: 'input_audio_buffer.append', + audio: audioData + }; + ws.send(JSON.stringify(message)); + } + }, + close: () => { + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ type: 'session.close' })); + ws.close(1000, 'Client initiated close.'); + } + } + }); + }; + + ws.onmessage = (event) => { + const message = JSON.parse(event.data); + if (callbacks && callbacks.onmessage) { + callbacks.onmessage(message); + } + }; + + ws.onerror = (error) => { + console.error('WebSocket error:', error.message); + if (callbacks && callbacks.onerror) { + callbacks.onerror(error); + } + reject(error); + }; + + ws.onclose = (event) => { + console.log(`WebSocket closed: ${event.code} ${event.reason}`); + if (callbacks && callbacks.onclose) { + callbacks.onclose(event); + } + }; + }); +} + +/** + * Creates an OpenAI LLM instance + * @param {object} opts - Configuration options + * @param {string} opts.apiKey - OpenAI API key + * @param {string} [opts.model='gpt-4.1'] - Model name + * @param {number} [opts.temperature=0.7] - Temperature + * @param {number} [opts.maxTokens=2048] - Max tokens + * @param {boolean} [opts.usePortkey=false] - Whether to use Portkey + * @param {string} [opts.portkeyVirtualKey] - Portkey virtual key + * @returns {object} LLM instance + */ +function createLLM({ apiKey, model = 'gpt-4.1', temperature = 0.7, maxTokens = 2048, usePortkey = false, portkeyVirtualKey, ...config }) { + const client = new OpenAI({ apiKey }); + + const callApi = async (messages) => { + if (!usePortkey) { + const response = await client.chat.completions.create({ + model: model, + messages: messages, + temperature: temperature, + max_tokens: maxTokens + }); + return { + content: response.choices[0].message.content.trim(), + raw: response + }; + } else { + const fetchUrl = 'https://api.portkey.ai/v1/chat/completions'; + const response = await fetch(fetchUrl, { + method: 'POST', + headers: { + 'x-portkey-api-key': 'gRv2UGRMq6GGLJ8aVEB4e7adIewu', + 'x-portkey-virtual-key': portkeyVirtualKey || apiKey, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + model: model, + messages, + temperature, + max_tokens: maxTokens, + }), + }); + + if (!response.ok) { + throw new Error(`Portkey API error: ${response.status} ${response.statusText}`); + } + + const result = await response.json(); + return { + content: result.choices[0].message.content.trim(), + raw: result + }; + } + }; + + return { + generateContent: async (parts) => { + const messages = []; + let systemPrompt = ''; + let userContent = []; + + for (const part of parts) { + if (typeof part === 'string') { + if (systemPrompt === '' && part.includes('You are')) { + systemPrompt = part; + } else { + userContent.push({ type: 'text', text: part }); + } + } else if (part.inlineData) { + userContent.push({ + type: 'image_url', + image_url: { url: `data:${part.inlineData.mimeType};base64,${part.inlineData.data}` } + }); + } + } + + if (systemPrompt) messages.push({ role: 'system', content: systemPrompt }); + if (userContent.length > 0) messages.push({ role: 'user', content: userContent }); + + const result = await callApi(messages); + + return { + response: { + text: () => result.content + }, + raw: result.raw + }; + }, + + // For compatibility with chat-style interfaces + chat: async (messages) => { + return await callApi(messages); + } + }; +} + +/** + * Creates an OpenAI streaming LLM instance + * @param {object} opts - Configuration options + * @param {string} opts.apiKey - OpenAI API key + * @param {string} [opts.model='gpt-4.1'] - Model name + * @param {number} [opts.temperature=0.7] - Temperature + * @param {number} [opts.maxTokens=2048] - Max tokens + * @param {boolean} [opts.usePortkey=false] - Whether to use Portkey + * @param {string} [opts.portkeyVirtualKey] - Portkey virtual key + * @returns {object} Streaming LLM instance + */ +function createStreamingLLM({ apiKey, model = 'gpt-4.1', temperature = 0.7, maxTokens = 2048, usePortkey = false, portkeyVirtualKey, ...config }) { + return { + streamChat: async (messages) => { + const fetchUrl = usePortkey + ? 'https://api.portkey.ai/v1/chat/completions' + : 'https://api.openai.com/v1/chat/completions'; + + const headers = usePortkey + ? { + 'x-portkey-api-key': 'gRv2UGRMq6GGLJ8aVEB4e7adIewu', + 'x-portkey-virtual-key': portkeyVirtualKey || apiKey, + 'Content-Type': 'application/json', + } + : { + Authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json', + }; + + const response = await fetch(fetchUrl, { + method: 'POST', + headers, + body: JSON.stringify({ + model: model, + messages, + temperature, + max_tokens: maxTokens, + stream: true, + }), + }); + + if (!response.ok) { + throw new Error(`OpenAI API error: ${response.status} ${response.statusText}`); + } + + return response; + } + }; +} + +module.exports = { + createSTT, + createLLM, + createStreamingLLM +}; \ No newline at end of file diff --git a/src/common/services/aiProviderService.js b/src/common/services/aiProviderService.js deleted file mode 100644 index fe24e47..0000000 --- a/src/common/services/aiProviderService.js +++ /dev/null @@ -1,377 +0,0 @@ -const { createOpenAiGenerativeClient, getOpenAiGenerativeModel } = require('./openAiClient.js'); -const { createGeminiClient, getGeminiGenerativeModel, createGeminiChat } = require('./googleGeminiClient.js'); - -/** - * Creates an AI client based on the provider - * @param {string} apiKey - The API key - * @param {string} provider - The provider ('openai' or 'gemini') - * @returns {object} The AI client - */ -function createAIClient(apiKey, provider = 'openai') { - switch (provider) { - case 'openai': - return createOpenAiGenerativeClient(apiKey); - case 'gemini': - return createGeminiClient(apiKey); - default: - throw new Error(`Unsupported AI provider: ${provider}`); - } -} - -/** - * Gets a generative model based on the provider - * @param {object} client - The AI client - * @param {string} provider - The provider ('openai' or 'gemini') - * @param {string} model - The model name (optional) - * @returns {object} The model object - */ -function getGenerativeModel(client, provider = 'openai', model) { - switch (provider) { - case 'openai': - return getOpenAiGenerativeModel(client, model || 'gpt-4.1'); - case 'gemini': - return getGeminiGenerativeModel(client, model || 'gemini-2.5-flash'); - default: - throw new Error(`Unsupported AI provider: ${provider}`); - } -} - -/** - * Makes a chat completion request based on the provider - * @param {object} params - Request parameters - * @returns {Promise} The completion response - */ -async function makeChatCompletion({ apiKey, provider = 'openai', messages, temperature = 0.7, maxTokens = 1024, model, stream = false }) { - if (provider === 'openai') { - const fetchUrl = 'https://api.openai.com/v1/chat/completions'; - const response = await fetch(fetchUrl, { - method: 'POST', - headers: { - Authorization: `Bearer ${apiKey}`, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - model: model || 'gpt-4.1', - messages, - temperature, - max_tokens: maxTokens, - stream, - }), - }); - - if (!response.ok) { - throw new Error(`OpenAI API error: ${response.status} ${response.statusText}`); - } - - if (stream) { - return response; - } - - const result = await response.json(); - return { - content: result.choices[0].message.content.trim(), - raw: result - }; - } else if (provider === 'gemini') { - const client = createGeminiClient(apiKey); - const genModel = getGeminiGenerativeModel(client, model || 'gemini-2.5-flash'); - - // Convert OpenAI format messages to Gemini format - const parts = []; - for (const message of messages) { - if (message.role === 'system') { - parts.push(message.content); - } else if (message.role === 'user') { - if (typeof message.content === 'string') { - parts.push(message.content); - } else if (Array.isArray(message.content)) { - // Handle multimodal content - for (const part of message.content) { - if (part.type === 'text') { - parts.push(part.text); - } else if (part.type === 'image_url' && part.image_url?.url) { - // Extract base64 data from data URL - const base64Match = part.image_url.url.match(/^data:(.+);base64,(.+)$/); - if (base64Match) { - parts.push({ - inlineData: { - mimeType: base64Match[1], - data: base64Match[2] - } - }); - } - } - } - } - } - } - - const result = await genModel.generateContent(parts); - return { - content: result.response.text(), - raw: result - }; - } else { - throw new Error(`Unsupported AI provider: ${provider}`); - } -} - -/** - * Makes a chat completion request with Portkey support - * @param {object} params - Request parameters including Portkey options - * @returns {Promise} The completion response - */ -async function makeChatCompletionWithPortkey({ - apiKey, - provider = 'openai', - messages, - temperature = 0.7, - maxTokens = 1024, - model, - usePortkey = false, - portkeyVirtualKey = null -}) { - if (!usePortkey) { - return makeChatCompletion({ apiKey, provider, messages, temperature, maxTokens, model }); - } - - // Portkey is only supported for OpenAI currently - if (provider !== 'openai') { - console.warn('Portkey is only supported for OpenAI provider, falling back to direct API'); - return makeChatCompletion({ apiKey, provider, messages, temperature, maxTokens, model }); - } - - const fetchUrl = 'https://api.portkey.ai/v1/chat/completions'; - const response = await fetch(fetchUrl, { - method: 'POST', - headers: { - 'x-portkey-api-key': 'gRv2UGRMq6GGLJ8aVEB4e7adIewu', - 'x-portkey-virtual-key': portkeyVirtualKey || apiKey, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - model: model || 'gpt-4.1', - messages, - temperature, - max_tokens: maxTokens, - }), - }); - - if (!response.ok) { - throw new Error(`Portkey API error: ${response.status} ${response.statusText}`); - } - - const result = await response.json(); - return { - content: result.choices[0].message.content.trim(), - raw: result - }; -} - -/** - * Makes a streaming chat completion request - * @param {object} params - Request parameters - * @returns {Promise} The streaming response - */ -async function makeStreamingChatCompletion({ apiKey, provider = 'openai', messages, temperature = 0.7, maxTokens = 1024, model }) { - if (provider === 'openai') { - const fetchUrl = 'https://api.openai.com/v1/chat/completions'; - const response = await fetch(fetchUrl, { - method: 'POST', - headers: { - Authorization: `Bearer ${apiKey}`, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - model: model || 'gpt-4.1', - messages, - temperature, - max_tokens: maxTokens, - stream: true, - }), - }); - - if (!response.ok) { - throw new Error(`OpenAI API error: ${response.status} ${response.statusText}`); - } - - return response; - } else if (provider === 'gemini') { - console.log('[AIProviderService] Starting Gemini streaming request'); - // Gemini streaming requires a different approach - // We'll create a ReadableStream that mimics OpenAI's SSE format - const geminiClient = createGeminiClient(apiKey); - - // Extract system instruction if present - let systemInstruction = ''; - const nonSystemMessages = []; - - for (const msg of messages) { - if (msg.role === 'system') { - systemInstruction = msg.content; - } else { - nonSystemMessages.push(msg); - } - } - - const chat = createGeminiChat(geminiClient, model || 'gemini-2.0-flash-exp', { - temperature, - maxOutputTokens: maxTokens || 8192, - systemInstruction: systemInstruction || undefined - }); - - // Create a ReadableStream to handle Gemini's streaming - const stream = new ReadableStream({ - async start(controller) { - try { - console.log('[AIProviderService] Processing messages for Gemini:', nonSystemMessages.length, 'messages (excluding system)'); - - // Get the last user message - const lastMessage = nonSystemMessages[nonSystemMessages.length - 1]; - let lastUserMessage = lastMessage.content; - - // Handle case where content might be an array (multimodal) - if (Array.isArray(lastUserMessage)) { - // Extract text content from array - const textParts = lastUserMessage.filter(part => - typeof part === 'string' || (part && part.type === 'text') - ); - lastUserMessage = textParts.map(part => - typeof part === 'string' ? part : part.text - ).join(' '); - } - - console.log('[AIProviderService] Sending message to Gemini:', - typeof lastUserMessage === 'string' ? lastUserMessage.substring(0, 100) + '...' : 'multimodal content'); - - // Prepare the message content for Gemini - let geminiContent = []; - - // Handle multimodal content properly - if (Array.isArray(lastMessage.content)) { - for (const part of lastMessage.content) { - if (typeof part === 'string') { - geminiContent.push(part); - } else if (part.type === 'text') { - geminiContent.push(part.text); - } else if (part.type === 'image_url' && part.image_url) { - // Convert base64 image to Gemini format - const base64Data = part.image_url.url.split(',')[1]; - geminiContent.push({ - inlineData: { - mimeType: 'image/png', - data: base64Data - } - }); - } - } - } else { - geminiContent = [lastUserMessage]; - } - - console.log('[AIProviderService] Prepared Gemini content:', - geminiContent.length, 'parts'); - - // Stream the response - let chunkCount = 0; - let totalContent = ''; - - for await (const chunk of chat.sendMessageStream(geminiContent)) { - chunkCount++; - const chunkText = chunk.text || ''; - totalContent += chunkText; - - // Format as SSE data - const data = JSON.stringify({ - choices: [{ - delta: { - content: chunkText - } - }] - }); - controller.enqueue(new TextEncoder().encode(`data: ${data}\n\n`)); - } - - console.log(`[AIProviderService] Streamed ${chunkCount} chunks, total length: ${totalContent.length} chars`); - - // Send the final done message - controller.enqueue(new TextEncoder().encode('data: [DONE]\n\n')); - controller.close(); - console.log('[AIProviderService] Gemini streaming completed successfully'); - } catch (error) { - console.error('[AIProviderService] Gemini streaming error:', error); - controller.error(error); - } - } - }); - - // Create a Response object with the stream - return new Response(stream, { - headers: { - 'Content-Type': 'text/event-stream', - 'Cache-Control': 'no-cache', - 'Connection': 'keep-alive' - } - }); - } else { - throw new Error(`Unsupported AI provider: ${provider}`); - } -} - -/** - * Makes a streaming chat completion request with Portkey support - * @param {object} params - Request parameters - * @returns {Promise} The streaming response - */ -async function makeStreamingChatCompletionWithPortkey({ - apiKey, - provider = 'openai', - messages, - temperature = 0.7, - maxTokens = 1024, - model, - usePortkey = false, - portkeyVirtualKey = null -}) { - if (!usePortkey) { - return makeStreamingChatCompletion({ apiKey, provider, messages, temperature, maxTokens, model }); - } - - // Portkey is only supported for OpenAI currently - if (provider !== 'openai') { - console.warn('Portkey is only supported for OpenAI provider, falling back to direct API'); - return makeStreamingChatCompletion({ apiKey, provider, messages, temperature, maxTokens, model }); - } - - const fetchUrl = 'https://api.portkey.ai/v1/chat/completions'; - const response = await fetch(fetchUrl, { - method: 'POST', - headers: { - 'x-portkey-api-key': 'gRv2UGRMq6GGLJ8aVEB4e7adIewu', - 'x-portkey-virtual-key': portkeyVirtualKey || apiKey, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - model: model || 'gpt-4.1', - messages, - temperature, - max_tokens: maxTokens, - stream: true, - }), - }); - - if (!response.ok) { - throw new Error(`Portkey API error: ${response.status} ${response.statusText}`); - } - - return response; -} - -module.exports = { - createAIClient, - getGenerativeModel, - makeChatCompletion, - makeChatCompletionWithPortkey, - makeStreamingChatCompletion, - makeStreamingChatCompletionWithPortkey -}; \ No newline at end of file diff --git a/src/common/services/googleGeminiClient.js b/src/common/services/googleGeminiClient.js deleted file mode 100644 index 877c82e..0000000 --- a/src/common/services/googleGeminiClient.js +++ /dev/null @@ -1,171 +0,0 @@ -const { GoogleGenerativeAI } = require('@google/generative-ai'); -const { GoogleGenAI } = require('@google/genai'); - -/** - * Creates and returns a Google Gemini client instance for generative AI. - * @param {string} apiKey - The API key for authentication. - * @returns {GoogleGenerativeAI} The initialized Gemini client. - */ -function createGeminiClient(apiKey) { - return new GoogleGenerativeAI(apiKey); -} - -/** - * Gets a Gemini model for text/image generation. - * @param {GoogleGenerativeAI} client - The Gemini client instance. - * @param {string} [model='gemini-2.5-flash'] - The name for the text/vision model. - * @returns {object} Model object with generateContent method - */ -function getGeminiGenerativeModel(client, model = 'gemini-2.5-flash') { - const genAI = client; - const geminiModel = genAI.getGenerativeModel({ model: model }); - - return { - generateContent: async (parts) => { - let systemPrompt = ''; - let userContent = []; - - for (const part of parts) { - if (typeof part === 'string') { - if (systemPrompt === '' && part.includes('You are')) { - systemPrompt = part; - } else { - userContent.push(part); - } - } else if (part.inlineData) { - // Convert base64 image data to Gemini format - userContent.push({ - inlineData: { - mimeType: part.inlineData.mimeType, - data: part.inlineData.data - } - }); - } - } - - // Prepare content array - const content = []; - - // Add system instruction if present - if (systemPrompt) { - // For Gemini, we'll prepend system prompt to user content - content.push(systemPrompt + '\n\n' + userContent[0]); - content.push(...userContent.slice(1)); - } else { - content.push(...userContent); - } - - try { - const result = await geminiModel.generateContent(content); - const response = await result.response; - - return { - response: { - text: () => response.text() - } - }; - } catch (error) { - console.error('Gemini API error:', error); - throw error; - } - } - }; -} - -/** - * Creates a Gemini chat session for multi-turn conversations. - * @param {GoogleGenerativeAI} client - The Gemini client instance. - * @param {string} [model='gemini-2.5-flash'] - The model to use. - * @param {object} [config={}] - Configuration options. - * @returns {object} Chat session object - */ -function createGeminiChat(client, model = 'gemini-2.5-flash', config = {}) { - const genAI = client; - const geminiModel = genAI.getGenerativeModel({ - model: model, - systemInstruction: config.systemInstruction - }); - - const chat = geminiModel.startChat({ - history: config.history || [], - generationConfig: { - temperature: config.temperature || 0.7, - maxOutputTokens: config.maxOutputTokens || 8192, - } - }); - - return { - sendMessage: async (message) => { - const result = await chat.sendMessage(message); - const response = await result.response; - return { - text: response.text() - }; - }, - sendMessageStream: async function* (message) { - const result = await chat.sendMessageStream(message); - for await (const chunk of result.stream) { - yield { - text: chunk.text() - }; - } - }, - getHistory: () => chat.getHistory() - }; -} - -// async function connectToGeminiSession(apiKey, { language = 'en-US', callbacks = {} } = {}) { -// const liveClient = new GoogleGenAI({ -// vertexai: false, // Vertex AI 사용 안함 -// apiKey, -// }); - -// // 라이브 STT 세션 열기 -// const session = await liveClient.live.connect({ -// model: 'gemini-live-2.5-flash-preview', -// callbacks, -// config: { -// inputAudioTranscription: {}, // 실시간 STT 필수 -// speechConfig: { languageCode: language }, -// }, -// }); - -// return { -// sendRealtimeInput: async data => session.send({ -// audio: { data, mimeType: 'audio/pcm;rate=24000' } -// }), -// close: async () => session.close(), -// }; -// } - -async function connectToGeminiSession(apiKey, { language = 'en-US', callbacks = {} } = {}) { - // ① 옛날 스타일 helper 재사용 - const liveClient = new GoogleGenAI({ vertexai: false, apiKey }); - - // ② 언어 코드 강제 BCP-47 변환 - const lang = language.includes('-') ? language : `${language}-US`; - - const session = await liveClient.live.connect({ - model: 'gemini-live-2.5-flash-preview', - callbacks, - config: { - inputAudioTranscription: {}, - speechConfig: { languageCode: lang }, - }, - }); - - // ③ SDK 0.5+ : sendRealtimeInput 가 정식 이름 - return { - sendRealtimeInput: async payload => session.sendRealtimeInput(payload), - close: async () => session.close(), - }; - } - - - -module.exports = { - createGeminiClient, - getGeminiGenerativeModel, - createGeminiChat, - connectToGeminiSession, -}; \ No newline at end of file diff --git a/src/common/services/openAiClient.js b/src/common/services/openAiClient.js deleted file mode 100644 index 56a9141..0000000 --- a/src/common/services/openAiClient.js +++ /dev/null @@ -1,177 +0,0 @@ -const OpenAI = require('openai'); -const WebSocket = require('ws'); - -/** - * Creates and returns an OpenAI client instance for STT (Speech-to-Text). - * @param {string} apiKey - The API key for authentication. - * @returns {OpenAI} The initialized OpenAI client. - */ -function createOpenAiClient(apiKey) { - return new OpenAI({ - apiKey: apiKey, - }); -} - -/** - * Creates and returns an OpenAI client instance for text/image generation. - * @param {string} apiKey - The API key for authentication. - * @returns {OpenAI} The initialized OpenAI client. - */ -function createOpenAiGenerativeClient(apiKey) { - return new OpenAI({ - apiKey: apiKey, - }); -} - -/** - * Connects to an OpenAI Realtime WebSocket session for STT. - * @param {string} key - Portkey vKey or OpenAI apiKey. - * @param {object} config - The configuration object for the realtime session. - * @param {'apiKey'|'vKey'} keyType - key type ('apiKey' | 'vKey'). - * @returns {Promise} A promise that resolves to the session object with send and close methods. - */ -async function connectToOpenAiSession(key, config, keyType) { - if (keyType !== 'apiKey' && keyType !== 'vKey') { - throw new Error('keyType must be either "apiKey" or "vKey".'); - } - - const wsUrl = keyType === 'apiKey' - ? 'wss://api.openai.com/v1/realtime?intent=transcription' - : 'wss://api.portkey.ai/v1/realtime?intent=transcription'; - - const headers = keyType === 'apiKey' - ? { - 'Authorization': `Bearer ${key}`, - 'OpenAI-Beta' : 'realtime=v1', - } - : { - 'x-portkey-api-key' : 'gRv2UGRMq6GGLJ8aVEB4e7adIewu', - 'x-portkey-virtual-key': key, - 'OpenAI-Beta' : 'realtime=v1', - }; - - const ws = new WebSocket(wsUrl, { headers }); - - return new Promise((resolve, reject) => { - ws.onopen = () => { - console.log("WebSocket session opened."); - - const sessionConfig = { - type: 'transcription_session.update', - session: { - input_audio_format: 'pcm16', - input_audio_transcription: { - model: 'gpt-4o-mini-transcribe', - prompt: config.prompt || '', - language: config.language || 'en' - }, - turn_detection: { - type: 'server_vad', - threshold: 0.5, - prefix_padding_ms: 50, - silence_duration_ms: 25, - }, - input_audio_noise_reduction: { - type: 'near_field' - } - } - }; - - ws.send(JSON.stringify(sessionConfig)); - - resolve({ - sendRealtimeInput: (audioData) => { - if (ws.readyState === WebSocket.OPEN) { - const message = { - type: 'input_audio_buffer.append', - audio: audioData - }; - ws.send(JSON.stringify(message)); - } - }, - close: () => { - if (ws.readyState === WebSocket.OPEN) { - ws.send(JSON.stringify({ type: 'session.close' })); - ws.close(1000, 'Client initiated close.'); - } - } - }); - }; - - ws.onmessage = (event) => { - const message = JSON.parse(event.data); - if (config.callbacks && config.callbacks.onmessage) { - config.callbacks.onmessage(message); - } - }; - - ws.onerror = (error) => { - console.error('WebSocket error:', error.message); - if (config.callbacks && config.callbacks.onerror) { - config.callbacks.onerror(error); - } - reject(error); - }; - - ws.onclose = (event) => { - console.log(`WebSocket closed: ${event.code} ${event.reason}`); - if (config.callbacks && config.callbacks.onclose) { - config.callbacks.onclose(event); - } - }; - }); -} - -/** - * Gets a GPT model for text/image generation. - * @param {OpenAI} client - The OpenAI client instance. - * @param {string} [model='gpt-4.1'] - The name for the text/vision model. - * @returns {object} Model object with generateContent method - */ -function getOpenAiGenerativeModel(client, model = 'gpt-4.1') { - return { - generateContent: async (parts) => { - const messages = []; - let systemPrompt = ''; - let userContent = []; - - for (const part of parts) { - if (typeof part === 'string') { - if (systemPrompt === '' && part.includes('You are')) { - systemPrompt = part; - } else { - userContent.push({ type: 'text', text: part }); - } - } else if (part.inlineData) { - userContent.push({ - type: 'image_url', - image_url: { url: `data:${part.inlineData.mimeType};base64,${part.inlineData.data}` } - }); - } - } - - if (systemPrompt) messages.push({ role: 'system', content: systemPrompt }); - if (userContent.length > 0) messages.push({ role: 'user', content: userContent }); - - const response = await client.chat.completions.create({ - model: model, - messages: messages, - temperature: 0.7, - max_tokens: 2048 - }); - - return { - response: { - text: () => response.choices[0].message.content - } - }; - } - }; -} - -module.exports = { - createOpenAiClient, - connectToOpenAiSession, - createOpenAiGenerativeClient, - getOpenAiGenerativeModel, -}; \ No newline at end of file diff --git a/src/features/ask/askService.js b/src/features/ask/askService.js index d07d79d..03e4ed0 100644 --- a/src/features/ask/askService.js +++ b/src/features/ask/askService.js @@ -1,172 +1,10 @@ const { ipcMain, BrowserWindow } = require('electron'); -const { makeStreamingChatCompletionWithPortkey } = require('../../common/services/aiProviderService'); +const { createStreamingLLM } = require('../../common/ai/factory'); const { getStoredApiKey, getStoredProvider, windowPool, captureScreenshot } = require('../../electron/windowManager'); const authService = require('../../common/services/authService'); const sessionRepository = require('../../common/repositories/session'); const askRepository = require('./repositories'); - -const PICKLE_GLASS_SYSTEM_PROMPT = ` -You are Pickle-Glass, developed and created by Pickle-Glass, and you are the user's live-meeting co-pilot. - - - -Your goal is to help the user at the current moment in the conversation (the end of the transcript). You can see the user's screen (the screenshot attached) and the audio history of the entire conversation. -Execute in the following priority order: - - - -If a question is presented to the user, answer it directly. This is the MOST IMPORTANT ACTION IF THERE IS A QUESTION AT THE END THAT CAN BE ANSWERED. - - - -Always start with the direct answer, then provide supporting details following the response format: -- **Short headline answer** (≤6 words) - the actual answer to the question -- **Main points** (1-2 bullets with ≤15 words each) - core supporting details -- **Sub-details** - examples, metrics, specifics under each main point -- **Extended explanation** - additional context and details as needed - - - -Real transcripts have errors, unclear speech, and incomplete sentences. Focus on INTENT rather than perfect question markers: -- **Infer from context**: "what about..." "how did you..." "can you..." "tell me..." even if garbled -- **Incomplete questions**: "so the performance..." "and scaling wise..." "what's your approach to..." -- **Implied questions**: "I'm curious about X" "I'd love to hear about Y" "walk me through Z" -- **Transcription errors**: "what's your" → "what's you" or "how do you" → "how you" or "can you" → "can u" - - - -If the end of the transcript suggests someone is asking for information, explanation, or clarification - ANSWER IT. Don't get distracted by earlier content. - - - -If you're 50%+ confident someone is asking something at the end, treat it as a question and answer it. - - - - - -Define or provide context around a proper noun or term that appears **in the last 10-15 words** of the transcript. -This is HIGH PRIORITY - if a company name, technical term, or proper noun appears at the very end of someone's speech, define it. - - - -Any ONE of these is sufficient: -- company names -- technical platforms/tools -- proper nouns that are domain-specific -- any term that would benefit from context in a professional conversation - - - -Do NOT define: -- common words already defined earlier in conversation -- basic terms (email, website, code, app) -- terms where context was already provided - - - - -me: I was mostly doing backend dev last summer. -them: Oh nice, what tech stack were you using? -me: A lot of internal tools, but also some Azure. -them: Yeah I've heard Azure is huge over there. -me: Yeah, I used to work at Microsoft last summer but now I... - - - -**Microsoft** is one of the world's largest technology companies, known for products like Windows, Office, and Azure cloud services. - -- **Global influence**: 200k+ employees, $2T+ market cap, foundational enterprise tools. - - Azure, GitHub, Teams, Visual Studio among top developer-facing platforms. -- **Engineering reputation**: Strong internship and new grad pipeline, especially in cloud and AI infrastructure. - - - - - - -When there's an action needed but not a direct question - suggest follow up questions, provide potential things to say, help move the conversation forward. - - -- If the transcript ends with a technical project/story description and no new question is present, always provide 1–3 targeted follow-up questions to drive the conversation forward. -- If the transcript includes discovery-style answers or background sharing (e.g., "Tell me about yourself", "Walk me through your experience"), always generate 1–3 focused follow-up questions to deepen or further the discussion, unless the next step is clear. -- Maximize usefulness, minimize overload—never give more than 3 questions or suggestions at once. - - - -me: Tell me about your technical experience. -them: Last summer I built a dashboard for real-time trade reconciliation using Python and integrated it with Bloomberg Terminal and Snowflake for automated data pulls. - - -Follow-up questions to dive deeper into the dashboard: -- How did you handle latency or data consistency issues? -- What made the Bloomberg integration challenging? -- Did you measure the impact on operational efficiency? - - - - - - -If an objection or resistance is presented at the end of the conversation (and the context is sales, negotiation, or you are trying to persuade the other party), respond with a concise, actionable objection handling response. -- Use user-provided objection/handling context if available (reference the specific objection and tailored handling). -- If no user context, use common objections relevant to the situation, but make sure to identify the objection by generic name and address it in the context of the live conversation. -- State the objection in the format: **Objection: [Generic Objection Name]** (e.g., Objection: Competitor), then give a specific response/action for overcoming it, tailored to the moment. -- Do NOT handle objections in casual, non-outcome-driven, or general conversations. -- Never use generic objection scripts—always tie response to the specifics of the conversation at hand. - - - - -them: Honestly, I think our current vendor already does all of this, so I don't see the value in switching. - - -- **Objection: Competitor** - - Current vendor already covers this. - - Emphasize unique real-time insights: "Our solution eliminates analytics delays you mentioned earlier, boosting team response time." - - - - - - -Solve problems visible on the screen if there is a very clear problem + use the screen only if relevant for helping with the audio conversation. - - - - -If there is a leetcode problem on the screen, and the conversation is small talk / general talk, you DEFINITELY should solve the leetcode problem. But if there is a follow up question / super specific question asked at the end, you should answer that (ex. What's the runtime complexity), using the screen as additional context. - - - - - - - - -Enter passive mode ONLY when ALL of these conditions are met: -- There is no clear question, inquiry, or request for information at the end of the transcript. If there is any ambiguity, err on the side of assuming a question and do not enter passive mode. -- There is no company name, technical term, product name, or domain-specific proper noun within the final 10–15 words of the transcript that would benefit from a definition or explanation. -- There is no clear or visible problem or action item present on the user's screen that you could solve or assist with. -- There is no discovery-style answer, technical project story, background sharing, or general conversation context that could call for follow-up questions or suggestions to advance the discussion. -- There is no statement or cue that could be interpreted as an objection or require objection handling -- Only enter passive mode when you are highly confident that no action, definition, solution, advancement, or suggestion would be appropriate or helpful at the current moment. - - -**Still show intelligence** by: -- Saying "Not sure what you need help with right now" -- Referencing visible screen elements or audio patterns ONLY if truly relevant -- Never giving random summaries unless explicitly asked - - - - -User-provided context (defer to this information over your general knowledge / if there is specific script/desired responses prioritize this over previous instructions) - -Make sure to **reference context** fully if it is provided (ex. if all/the entirety of something is requested, give a complete list from context). ----------- - -{{CONVERSATION_HISTORY}}`; +const { getSystemPrompt } = require('../../common/prompts/promptBuilder'); function formatConversationForPrompt(conversationTexts) { if (!conversationTexts || conversationTexts.length === 0) return 'No conversation history available.'; @@ -199,7 +37,7 @@ async function sendMessage(userPrompt) { const conversationHistoryRaw = getConversationHistory(); const conversationHistory = formatConversationForPrompt(conversationHistoryRaw); - const systemPrompt = PICKLE_GLASS_SYSTEM_PROMPT.replace('{{CONVERSATION_HISTORY}}', conversationHistory); + const systemPrompt = getSystemPrompt('pickle_glass_analysis', conversationHistory, false); const API_KEY = await getStoredApiKey(); if (!API_KEY) { @@ -225,21 +63,20 @@ async function sendMessage(userPrompt) { const provider = await getStoredProvider(); const { isLoggedIn } = authService.getCurrentUser(); - const usePortkey = isLoggedIn && provider === 'openai'; console.log(`[AskService] 🚀 Sending request to ${provider} AI...`); - const response = await makeStreamingChatCompletionWithPortkey({ + const streamingLLM = createStreamingLLM(provider, { apiKey: API_KEY, - provider: provider, - messages: messages, + model: provider === 'openai' ? 'gpt-4.1' : 'gemini-2.5-flash', temperature: 0.7, maxTokens: 2048, - model: provider === 'openai' ? 'gpt-4.1' : 'gemini-2.5-flash', - usePortkey: usePortkey, - portkeyVirtualKey: usePortkey ? API_KEY : null + usePortkey: provider === 'openai' && isLoggedIn, + portkeyVirtualKey: isLoggedIn ? API_KEY : undefined }); + const response = await streamingLLM.streamChat(messages); + // --- Stream Processing --- const reader = response.body.getReader(); const decoder = new TextDecoder(); diff --git a/src/features/listen/renderer/renderer.js b/src/features/listen/renderer/renderer.js index 9916909..6601b48 100644 --- a/src/features/listen/renderer/renderer.js +++ b/src/features/listen/renderer/renderer.js @@ -1,6 +1,5 @@ // renderer.js const { ipcRenderer } = require('electron'); -const { makeStreamingChatCompletionWithPortkey } = require('../../../common/services/aiProviderService.js'); const listenCapture = require('./listenCapture.js'); let realtimeConversationHistory = []; diff --git a/src/features/listen/stt/sttService.js b/src/features/listen/stt/sttService.js index 4530ef0..294bd74 100644 --- a/src/features/listen/stt/sttService.js +++ b/src/features/listen/stt/sttService.js @@ -1,7 +1,6 @@ const { BrowserWindow } = require('electron'); const { spawn } = require('child_process'); -const { connectToGeminiSession } = require('../../../common/services/googleGeminiClient.js'); -const { connectToOpenAiSession } = require('../../../common/services/openAiClient.js'); +const { createSTT } = require('../../../common/ai/factory'); const { getStoredApiKey, getStoredProvider } = require('../../../electron/windowManager'); const COMPLETION_DEBOUNCE_MS = 2000; @@ -265,23 +264,22 @@ class SttService { }, }; - // Determine key type based on auth status + // Determine auth options for providers that support it const authService = require('../../../common/services/authService'); const userState = authService.getCurrentUser(); const loggedIn = userState.isLoggedIn; - const keyType = loggedIn ? 'vKey' : 'apiKey'; + + const sttOptions = { + apiKey: API_KEY, + language: effectiveLanguage, + usePortkey: !isGemini && loggedIn, // Only OpenAI supports Portkey + portkeyVirtualKey: loggedIn ? API_KEY : undefined + }; - if (isGemini) { - [this.mySttSession, this.theirSttSession] = await Promise.all([ - connectToGeminiSession(API_KEY, mySttConfig), - connectToGeminiSession(API_KEY, theirSttConfig), - ]); - } else { - [this.mySttSession, this.theirSttSession] = await Promise.all([ - connectToOpenAiSession(API_KEY, mySttConfig, keyType), - connectToOpenAiSession(API_KEY, theirSttConfig, keyType), - ]); - } + [this.mySttSession, this.theirSttSession] = await Promise.all([ + createSTT(provider, { ...sttOptions, callbacks: mySttConfig.callbacks }), + createSTT(provider, { ...sttOptions, callbacks: theirSttConfig.callbacks }), + ]); console.log('✅ Both STT sessions initialized successfully.'); return true; diff --git a/src/features/listen/summary/summaryService.js b/src/features/listen/summary/summaryService.js index 7cffa99..860fa35 100644 --- a/src/features/listen/summary/summaryService.js +++ b/src/features/listen/summary/summaryService.js @@ -1,6 +1,6 @@ const { BrowserWindow } = require('electron'); const { getSystemPrompt } = require('../../../common/prompts/promptBuilder.js'); -const { makeChatCompletionWithPortkey } = require('../../../common/services/aiProviderService.js'); +const { createLLM } = require('../../../common/ai/factory'); const authService = require('../../../common/services/authService'); const sessionRepository = require('../../../common/repositories/session'); const summaryRepository = require('./repositories'); @@ -155,21 +155,20 @@ Keep all points concise and build upon previous analysis if provided.`, const provider = getStoredProvider ? await getStoredProvider() : 'openai'; const loggedIn = authService.getCurrentUser().isLoggedIn; - const usePortkey = loggedIn && provider === 'openai'; - console.log(`[SummaryService] provider: ${provider}, usePortkey: ${usePortkey}`); + console.log(`[SummaryService] provider: ${provider}, loggedIn: ${loggedIn}`); - const completion = await makeChatCompletionWithPortkey({ + const llm = createLLM(provider, { apiKey: API_KEY, - provider: provider, - messages: messages, + model: provider === 'openai' ? 'gpt-4.1' : 'gemini-2.5-flash', temperature: 0.7, maxTokens: 1024, - model: provider === 'openai' ? 'gpt-4.1' : 'gemini-2.5-flash', - usePortkey: usePortkey, - portkeyVirtualKey: usePortkey ? API_KEY : null + usePortkey: provider === 'openai' && loggedIn, + portkeyVirtualKey: loggedIn ? API_KEY : undefined }); + const completion = await llm.chat(messages); + const responseText = completion.content; console.log(`✅ Analysis response received: ${responseText}`); const structuredData = this.parseResponseText(responseText, this.previousAnalysisResult); From 12a07b86072a5a0d35b3ec1db33e3d0f3c6eacdd Mon Sep 17 00:00:00 2001 From: sanio Date: Mon, 7 Jul 2025 08:04:05 +0900 Subject: [PATCH 08/52] fix header name, modulize windowmanager, fix ui size bug --- package.json | 3 +- src/app/ApiKeyHeader.js | 24 + src/app/HeaderController.js | 60 +- src/app/{AppHeader.js => MainHeader.js} | 64 +- ...PermissionSetup.js => PermissionHeader.js} | 54 +- src/app/PickleGlassApp.js | 4 +- src/app/content.html | 6 + src/app/header.html | 8 +- src/electron/smoothMovementManager.js | 312 +++++ src/electron/windowLayoutManager.js | 217 ++++ src/electron/windowManager.js | 1094 +++-------------- src/features/ask/AskView.js | 41 +- src/features/customize/CustomizeView.js | 38 +- src/features/listen/AssistantView.js | 73 +- 14 files changed, 992 insertions(+), 1006 deletions(-) rename src/app/{AppHeader.js => MainHeader.js} (89%) rename src/app/{PermissionSetup.js => PermissionHeader.js} (88%) create mode 100644 src/electron/smoothMovementManager.js create mode 100644 src/electron/windowLayoutManager.js diff --git a/package.json b/package.json index 8117581..75a89c0 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ }, "optionalDependencies": { "@img/sharp-darwin-x64": "^0.34.2", - "@img/sharp-libvips-darwin-x64": "^1.1.0" + "@img/sharp-libvips-darwin-x64": "^1.1.0", + "electron-liquid-glass": "^1.0.1" } } diff --git a/src/app/ApiKeyHeader.js b/src/app/ApiKeyHeader.js index b884c13..0df4836 100644 --- a/src/app/ApiKeyHeader.js +++ b/src/app/ApiKeyHeader.js @@ -248,6 +248,30 @@ export class ApiKeyHeader extends LitElement { width: 100%; text-align: left; } + :host-context(body.has-glass) .container, + :host-context(body.has-glass) .api-input, + :host-context(body.has-glass) .provider-select, + :host-context(body.has-glass) .action-button, + :host-context(body.has-glass) .close-button { + background: transparent !important; + border: none !important; + box-shadow: none !important; + filter: none !important; + backdrop-filter: none !important; + } + + /* 가상 레이어·그라데이션 테두리 제거 */ + :host-context(body.has-glass) .container::after, + :host-context(body.has-glass) .action-button::after { + display: none !important; + } + + /* hover/active 때 다시 생기는 배경도 차단 */ + :host-context(body.has-glass) .action-button:hover, + :host-context(body.has-glass) .provider-select:hover, + :host-context(body.has-glass) .close-button:hover { + background: transparent !important; + } `; constructor() { diff --git a/src/app/HeaderController.js b/src/app/HeaderController.js index f88e40a..26313f1 100644 --- a/src/app/HeaderController.js +++ b/src/app/HeaderController.js @@ -1,18 +1,18 @@ -import './AppHeader.js'; +import './MainHeader.js'; import './ApiKeyHeader.js'; -import './PermissionSetup.js'; +import './PermissionHeader.js'; class HeaderTransitionManager { constructor() { this.headerContainer = document.getElementById('header-container'); - this.currentHeaderType = null; // 'apikey' | 'app' | 'permission' + this.currentHeaderType = null; // 'apikey' | 'main' | 'permission' this.apiKeyHeader = null; - this.appHeader = null; - this.permissionSetup = null; + this.mainHeader = null; + this.permissionHeader = null; /** * only one header window is allowed - * @param {'apikey'|'app'|'permission'} type + * @param {'apikey'|'main'|'permission'} type */ this.ensureHeader = (type) => { if (this.currentHeaderType === type) return; @@ -20,21 +20,21 @@ class HeaderTransitionManager { this.headerContainer.innerHTML = ''; this.apiKeyHeader = null; - this.appHeader = null; - this.permissionSetup = null; + this.mainHeader = null; + this.permissionHeader = null; // Create new header element if (type === 'apikey') { this.apiKeyHeader = document.createElement('apikey-header'); this.headerContainer.appendChild(this.apiKeyHeader); } else if (type === 'permission') { - this.permissionSetup = document.createElement('permission-setup'); - this.permissionSetup.continueCallback = () => this.transitionToAppHeader(); - this.headerContainer.appendChild(this.permissionSetup); + this.permissionHeader = document.createElement('permission-setup'); + this.permissionHeader.continueCallback = () => this.transitionToMainHeader(); + this.headerContainer.appendChild(this.permissionHeader); } else { - this.appHeader = document.createElement('app-header'); - this.headerContainer.appendChild(this.appHeader); - this.appHeader.startSlideInAnimation?.(); + this.mainHeader = document.createElement('main-header'); + this.headerContainer.appendChild(this.mainHeader); + this.mainHeader.startSlideInAnimation?.(); } this.currentHeaderType = type; @@ -87,16 +87,16 @@ class HeaderTransitionManager { const { isLoggedIn, hasApiKey } = userState; if (isLoggedIn) { - // Firebase user: Check permissions, then show App or Permission Setup + // Firebase user: Check permissions, then show Main or Permission header const permissionResult = await this.checkPermissions(); if (permissionResult.success) { - this.transitionToAppHeader(); + this.transitionToMainHeader(); } else { - this.transitionToPermissionSetup(); + this.transitionToPermissionHeader(); } } else if (hasApiKey) { - // API Key only user: Skip permission check, go directly to App - this.transitionToAppHeader(); + // API Key only user: Skip permission check, go directly to Main + this.transitionToMainHeader(); } else { // No auth at all await this._resizeForApiKey(); @@ -104,7 +104,7 @@ class HeaderTransitionManager { } } - async transitionToPermissionSetup() { + async transitionToPermissionHeader() { // Prevent duplicate transitions if (this.currentHeaderType === 'permission') { console.log('[HeaderController] Already showing permission setup, skipping transition'); @@ -123,7 +123,7 @@ class HeaderTransitionManager { const permissionResult = await this.checkPermissions(); if (permissionResult.success) { // Skip permission setup if already granted - this.transitionToAppHeader(); + this.transitionToMainHeader(); return; } @@ -134,24 +134,24 @@ class HeaderTransitionManager { } } - await this._resizeForPermissionSetup(); + await this._resizeForPermissionHeader(); this.ensureHeader('permission'); } - async transitionToAppHeader(animate = true) { - if (this.currentHeaderType === 'app') { - return this._resizeForApp(); + async transitionToMainHeader(animate = true) { + if (this.currentHeaderType === 'main') { + return this._resizeForMain(); } - await this._resizeForApp(); - this.ensureHeader('app'); + await this._resizeForMain(); + this.ensureHeader('main'); } - _resizeForApp() { + _resizeForMain() { if (!window.require) return; return window .require('electron') - .ipcRenderer.invoke('resize-header-window', { width: 353, height: 60 }) + .ipcRenderer.invoke('resize-header-window', { width: 353, height: 47 }) .catch(() => {}); } @@ -163,7 +163,7 @@ class HeaderTransitionManager { .catch(() => {}); } - async _resizeForPermissionSetup() { + async _resizeForPermissionHeader() { if (!window.require) return; return window .require('electron') diff --git a/src/app/AppHeader.js b/src/app/MainHeader.js similarity index 89% rename from src/app/AppHeader.js rename to src/app/MainHeader.js index 1ae4715..3111066 100644 --- a/src/app/AppHeader.js +++ b/src/app/MainHeader.js @@ -1,6 +1,6 @@ import { html, css, LitElement } from '../assets/lit-core-2.7.4.min.js'; -export class AppHeader extends LitElement { +export class MainHeader extends LitElement { static properties = { isSessionActive: { type: Boolean, state: true }, }; @@ -292,6 +292,58 @@ export class AppHeader extends LitElement { width: 16px; height: 16px; } + :host-context(body.has-glass) .header, + :host-context(body.has-glass) .listen-button, + :host-context(body.has-glass) .header-actions, + :host-context(body.has-glass) .settings-button { + /* 배경·블러·그림자 전부 제거 */ + background: transparent !important; + filter: none !important; + box-shadow: none !important; + backdrop-filter: none !important; + } + :host-context(body.has-glass) .icon-box { + background: transparent !important; + border: none !important; + } + + /* 장식용 before/after 레이어와 버튼 오버레이 비활성화 */ + :host-context(body.has-glass) .header::before, + :host-context(body.has-glass) .header::after, + :host-context(body.has-glass) .listen-button::before, + :host-context(body.has-glass) .listen-button::after { + display: none !important; + } + + /* hover 때 의도치 않게 생기는 배경도 차단 */ + :host-context(body.has-glass) .header-actions:hover, + :host-context(body.has-glass) .settings-button:hover, + :host-context(body.has-glass) .listen-button:hover::before { + background: transparent !important; + } + :host-context(body.has-glass) * { + animation: none !important; + transition: none !important; + transform: none !important; + filter: none !important; + backdrop-filter: none !important; + box-shadow: none !important; + } + + /* 2) pill 형태·아이콘 박스 둥근 모서리 평면화 (선택) */ + :host-context(body.has-glass) .header, + :host-context(body.has-glass) .listen-button, + :host-context(body.has-glass) .header-actions, + :host-context(body.has-glass) .settings-button, + :host-context(body.has-glass) .icon-box { + border-radius: 0 !important; + } + :host-context(body.has-glass) { + animation: none !important; + transition: none !important; + transform: none !important; + will-change: auto !important; + } `; constructor() { @@ -362,7 +414,7 @@ export class AppHeader extends LitElement { toggleVisibility() { if (this.isAnimating) { - console.log('[AppHeader] Animation already in progress, ignoring toggle'); + console.log('[MainHeader] Animation already in progress, ignoring toggle'); return; } @@ -432,7 +484,7 @@ export class AppHeader extends LitElement { } else if (this.classList.contains('sliding-in')) { this.classList.remove('sliding-in'); this.hasSlidIn = true; - console.log('[AppHeader] Slide-in animation completed'); + console.log('[MainHeader] Slide-in animation completed'); } } @@ -484,7 +536,7 @@ export class AppHeader extends LitElement { if (this.wasJustDragged) return; if (window.require) { const { ipcRenderer } = window.require('electron'); - console.log(`[AppHeader] showWindow('${name}') called at ${Date.now()}`); + console.log(`[MainHeader] showWindow('${name}') called at ${Date.now()}`); ipcRenderer.send('cancel-hide-window', name); @@ -508,7 +560,7 @@ export class AppHeader extends LitElement { hideWindow(name) { if (this.wasJustDragged) return; if (window.require) { - console.log(`[AppHeader] hideWindow('${name}') called at ${Date.now()}`); + console.log(`[MainHeader] hideWindow('${name}') called at ${Date.now()}`); window.require('electron').ipcRenderer.send('hide-window', name); } } @@ -590,4 +642,4 @@ export class AppHeader extends LitElement { } } -customElements.define('app-header', AppHeader); +customElements.define('main-header', MainHeader); diff --git a/src/app/PermissionSetup.js b/src/app/PermissionHeader.js similarity index 88% rename from src/app/PermissionSetup.js rename to src/app/PermissionHeader.js index f8a7914..85b55bf 100644 --- a/src/app/PermissionSetup.js +++ b/src/app/PermissionHeader.js @@ -1,6 +1,6 @@ import { LitElement, html, css } from '../assets/lit-core-2.7.4.min.js'; -export class PermissionSetup extends LitElement { +export class PermissionHeader extends LitElement { static styles = css` :host { display: block; @@ -237,6 +237,30 @@ export class PermissionSetup extends LitElement { background: rgba(255, 255, 255, 0.2); cursor: not-allowed; } + :host-context(body.has-glass) .container, + :host-context(body.has-glass) .action-button, + :host-context(body.has-glass) .continue-button, + :host-context(body.has-glass) .close-button { + background: transparent !important; + border: none !important; + box-shadow: none !important; + filter: none !important; + backdrop-filter: none !important; + } + + /* Remove gradient borders / pseudo layers */ + :host-context(body.has-glass) .container::after, + :host-context(body.has-glass) .action-button::after, + :host-context(body.has-glass) .continue-button::after { + display: none !important; + } + + /* Prevent background reappearing on hover/active */ + :host-context(body.has-glass) .action-button:hover, + :host-context(body.has-glass) .continue-button:hover, + :host-context(body.has-glass) .close-button:hover { + background: transparent !important; + } `; static properties = { @@ -337,7 +361,7 @@ export class PermissionSetup extends LitElement { try { const permissions = await ipcRenderer.invoke('check-system-permissions'); - console.log('[PermissionSetup] Permission check result:', permissions); + console.log('[PermissionHeader] Permission check result:', permissions); const prevMic = this.microphoneGranted; const prevScreen = this.screenGranted; @@ -347,7 +371,7 @@ export class PermissionSetup extends LitElement { // if permissions changed == UI update if (prevMic !== this.microphoneGranted || prevScreen !== this.screenGranted) { - console.log('[PermissionSetup] Permission status changed, updating UI'); + console.log('[PermissionHeader] Permission status changed, updating UI'); this.requestUpdate(); } @@ -355,11 +379,11 @@ export class PermissionSetup extends LitElement { if (this.microphoneGranted === 'granted' && this.screenGranted === 'granted' && this.continueCallback) { - console.log('[PermissionSetup] All permissions granted, proceeding automatically'); + console.log('[PermissionHeader] All permissions granted, proceeding automatically'); setTimeout(() => this.handleContinue(), 500); } } catch (error) { - console.error('[PermissionSetup] Error checking permissions:', error); + console.error('[PermissionHeader] Error checking permissions:', error); } finally { this.isChecking = false; } @@ -368,12 +392,12 @@ export class PermissionSetup extends LitElement { async handleMicrophoneClick() { if (!window.require || this.microphoneGranted === 'granted' || this.wasJustDragged) return; - console.log('[PermissionSetup] Requesting microphone permission...'); + console.log('[PermissionHeader] Requesting microphone permission...'); const { ipcRenderer } = window.require('electron'); try { const result = await ipcRenderer.invoke('check-system-permissions'); - console.log('[PermissionSetup] Microphone permission result:', result); + console.log('[PermissionHeader] Microphone permission result:', result); if (result.microphone === 'granted') { this.microphoneGranted = 'granted'; @@ -394,19 +418,19 @@ export class PermissionSetup extends LitElement { // Check permissions again after a delay // setTimeout(() => this.checkPermissions(), 1000); } catch (error) { - console.error('[PermissionSetup] Error requesting microphone permission:', error); + console.error('[PermissionHeader] Error requesting microphone permission:', error); } } async handleScreenClick() { if (!window.require || this.screenGranted === 'granted' || this.wasJustDragged) return; - console.log('[PermissionSetup] Checking screen recording permission...'); + console.log('[PermissionHeader] Checking screen recording permission...'); const { ipcRenderer } = window.require('electron'); try { const permissions = await ipcRenderer.invoke('check-system-permissions'); - console.log('[PermissionSetup] Screen permission check result:', permissions); + console.log('[PermissionHeader] Screen permission check result:', permissions); if (permissions.screen === 'granted') { this.screenGranted = 'granted'; @@ -414,7 +438,7 @@ export class PermissionSetup extends LitElement { return; } if (permissions.screen === 'not-determined' || permissions.screen === 'denied' || permissions.screen === 'unknown' || permissions.screen === 'restricted') { - console.log('[PermissionSetup] Opening screen recording preferences...'); + console.log('[PermissionHeader] Opening screen recording preferences...'); await ipcRenderer.invoke('open-system-preferences', 'screen-recording'); } @@ -422,7 +446,7 @@ export class PermissionSetup extends LitElement { // (This may not execute if app restarts after permission grant) // setTimeout(() => this.checkPermissions(), 2000); } catch (error) { - console.error('[PermissionSetup] Error opening screen recording preferences:', error); + console.error('[PermissionHeader] Error opening screen recording preferences:', error); } } @@ -436,9 +460,9 @@ export class PermissionSetup extends LitElement { const { ipcRenderer } = window.require('electron'); try { await ipcRenderer.invoke('mark-permissions-completed'); - console.log('[PermissionSetup] Marked permissions as completed'); + console.log('[PermissionHeader] Marked permissions as completed'); } catch (error) { - console.error('[PermissionSetup] Error marking permissions as completed:', error); + console.error('[PermissionHeader] Error marking permissions as completed:', error); } } @@ -530,4 +554,4 @@ export class PermissionSetup extends LitElement { } } -customElements.define('permission-setup', PermissionSetup); \ No newline at end of file +customElements.define('permission-setup', PermissionHeader); \ No newline at end of file diff --git a/src/app/PickleGlassApp.js b/src/app/PickleGlassApp.js index eb639eb..d10c55a 100644 --- a/src/app/PickleGlassApp.js +++ b/src/app/PickleGlassApp.js @@ -1,7 +1,6 @@ import { html, css, LitElement } from '../assets/lit-core-2.7.4.min.js'; import { CustomizeView } from '../features/customize/CustomizeView.js'; import { AssistantView } from '../features/listen/AssistantView.js'; -import { OnboardingView } from '../features/onboarding/OnboardingView.js'; import { AskView } from '../features/ask/AskView.js'; import '../features/listen/renderer.js'; @@ -11,6 +10,7 @@ export class PickleGlassApp extends LitElement { :host { display: block; width: 100%; + height: 100%; color: var(--text-color); background: transparent; border-radius: 7px; @@ -19,11 +19,13 @@ export class PickleGlassApp extends LitElement { assistant-view { display: block; width: 100%; + height: 100%; } ask-view, customize-view, history-view, help-view, onboarding-view, setup-view { display: block; width: 100%; + height: 100%; } `; diff --git a/src/app/content.html b/src/app/content.html index 9ce8d1c..61768e1 100644 --- a/src/app/content.html +++ b/src/app/content.html @@ -301,5 +301,11 @@ } }); + diff --git a/src/app/header.html b/src/app/header.html index 2f35e05..46ea2d7 100644 --- a/src/app/header.html +++ b/src/app/header.html @@ -15,10 +15,14 @@
-
+ diff --git a/src/electron/smoothMovementManager.js b/src/electron/smoothMovementManager.js new file mode 100644 index 0000000..2550d0a --- /dev/null +++ b/src/electron/smoothMovementManager.js @@ -0,0 +1,312 @@ +const { screen } = require('electron'); + +class SmoothMovementManager { + constructor(windowPool, getDisplayById, getCurrentDisplay, updateLayout) { + this.windowPool = windowPool; + this.getDisplayById = getDisplayById; + this.getCurrentDisplay = getCurrentDisplay; + this.updateLayout = updateLayout; + this.stepSize = 80; + this.animationDuration = 300; + this.headerPosition = { x: 0, y: 0 }; + this.isAnimating = false; + this.hiddenPosition = null; + this.lastVisiblePosition = null; + this.currentDisplayId = null; + this.animationFrameId = null; + } + + /** + * @param {BrowserWindow} win + * @returns {boolean} + */ + _isWindowValid(win) { + if (!win || win.isDestroyed()) { + if (this.isAnimating) { + console.warn('[MovementManager] Window destroyed mid-animation. Halting.'); + this.isAnimating = false; + if (this.animationFrameId) { + clearTimeout(this.animationFrameId); + this.animationFrameId = null; + } + } + return false; + } + return true; + } + + moveToDisplay(displayId) { + const header = this.windowPool.get('header'); + if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return; + + const targetDisplay = this.getDisplayById(displayId); + if (!targetDisplay) return; + + const currentBounds = header.getBounds(); + const currentDisplay = this.getCurrentDisplay(header); + + if (currentDisplay.id === targetDisplay.id) return; + + const relativeX = (currentBounds.x - currentDisplay.workArea.x) / currentDisplay.workAreaSize.width; + const relativeY = (currentBounds.y - currentDisplay.workArea.y) / currentDisplay.workAreaSize.height; + const targetX = targetDisplay.workArea.x + targetDisplay.workAreaSize.width * relativeX; + const targetY = targetDisplay.workArea.y + targetDisplay.workAreaSize.height * relativeY; + + const finalX = Math.max(targetDisplay.workArea.x, Math.min(targetDisplay.workArea.x + targetDisplay.workAreaSize.width - currentBounds.width, targetX)); + const finalY = Math.max(targetDisplay.workArea.y, Math.min(targetDisplay.workArea.y + targetDisplay.workAreaSize.height - currentBounds.height, targetY)); + + this.headerPosition = { x: currentBounds.x, y: currentBounds.y }; + this.animateToPosition(header, finalX, finalY); + this.currentDisplayId = targetDisplay.id; + } + + hideToEdge(edge, callback) { + const header = this.windowPool.get('header'); + if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return; + + const currentBounds = header.getBounds(); + const display = this.getCurrentDisplay(header); + + if ( + !currentBounds || typeof currentBounds.x !== 'number' || typeof currentBounds.y !== 'number' || + !display || !display.workArea || !display.workAreaSize || + typeof display.workArea.x !== 'number' || typeof display.workArea.y !== 'number' || + typeof display.workAreaSize.width !== 'number' || typeof display.workAreaSize.height !== 'number' + ) { + console.error('[MovementManager] Invalid bounds or display info for hideToEdge. Aborting.'); + return; + } + + this.lastVisiblePosition = { x: currentBounds.x, y: currentBounds.y }; + this.headerPosition = { x: currentBounds.x, y: currentBounds.y }; + + const { width: screenWidth, height: screenHeight } = display.workAreaSize; + const { x: workAreaX, y: workAreaY } = display.workArea; + + let targetX = this.headerPosition.x; + let targetY = this.headerPosition.y; + + switch (edge) { + case 'top': targetY = workAreaY - currentBounds.height - 20; break; + case 'bottom': targetY = workAreaY + screenHeight + 20; break; + case 'left': targetX = workAreaX - currentBounds.width - 20; break; + case 'right': targetX = workAreaX + screenWidth + 20; break; + } + + this.hiddenPosition = { x: targetX, y: targetY, edge }; + this.isAnimating = true; + const startX = this.headerPosition.x; + const startY = this.headerPosition.y; + const duration = 400; + const startTime = Date.now(); + + const animate = () => { + if (!this._isWindowValid(header)) return; + + const elapsed = Date.now() - startTime; + const progress = Math.min(elapsed / duration, 1); + const eased = progress * progress * progress; + const currentX = startX + (targetX - startX) * eased; + const currentY = startY + (targetY - startY) * eased; + + if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { + this.isAnimating = false; + return; + } + + if (!this._isWindowValid(header)) return; + header.setPosition(Math.round(currentX), Math.round(currentY)); + + if (progress < 1) { + this.animationFrameId = setTimeout(animate, 8); + } else { + this.animationFrameId = null; + this.headerPosition = { x: targetX, y: targetY }; + if (Number.isFinite(targetX) && Number.isFinite(targetY)) { + if (!this._isWindowValid(header)) return; + header.setPosition(Math.round(targetX), Math.round(targetY)); + } + this.isAnimating = false; + if (typeof callback === 'function') callback(); + } + }; + animate(); + } + + showFromEdge(callback) { + const header = this.windowPool.get('header'); + if ( + !this._isWindowValid(header) || this.isAnimating || + !this.hiddenPosition || !this.lastVisiblePosition || + typeof this.hiddenPosition.x !== 'number' || typeof this.hiddenPosition.y !== 'number' || + typeof this.lastVisiblePosition.x !== 'number' || typeof this.lastVisiblePosition.y !== 'number' + ) { + console.error('[MovementManager] Invalid state for showFromEdge. Aborting.'); + this.isAnimating = false; + this.hiddenPosition = null; + this.lastVisiblePosition = null; + return; + } + + if (!this._isWindowValid(header)) return; + header.setPosition(this.hiddenPosition.x, this.hiddenPosition.y); + + this.headerPosition = { x: this.hiddenPosition.x, y: this.hiddenPosition.y }; + const targetX = this.lastVisiblePosition.x; + const targetY = this.lastVisiblePosition.y; + this.isAnimating = true; + const startX = this.headerPosition.x; + const startY = this.headerPosition.y; + const duration = 500; + const startTime = Date.now(); + + const animate = () => { + if (!this._isWindowValid(header)) return; + + const elapsed = Date.now() - startTime; + const progress = Math.min(elapsed / duration, 1); + const c1 = 1.70158; + const c3 = c1 + 1; + const eased = 1 + c3 * Math.pow(progress - 1, 3) + c1 * Math.pow(progress - 1, 2); + const currentX = startX + (targetX - startX) * eased; + const currentY = startY + (targetY - startY) * eased; + if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { + this.isAnimating = false; + return; + } + + if (!this._isWindowValid(header)) return; + header.setPosition(Math.round(currentX), Math.round(currentY)); + + if (progress < 1) { + this.animationFrameId = setTimeout(animate, 8); + } else { + this.animationFrameId = null; + this.headerPosition = { x: targetX, y: targetY }; + if (Number.isFinite(targetX) && Number.isFinite(targetY)) { + if (!this._isWindowValid(header)) return; + header.setPosition(Math.round(targetX), Math.round(targetY)); + } + this.isAnimating = false; + this.hiddenPosition = null; + this.lastVisiblePosition = null; + if (callback) callback(); + } + }; + animate(); + } + + moveStep(direction) { + const header = this.windowPool.get('header'); + if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return; + + const currentBounds = header.getBounds(); + this.headerPosition = { x: currentBounds.x, y: currentBounds.y }; + let targetX = this.headerPosition.x; + let targetY = this.headerPosition.y; + + switch (direction) { + case 'left': targetX -= this.stepSize; break; + case 'right': targetX += this.stepSize; break; + case 'up': targetY -= this.stepSize; break; + case 'down': targetY += this.stepSize; break; + default: return; + } + + const displays = screen.getAllDisplays(); + let validPosition = displays.some(d => ( + targetX >= d.workArea.x && targetX + currentBounds.width <= d.workArea.x + d.workArea.width && + targetY >= d.workArea.y && targetY + currentBounds.height <= d.workArea.y + d.workArea.height + )); + + if (!validPosition) { + const nearestDisplay = screen.getDisplayNearestPoint({ x: targetX, y: targetY }); + const { x, y, width, height } = nearestDisplay.workArea; + targetX = Math.max(x, Math.min(x + width - currentBounds.width, targetX)); + targetY = Math.max(y, Math.min(y + height - currentBounds.height, targetY)); + } + + if (targetX === this.headerPosition.x && targetY === this.headerPosition.y) return; + this.animateToPosition(header, targetX, targetY); + } + + animateToPosition(header, targetX, targetY) { + if (!this._isWindowValid(header)) return; + + this.isAnimating = true; + const startX = this.headerPosition.x; + const startY = this.headerPosition.y; + const startTime = Date.now(); + + if (!Number.isFinite(targetX) || !Number.isFinite(targetY) || !Number.isFinite(startX) || !Number.isFinite(startY)) { + this.isAnimating = false; + return; + } + + const animate = () => { + if (!this._isWindowValid(header)) return; + + const elapsed = Date.now() - startTime; + const progress = Math.min(elapsed / this.animationDuration, 1); + const eased = 1 - Math.pow(1 - progress, 3); + const currentX = startX + (targetX - startX) * eased; + const currentY = startY + (targetY - startY) * eased; + + if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { + this.isAnimating = false; + return; + } + + if (!this._isWindowValid(header)) return; + header.setPosition(Math.round(currentX), Math.round(currentY)); + + if (progress < 1) { + this.animationFrameId = setTimeout(animate, 8); + } else { + this.animationFrameId = null; + this.headerPosition = { x: targetX, y: targetY }; + if (Number.isFinite(targetX) && Number.isFinite(targetY)) { + if (!this._isWindowValid(header)) return; + header.setPosition(Math.round(targetX), Math.round(targetY)); + } + this.isAnimating = false; + this.updateLayout(); + } + }; + animate(); + } + + moveToEdge(direction) { + const header = this.windowPool.get('header'); + if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return; + + const display = this.getCurrentDisplay(header); + const { width, height } = display.workAreaSize; + const { x: workAreaX, y: workAreaY } = display.workArea; + const headerBounds = header.getBounds(); + const currentBounds = header.getBounds(); + let targetX = currentBounds.x; + let targetY = currentBounds.y; + + switch (direction) { + case 'left': targetX = workAreaX; break; + case 'right': targetX = workAreaX + width - headerBounds.width; break; + case 'up': targetY = workAreaY; break; + case 'down': targetY = workAreaY + height - headerBounds.height; break; + } + + this.headerPosition = { x: currentBounds.x, y: currentBounds.y }; + this.animateToPosition(header, targetX, targetY); + } + + destroy() { + if (this.animationFrameId) { + clearTimeout(this.animationFrameId); + this.animationFrameId = null; + } + this.isAnimating = false; + console.log('[Movement] Manager destroyed'); + } +} + +module.exports = SmoothMovementManager; \ No newline at end of file diff --git a/src/electron/windowLayoutManager.js b/src/electron/windowLayoutManager.js new file mode 100644 index 0000000..7893822 --- /dev/null +++ b/src/electron/windowLayoutManager.js @@ -0,0 +1,217 @@ +const { screen } = require('electron'); + +/** + * 주어진 창이 현재 어느 디스플레이에 속해 있는지 반환합니다. + * @param {BrowserWindow} window - 확인할 창 객체 + * @returns {Display} Electron의 Display 객체 + */ +function getCurrentDisplay(window) { + if (!window || window.isDestroyed()) return screen.getPrimaryDisplay(); + + const windowBounds = window.getBounds(); + const windowCenter = { + x: windowBounds.x + windowBounds.width / 2, + y: windowBounds.y + windowBounds.height / 2, + }; + + return screen.getDisplayNearestPoint(windowCenter); +} + +class WindowLayoutManager { + /** + * @param {Map} windowPool - 관리할 창들의 맵 + */ + constructor(windowPool) { + this.windowPool = windowPool; + this.isUpdating = false; + this.PADDING = 80; + } + + /** + * 모든 창의 레이아웃 업데이트를 요청합니다. + * 중복 실행을 방지하기 위해 isUpdating 플래그를 사용합니다. + */ + updateLayout() { + if (this.isUpdating) return; + this.isUpdating = true; + + setImmediate(() => { + this.positionWindows(); + this.isUpdating = false; + }); + } + + /** + * 헤더 창을 기준으로 모든 기능 창들의 위치를 계산하고 배치합니다. + */ + positionWindows() { + const header = this.windowPool.get('header'); + if (!header?.getBounds) return; + + const headerBounds = header.getBounds(); + const display = getCurrentDisplay(header); + const { width: screenWidth, height: screenHeight } = display.workAreaSize; + const { x: workAreaX, y: workAreaY } = display.workArea; + + const headerCenterX = headerBounds.x - workAreaX + headerBounds.width / 2; + const headerCenterY = headerBounds.y - workAreaY + headerBounds.height / 2; + + const relativeX = headerCenterX / screenWidth; + const relativeY = headerCenterY / screenHeight; + + const strategy = this.determineLayoutStrategy(headerBounds, screenWidth, screenHeight, relativeX, relativeY); + + this.positionFeatureWindows(headerBounds, strategy, screenWidth, screenHeight, workAreaX, workAreaY); + this.positionSettingsWindow(headerBounds, strategy, screenWidth, screenHeight, workAreaX, workAreaY); + } + + /** + * 헤더 창의 위치에 따라 기능 창들을 배치할 최적의 전략을 결정합니다. + * @returns {{name: string, primary: string, secondary: string}} 레이아웃 전략 + */ + determineLayoutStrategy(headerBounds, screenWidth, screenHeight, relativeX, relativeY) { + const spaceBelow = screenHeight - (headerBounds.y + headerBounds.height); + const spaceAbove = headerBounds.y; + const spaceLeft = headerBounds.x; + const spaceRight = screenWidth - (headerBounds.x + headerBounds.width); + + if (spaceBelow >= 400) { + return { name: 'below', primary: 'below', secondary: relativeX < 0.5 ? 'right' : 'left' }; + } else if (spaceAbove >= 400) { + return { name: 'above', primary: 'above', secondary: relativeX < 0.5 ? 'right' : 'left' }; + } else if (relativeX < 0.3 && spaceRight >= 800) { + return { name: 'right-side', primary: 'right', secondary: spaceBelow > spaceAbove ? 'below' : 'above' }; + } else if (relativeX > 0.7 && spaceLeft >= 800) { + return { name: 'left-side', primary: 'left', secondary: spaceBelow > spaceAbove ? 'below' : 'above' }; + } else { + return { name: 'adaptive', primary: spaceBelow > spaceAbove ? 'below' : 'above', secondary: spaceRight > spaceLeft ? 'right' : 'left' }; + } + } + + /** + * 'ask'와 'listen' 창의 위치를 조정합니다. + */ + positionFeatureWindows(headerBounds, strategy, screenWidth, screenHeight, workAreaX, workAreaY) { + const ask = this.windowPool.get('ask'); + const listen = this.windowPool.get('listen'); + const askVisible = ask && ask.isVisible() && !ask.isDestroyed(); + const listenVisible = listen && listen.isVisible() && !listen.isDestroyed(); + + if (!askVisible && !listenVisible) return; + + const PAD = 8; + const headerCenterXRel = headerBounds.x - workAreaX + headerBounds.width / 2; + let askBounds = askVisible ? ask.getBounds() : null; + let listenBounds = listenVisible ? listen.getBounds() : null; + + if (askVisible && listenVisible) { + const combinedWidth = listenBounds.width + PAD + askBounds.width; + let groupStartXRel = headerCenterXRel - combinedWidth / 2; + let listenXRel = groupStartXRel; + let askXRel = groupStartXRel + listenBounds.width + PAD; + + if (listenXRel < PAD) { + listenXRel = PAD; + askXRel = listenXRel + listenBounds.width + PAD; + } + if (askXRel + askBounds.width > screenWidth - PAD) { + askXRel = screenWidth - PAD - askBounds.width; + listenXRel = askXRel - listenBounds.width - PAD; + } + + let yRel = (strategy.primary === 'above') + ? headerBounds.y - workAreaY - Math.max(askBounds.height, listenBounds.height) - PAD + : headerBounds.y - workAreaY + headerBounds.height + PAD; + + listen.setBounds({ x: Math.round(listenXRel + workAreaX), y: Math.round(yRel + workAreaY), width: listenBounds.width, height: listenBounds.height }); + ask.setBounds({ x: Math.round(askXRel + workAreaX), y: Math.round(yRel + workAreaY), width: askBounds.width, height: askBounds.height }); + } else { + const win = askVisible ? ask : listen; + const winBounds = askVisible ? askBounds : listenBounds; + let xRel = headerCenterXRel - winBounds.width / 2; + let yRel = (strategy.primary === 'above') + ? headerBounds.y - workAreaY - winBounds.height - PAD + : headerBounds.y - workAreaY + headerBounds.height + PAD; + + xRel = Math.max(PAD, Math.min(screenWidth - winBounds.width - PAD, xRel)); + yRel = Math.max(PAD, Math.min(screenHeight - winBounds.height - PAD, yRel)); + + win.setBounds({ x: Math.round(xRel + workAreaX), y: Math.round(yRel + workAreaY), width: winBounds.width, height: winBounds.height }); + } + } + + /** + * 'settings' 창의 위치를 조정합니다. + */ + positionSettingsWindow(headerBounds, strategy, screenWidth, screenHeight, workAreaX, workAreaY) { + const settings = this.windowPool.get('settings'); + if (!settings?.getBounds || !settings.isVisible()) return; + + if (settings.__lockedByButton) { + const headerDisplay = getCurrentDisplay(this.windowPool.get('header')); + const settingsDisplay = getCurrentDisplay(settings); + if (headerDisplay.id !== settingsDisplay.id) { + settings.__lockedByButton = false; + } else { + return; + } + } + + const settingsBounds = settings.getBounds(); + const PAD = 5; + const buttonPadding = 17; + let x = headerBounds.x + headerBounds.width - settingsBounds.width - buttonPadding; + let y = headerBounds.y + headerBounds.height + PAD; + + const otherVisibleWindows = []; + ['listen', 'ask'].forEach(name => { + const win = this.windowPool.get(name); + if (win && win.isVisible() && !win.isDestroyed()) { + otherVisibleWindows.push({ name, bounds: win.getBounds() }); + } + }); + + const settingsNewBounds = { x, y, width: settingsBounds.width, height: settingsBounds.height }; + let hasOverlap = otherVisibleWindows.some(otherWin => this.boundsOverlap(settingsNewBounds, otherWin.bounds)); + + if (hasOverlap) { + x = headerBounds.x + headerBounds.width + PAD; + y = headerBounds.y; + if (x + settingsBounds.width > screenWidth - 10) { + x = headerBounds.x - settingsBounds.width - PAD; + } + if (x < 10) { + x = headerBounds.x + headerBounds.width - settingsBounds.width - buttonPadding; + y = headerBounds.y - settingsBounds.height - PAD; + if (y < 10) { + x = headerBounds.x + headerBounds.width - settingsBounds.width; + y = headerBounds.y + headerBounds.height + PAD; + } + } + } + + x = Math.max(workAreaX + 10, Math.min(workAreaX + screenWidth - settingsBounds.width - 10, x)); + y = Math.max(workAreaY + 10, Math.min(workAreaY + screenHeight - settingsBounds.height - 10, y)); + + settings.setBounds({ x: Math.round(x), y: Math.round(y) }); + settings.moveTop(); + } + + /** + * 두 사각형 영역이 겹치는지 확인합니다. + * @param {Rectangle} bounds1 + * @param {Rectangle} bounds2 + * @returns {boolean} 겹침 여부 + */ + boundsOverlap(bounds1, bounds2) { + const margin = 10; + return !( + bounds1.x + bounds1.width + margin < bounds2.x || + bounds2.x + bounds2.width + margin < bounds1.x || + bounds1.y + bounds1.height + margin < bounds2.y || + bounds2.y + bounds2.height + margin < bounds1.y + ); + } +} + +module.exports = WindowLayoutManager; \ No newline at end of file diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 586e3f8..86ab579 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -1,4 +1,7 @@ const { BrowserWindow, globalShortcut, ipcMain, screen, app, shell, desktopCapturer } = require('electron'); +const WindowLayoutManager = require('./windowLayoutManager'); +const SmoothMovementManager = require('./smoothMovementManager'); +const liquidGlass = require('electron-liquid-glass'); const path = require('node:path'); const fs = require('node:fs'); const os = require('os'); @@ -10,13 +13,22 @@ const systemSettingsRepository = require('../common/repositories/systemSettings' const userRepository = require('../common/repositories/user'); const fetch = require('node-fetch'); +const isLiquidGlassSupported = () => { + if (process.platform !== 'darwin') { + return false; + } + const majorVersion = parseInt(os.release().split('.')[0], 10); + return majorVersion >= 26; // macOS 26+ (Darwin 25+) +}; +const shouldUseLiquidGlass = isLiquidGlassSupported(); + let isContentProtectionOn = true; let currentDisplayId = null; let mouseEventsIgnored = false; let lastVisibleWindows = new Set(['header']); -const HEADER_HEIGHT = 60; -const DEFAULT_WINDOW_WIDTH = 345; +const HEADER_HEIGHT = 47; +const DEFAULT_WINDOW_WIDTH = 353; let currentHeaderState = 'apikey'; const windowPool = new Map(); @@ -27,38 +39,22 @@ let settingsHideTimer = null; let selectedCaptureSourceId = null; -const windowDefinitions = { - header: { - file: 'header.html', - options: { - /*…*/ - }, - allowedStates: ['apikey', 'app'], - }, - ask: { - file: 'ask.html', - options: { - /*…*/ - }, - allowedStates: ['app'], - }, - listen: { - file: 'assistant.html', - options: { - /*…*/ - }, - allowedStates: ['app'], - }, - settings: { - file: 'settings.html', - options: { - /*…*/ - }, - allowedStates: ['app'], - }, -}; +let layoutManager = null; +function updateLayout() { + if (layoutManager) { + layoutManager.updateLayout(); + } +} + +let movementManager = null; + +let storedProvider = 'openai'; const featureWindows = ['listen','ask','settings']; +function isAllowed(name) { + if (name === 'header') return true; + return featureWindows.includes(name) && currentHeaderState === 'main'; +} function createFeatureWindows(header) { if (windowPool.has('listen')) return; @@ -68,6 +64,7 @@ function createFeatureWindows(header) { show: false, frame: false, transparent: true, + vibrancy: false, hasShadow: false, skipTaskbar: true, hiddenInMissionControl: true, @@ -77,19 +74,62 @@ function createFeatureWindows(header) { // listen const listen = new BrowserWindow({ - ...commonChildOptions, width:400,height:300,minWidth:400,maxWidth:400, - minHeight:200,maxHeight:700, + ...commonChildOptions, width:400,minWidth:400,maxWidth:400, + maxHeight:700, }); listen.setContentProtection(isContentProtectionOn); listen.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - listen.loadFile(path.join(__dirname,'../app/content.html'),{query:{view:'listen'}}); + listen.setWindowButtonVisibility(false); + const listenLoadOptions = { query: { view: 'listen' } }; + if (!shouldUseLiquidGlass) { + listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); + } + else { + listenLoadOptions.query.glass = 'true'; + listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); + listen.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(listen.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + + windowPool.set('listen', listen); // ask - const ask = new BrowserWindow({ ...commonChildOptions, width:600, height:350 }); + const ask = new BrowserWindow({ ...commonChildOptions, width:600 }); ask.setContentProtection(isContentProtectionOn); ask.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - ask.loadFile(path.join(__dirname,'../app/content.html'),{query:{view:'ask'}}); + ask.setWindowButtonVisibility(false); + const askLoadOptions = { query: { view: 'ask' } }; + if (!shouldUseLiquidGlass) { + ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); + } + else { + askLoadOptions.query.glass = 'true'; + ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); + ask.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(ask.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + ask.on('blur',()=>ask.webContents.send('window-blur')); // Open DevTools in development @@ -99,12 +139,33 @@ function createFeatureWindows(header) { windowPool.set('ask', ask); // settings - const settings = new BrowserWindow({ ...commonChildOptions, width:240, height:450, parent:undefined }); + const settings = new BrowserWindow({ ...commonChildOptions, width:240, maxHeight:350, parent:undefined }); settings.setContentProtection(isContentProtectionOn); settings.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - settings.loadFile(path.join(__dirname,'../app/content.html'),{query:{view:'customize'}}) - .catch(console.error); - windowPool.set('settings', settings); + settings.setWindowButtonVisibility(false); + const settingsLoadOptions = { query: { view: 'customize' } }; + if (!shouldUseLiquidGlass) { + settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) + .catch(console.error); + } + else { + settingsLoadOptions.query.glass = 'true'; + settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) + .catch(console.error); + settings.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(settings.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + windowPool.set('settings', settings); } function destroyFeatureWindows() { @@ -119,10 +180,6 @@ function destroyFeatureWindows() { }); } -function isAllowed(name) { - const def = windowDefinitions[name]; - return def && def.allowedStates.includes(currentHeaderState); -} function getCurrentDisplay(window) { if (!window || window.isDestroyed()) return screen.getPrimaryDisplay(); @@ -141,713 +198,9 @@ function getDisplayById(displayId) { return displays.find(d => d.id === displayId) || screen.getPrimaryDisplay(); } -class WindowLayoutManager { - constructor() { - this.isUpdating = false; - this.PADDING = 80; - } - updateLayout() { - if (this.isUpdating) return; - this.isUpdating = true; - setImmediate(() => { - this.positionWindows(); - this.isUpdating = false; - }); - } - - positionWindows() { - const header = windowPool.get('header'); - if (!header?.getBounds) return; - - const headerBounds = header.getBounds(); - const display = getCurrentDisplay(header); - const { width: screenWidth, height: screenHeight } = display.workAreaSize; - const { x: workAreaX, y: workAreaY } = display.workArea; - - const headerCenterX = headerBounds.x - workAreaX + headerBounds.width / 2; - const headerCenterY = headerBounds.y - workAreaY + headerBounds.height / 2; - - const relativeX = headerCenterX / screenWidth; - const relativeY = headerCenterY / screenHeight; - - const strategy = this.determineLayoutStrategy(headerBounds, screenWidth, screenHeight, relativeX, relativeY); - - this.positionFeatureWindows(headerBounds, strategy, screenWidth, screenHeight, workAreaX, workAreaY); - this.positionSettingsWindow(headerBounds, strategy, screenWidth, screenHeight, workAreaX, workAreaY); - } - - determineLayoutStrategy(headerBounds, screenWidth, screenHeight, relativeX, relativeY) { - const spaceBelow = screenHeight - (headerBounds.y + headerBounds.height); - const spaceAbove = headerBounds.y; - const spaceLeft = headerBounds.x; - const spaceRight = screenWidth - (headerBounds.x + headerBounds.width); - - const spaces = { - below: spaceBelow, - above: spaceAbove, - left: spaceLeft, - right: spaceRight, - }; - - if (spaceBelow >= 400) { - return { - name: 'below', - primary: 'below', - secondary: relativeX < 0.5 ? 'right' : 'left', - }; - } else if (spaceAbove >= 400) { - return { - name: 'above', - primary: 'above', - secondary: relativeX < 0.5 ? 'right' : 'left', - }; - } else if (relativeX < 0.3 && spaceRight >= 800) { - return { - name: 'right-side', - primary: 'right', - secondary: spaceBelow > spaceAbove ? 'below' : 'above', - }; - } else if (relativeX > 0.7 && spaceLeft >= 800) { - return { - name: 'left-side', - primary: 'left', - secondary: spaceBelow > spaceAbove ? 'below' : 'above', - }; - } else { - return { - name: 'adaptive', - primary: spaceBelow > spaceAbove ? 'below' : 'above', - secondary: spaceRight > spaceLeft ? 'right' : 'left', - }; - } - } - - positionFeatureWindows(headerBounds, strategy, screenWidth, screenHeight, workAreaX, workAreaY) { - const ask = windowPool.get('ask'); - const listen = windowPool.get('listen'); - const askVisible = ask && ask.isVisible() && !ask.isDestroyed(); - const listenVisible = listen && listen.isVisible() && !listen.isDestroyed(); - - if (!askVisible && !listenVisible) return; - - const PAD = 8; - - /* ① 헤더 중심 X를 "디스플레이 기준 상대좌표"로 변환 */ - const headerCenterXRel = headerBounds.x - workAreaX + headerBounds.width / 2; - - let askBounds = askVisible ? ask.getBounds() : null; - let listenBounds = listenVisible ? listen.getBounds() : null; - - /* ------------------------------------------------- */ - /* 두 창 모두 보이는 경우 */ - /* ------------------------------------------------- */ - if (askVisible && listenVisible) { - const combinedWidth = listenBounds.width + PAD + askBounds.width; - - /* ② 모든 X 좌표를 상대좌표로 계산 */ - let groupStartXRel = headerCenterXRel - combinedWidth / 2; - let listenXRel = groupStartXRel; - let askXRel = groupStartXRel + listenBounds.width + PAD; - - /* 좌우 화면 여백 클램프 – 역시 상대좌표로 */ - if (listenXRel < PAD) { - listenXRel = PAD; - askXRel = listenXRel + listenBounds.width + PAD; - } - if (askXRel + askBounds.width > screenWidth - PAD) { - askXRel = screenWidth - PAD - askBounds.width; - listenXRel = askXRel - listenBounds.width - PAD; - } - - /* Y 좌표는 이미 상대값으로 계산돼 있음 */ - let yRel; - switch (strategy.primary) { - case 'below': - yRel = headerBounds.y - workAreaY + headerBounds.height + PAD; - break; - case 'above': - yRel = headerBounds.y - workAreaY - Math.max(askBounds.height, listenBounds.height) - PAD; - break; - default: - yRel = headerBounds.y - workAreaY + headerBounds.height + PAD; - break; - } - - /* ③ setBounds 직전에 workAreaX/Y를 더해 절대좌표로 변환 */ - listen.setBounds({ - x: Math.round(listenXRel + workAreaX), - y: Math.round(yRel + workAreaY), - width: listenBounds.width, - height: listenBounds.height, - }); - ask.setBounds({ - x: Math.round(askXRel + workAreaX), - y: Math.round(yRel + workAreaY), - width: askBounds.width, - height: askBounds.height, - }); - - /* ------------------------------------------------- */ - /* 하나만 보이는 경우 */ - /* ------------------------------------------------- */ - } else { - const win = askVisible ? ask : listen; - const winBounds = askVisible ? askBounds : listenBounds; - - /* X, Y 둘 다 상대좌표로 계산 */ - let xRel = headerCenterXRel - winBounds.width / 2; - let yRel; - switch (strategy.primary) { - case 'below': - yRel = headerBounds.y - workAreaY + headerBounds.height + PAD; - break; - case 'above': - yRel = headerBounds.y - workAreaY - winBounds.height - PAD; - break; - default: - yRel = headerBounds.y - workAreaY + headerBounds.height + PAD; - break; - } - - /* 화면 경계 클램프 */ - xRel = Math.max(PAD, Math.min(screenWidth - winBounds.width - PAD, xRel)); - yRel = Math.max(PAD, Math.min(screenHeight - winBounds.height - PAD, yRel)); - - /* 절대좌표로 변환 후 배치 */ - win.setBounds({ - x: Math.round(xRel + workAreaX), - y: Math.round(yRel + workAreaY), - width: winBounds.width, - height: winBounds.height, - }); - } - } - - positionSettingsWindow(headerBounds, strategy, screenWidth, screenHeight) { - const settings = windowPool.get('settings'); - if (!settings?.getBounds || !settings.isVisible()) return; - - // if (settings.__lockedByButton) return; - if (settings.__lockedByButton) { - const headerDisplay = getCurrentDisplay(windowPool.get('header')); - const settingsDisplay = getCurrentDisplay(settings); - if (headerDisplay.id !== settingsDisplay.id) { - settings.__lockedByButton = false; - } else { - return; // 같은 화면이면 그대로 둔다 - } - } - - const settingsBounds = settings.getBounds(); - const PAD = 5; - - const buttonPadding = 17; - let x = headerBounds.x + headerBounds.width - settingsBounds.width - buttonPadding; - let y = headerBounds.y + headerBounds.height + PAD; - - const otherVisibleWindows = []; - ['listen', 'ask'].forEach(name => { - const win = windowPool.get(name); - if (win && win.isVisible() && !win.isDestroyed()) { - otherVisibleWindows.push({ - name, - bounds: win.getBounds(), - }); - } - }); - - const settingsNewBounds = { x, y, width: settingsBounds.width, height: settingsBounds.height }; - let hasOverlap = false; - - for (const otherWin of otherVisibleWindows) { - if (this.boundsOverlap(settingsNewBounds, otherWin.bounds)) { - hasOverlap = true; - break; - } - } - - if (hasOverlap) { - x = headerBounds.x + headerBounds.width + PAD; - y = headerBounds.y; - settingsNewBounds.x = x; - settingsNewBounds.y = y; - - if (x + settingsBounds.width > screenWidth - 10) { - x = headerBounds.x - settingsBounds.width - PAD; - settingsNewBounds.x = x; - } - - if (x < 10) { - x = headerBounds.x + headerBounds.width - settingsBounds.width - buttonPadding; - y = headerBounds.y - settingsBounds.height - PAD; - settingsNewBounds.x = x; - settingsNewBounds.y = y; - - if (y < 10) { - x = headerBounds.x + headerBounds.width - settingsBounds.width; - y = headerBounds.y + headerBounds.height + PAD; - } - } - } - - x = Math.max(10, Math.min(screenWidth - settingsBounds.width - 10, x)); - y = Math.max(10, Math.min(screenHeight - settingsBounds.height - 10, y)); - - settings.setBounds({ x, y }); - settings.moveTop(); - - // console.log(`[Layout] Settings positioned at (${x}, ${y}) ${hasOverlap ? '(adjusted for overlap)' : '(default position)'}`); - } - - boundsOverlap(bounds1, bounds2) { - const margin = 10; - return !( - bounds1.x + bounds1.width + margin < bounds2.x || - bounds2.x + bounds2.width + margin < bounds1.x || - bounds1.y + bounds1.height + margin < bounds2.y || - bounds2.y + bounds2.height + margin < bounds1.y - ); - } - - isWindowVisible(windowName) { - const window = windowPool.get(windowName); - return window && !window.isDestroyed() && window.isVisible(); - } - - destroy() {} -} - -class SmoothMovementManager { - constructor() { - this.stepSize = 80; - this.animationDuration = 300; - this.headerPosition = { x: 0, y: 0 }; - this.isAnimating = false; - this.hiddenPosition = null; - this.lastVisiblePosition = null; - this.currentDisplayId = null; - } - - moveToDisplay(displayId) { - const header = windowPool.get('header'); - if (!header || !header.isVisible() || this.isAnimating) return; - - const targetDisplay = getDisplayById(displayId); - if (!targetDisplay) return; - - const currentBounds = header.getBounds(); - const currentDisplay = getCurrentDisplay(header); - - if (currentDisplay.id === targetDisplay.id) { - console.log('[Movement] Already on target display'); - return; - } - - const relativeX = (currentBounds.x - currentDisplay.workArea.x) / currentDisplay.workAreaSize.width; - const relativeY = (currentBounds.y - currentDisplay.workArea.y) / currentDisplay.workAreaSize.height; - - const targetX = targetDisplay.workArea.x + targetDisplay.workAreaSize.width * relativeX; - const targetY = targetDisplay.workArea.y + targetDisplay.workAreaSize.height * relativeY; - - const finalX = Math.max( - targetDisplay.workArea.x, - Math.min(targetDisplay.workArea.x + targetDisplay.workAreaSize.width - currentBounds.width, targetX) - ); - const finalY = Math.max( - targetDisplay.workArea.y, - Math.min(targetDisplay.workArea.y + targetDisplay.workAreaSize.height - currentBounds.height, targetY) - ); - - this.headerPosition = { x: currentBounds.x, y: currentBounds.y }; - this.animateToPosition(header, finalX, finalY); - - this.currentDisplayId = targetDisplay.id; - } - - hideToEdge(edge, callback) { - const header = windowPool.get('header'); - if (!header || !header.isVisible() || this.isAnimating) return; - - console.log(`[Movement] Hiding to ${edge} edge`); - - const currentBounds = header.getBounds(); - this.lastVisiblePosition = { x: currentBounds.x, y: currentBounds.y }; - this.headerPosition = { x: currentBounds.x, y: currentBounds.y }; - - const display = getCurrentDisplay(header); - const { width: screenWidth, height: screenHeight } = display.workAreaSize; - const { x: workAreaX, y: workAreaY } = display.workArea; - const headerBounds = header.getBounds(); - - let targetX = this.headerPosition.x; - let targetY = this.headerPosition.y; - - switch (edge) { - case 'top': - targetY = workAreaY - headerBounds.height - 20; - break; - case 'bottom': - targetY = workAreaY + screenHeight + 20; - break; - case 'left': - targetX = workAreaX - headerBounds.width - 20; - break; - case 'right': - targetX = workAreaX + screenWidth + 20; - break; - } - - this.hiddenPosition = { x: targetX, y: targetY, edge }; - - this.isAnimating = true; - const startX = this.headerPosition.x; - const startY = this.headerPosition.y; - const duration = 400; - const startTime = Date.now(); - - const animate = () => { - if (!header || typeof header.setPosition !== 'function' || header.isDestroyed()) { - this.isAnimating = false; - return; - } - - const elapsed = Date.now() - startTime; - const progress = Math.min(elapsed / duration, 1); - const eased = progress * progress * progress; - - const currentX = startX + (targetX - startX) * eased; - const currentY = startY + (targetY - startY) * eased; - - // Validate computed positions before using - if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { - console.error('[Movement] Invalid animation values for hide:', { - currentX, currentY, progress, eased, startX, startY, targetX, targetY - }); - this.isAnimating = false; - return; - } - - // Safely call setPosition - try { - header.setPosition(Math.round(currentX), Math.round(currentY)); - } catch (err) { - console.error('[Movement] Failed to set position:', err); - this.isAnimating = false; - return; - } - - if (progress < 1) { - setTimeout(animate, 8); - } else { - this.headerPosition = { x: targetX, y: targetY }; - - if (Number.isFinite(targetX) && Number.isFinite(targetY)) { - try { - header.setPosition(Math.round(targetX), Math.round(targetY)); - } catch (err) { - console.error('[Movement] Failed to set final position:', err); - } - } - - this.isAnimating = false; - - if (typeof callback === 'function') { - try { - callback(); - } catch (err) { - console.error('[Movement] Callback error:', err); - } - } - - console.log(`[Movement] Hide to ${edge} completed`); - } - }; - - animate(); - } - - showFromEdge(callback) { - const header = windowPool.get('header'); - if (!header || this.isAnimating || !this.hiddenPosition || !this.lastVisiblePosition) return; - - console.log(`[Movement] Showing from ${this.hiddenPosition.edge} edge`); - - header.setPosition(this.hiddenPosition.x, this.hiddenPosition.y); - this.headerPosition = { x: this.hiddenPosition.x, y: this.hiddenPosition.y }; - - const targetX = this.lastVisiblePosition.x; - const targetY = this.lastVisiblePosition.y; - - this.isAnimating = true; - const startX = this.headerPosition.x; - const startY = this.headerPosition.y; - const duration = 500; - const startTime = Date.now(); - - const animate = () => { - if (!header || header.isDestroyed()) { - this.isAnimating = false; - return; - } - - const elapsed = Date.now() - startTime; - const progress = Math.min(elapsed / duration, 1); - - const c1 = 1.70158; - const c3 = c1 + 1; - const eased = 1 + c3 * Math.pow(progress - 1, 3) + c1 * Math.pow(progress - 1, 2); - - const currentX = startX + (targetX - startX) * eased; - const currentY = startY + (targetY - startY) * eased; - - if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { - console.error('[Movement] Invalid animation values for show:', { currentX, currentY, progress, eased }); - this.isAnimating = false; - return; - } - - header.setPosition(Math.round(currentX), Math.round(currentY)); - - if (progress < 1) { - setTimeout(animate, 8); - } else { - this.headerPosition = { x: targetX, y: targetY }; - this.headerPosition = { x: targetX, y: targetY }; - if (Number.isFinite(targetX) && Number.isFinite(targetY)) { - header.setPosition(Math.round(targetX), Math.round(targetY)); - } - this.isAnimating = false; - - this.hiddenPosition = null; - this.lastVisiblePosition = null; - - if (callback) callback(); - - console.log(`[Movement] Show from edge completed`); - } - }; - - animate(); - } - - moveStep(direction) { - const header = windowPool.get('header'); - if (!header || !header.isVisible() || this.isAnimating) return; - - console.log(`[Movement] Step ${direction}`); - - const currentBounds = header.getBounds(); - this.headerPosition = { x: currentBounds.x, y: currentBounds.y }; - - let targetX = this.headerPosition.x; - let targetY = this.headerPosition.y; - - switch (direction) { - case 'left': - targetX -= this.stepSize; - break; - case 'right': - targetX += this.stepSize; - break; - case 'up': - targetY -= this.stepSize; - break; - case 'down': - targetY += this.stepSize; - break; - default: - return; - } - - const displays = screen.getAllDisplays(); - let validPosition = false; - - for (const display of displays) { - const { x, y, width, height } = display.workArea; - const headerBounds = header.getBounds(); - - if (targetX >= x && targetX + headerBounds.width <= x + width && targetY >= y && targetY + headerBounds.height <= y + height) { - validPosition = true; - break; - } - } - - if (!validPosition) { - const nearestDisplay = screen.getDisplayNearestPoint({ x: targetX, y: targetY }); - const { x, y, width, height } = nearestDisplay.workArea; - const headerBounds = header.getBounds(); - - targetX = Math.max(x, Math.min(x + width - headerBounds.width, targetX)); - targetY = Math.max(y, Math.min(y + height - headerBounds.height, targetY)); - } - - if (targetX === this.headerPosition.x && targetY === this.headerPosition.y) { - console.log(`[Movement] Already at boundary for ${direction}`); - return; - } - - this.animateToPosition(header, targetX, targetY); - } - - animateToPosition(header, targetX, targetY) { - this.isAnimating = true; - - const startX = this.headerPosition.x; - const startY = this.headerPosition.y; - const startTime = Date.now(); - - if (!Number.isFinite(targetX) || !Number.isFinite(targetY) || !Number.isFinite(startX) || !Number.isFinite(startY)) { - console.error('[Movement] Invalid position values:', { startX, startY, targetX, targetY }); - this.isAnimating = false; - return; - } - - const animate = () => { - if (!header || header.isDestroyed()) { - this.isAnimating = false; - return; - } - - const elapsed = Date.now() - startTime; - const progress = Math.min(elapsed / this.animationDuration, 1); - - const eased = 1 - Math.pow(1 - progress, 3); - - const currentX = startX + (targetX - startX) * eased; - const currentY = startY + (targetY - startY) * eased; - - if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { - console.error('[Movement] Invalid animation values:', { currentX, currentY, progress, eased }); - this.isAnimating = false; - return; - } - - header.setPosition(Math.round(currentX), Math.round(currentY)); - - if (progress < 1) { - setTimeout(animate, 8); - } else { - this.headerPosition = { x: targetX, y: targetY }; - if (Number.isFinite(targetX) && Number.isFinite(targetY)) { - header.setPosition(Math.round(targetX), Math.round(targetY)); - } else { - console.warn('[Movement] Final position invalid, skip setPosition:', { targetX, targetY }); - } - this.isAnimating = false; - - updateLayout(); - - console.log(`[Movement] Step completed to (${targetX}, ${targetY})`); - } - }; - - animate(); - } - - moveToEdge(direction) { - const header = windowPool.get('header'); - if (!header || !header.isVisible() || this.isAnimating) return; - - console.log(`[Movement] Move to edge: ${direction}`); - - const display = getCurrentDisplay(header); - const { width, height } = display.workAreaSize; - const { x: workAreaX, y: workAreaY } = display.workArea; - const headerBounds = header.getBounds(); - - const currentBounds = header.getBounds(); - let targetX = currentBounds.x; - let targetY = currentBounds.y; - - switch (direction) { - case 'left': - targetX = workAreaX; - break; - case 'right': - targetX = workAreaX + width - headerBounds.width; - break; - case 'up': - targetY = workAreaY; - break; - case 'down': - targetY = workAreaY + height - headerBounds.height; - break; - } - - this.headerPosition = { x: currentBounds.x, y: currentBounds.y }; - - this.isAnimating = true; - const startX = this.headerPosition.x; - const startY = this.headerPosition.y; - const duration = 400; - const startTime = Date.now(); // 이 줄을 animate 함수 정의 전으로 이동 - - if (!Number.isFinite(targetX) || !Number.isFinite(targetY) || !Number.isFinite(startX) || !Number.isFinite(startY)) { - console.error('[Movement] Invalid edge position values:', { startX, startY, targetX, targetY }); - this.isAnimating = false; - return; - } - - const animate = () => { - if (!header || header.isDestroyed()) { - this.isAnimating = false; - return; - } - - const elapsed = Date.now() - startTime; - const progress = Math.min(elapsed / duration, 1); - - const eased = 1 - Math.pow(1 - progress, 4); - - const currentX = startX + (targetX - startX) * eased; - const currentY = startY + (targetY - startY) * eased; - - if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { - console.error('[Movement] Invalid edge animation values:', { currentX, currentY, progress, eased }); - this.isAnimating = false; - return; - } - - header.setPosition(Math.round(currentX), Math.round(currentY)); - - if (progress < 1) { - setTimeout(animate, 8); - } else { - if (Number.isFinite(targetX) && Number.isFinite(targetY)) { - header.setPosition(Math.round(targetX), Math.round(targetY)); - } - this.headerPosition = { x: targetX, y: targetY }; - this.isAnimating = false; - - updateLayout(); - - console.log(`[Movement] Edge movement completed: ${direction}`); - } - }; - - animate(); - } - - handleKeyPress(direction) {} - - handleKeyRelease(direction) {} - - forceStopMovement() { - this.isAnimating = false; - } - - destroy() { - this.isAnimating = false; - console.log('[Movement] Destroyed'); - } -} - -const layoutManager = new WindowLayoutManager(); -let movementManager = null; - -function toggleAllWindowsVisibility() { +function toggleAllWindowsVisibility(movementManager) { const header = windowPool.get('header'); if (!header) return; @@ -919,21 +272,6 @@ function toggleAllWindowsVisibility() { } } -function ensureDataDirectories() { - const homeDir = os.homedir(); - const pickleGlassDir = path.join(homeDir, '.pickle-glass'); - const dataDir = path.join(pickleGlassDir, 'data'); - const imageDir = path.join(dataDir, 'image'); - const audioDir = path.join(dataDir, 'audio'); - - [pickleGlassDir, dataDir, imageDir, audioDir].forEach(dir => { - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); - } - }); - - return { imageDir, audioDir }; -} function createWindows() { const primaryDisplay = screen.getPrimaryDisplay(); @@ -941,8 +279,8 @@ function createWindows() { const initialX = Math.round((screenWidth - DEFAULT_WINDOW_WIDTH) / 2); const initialY = workAreaY + 21; - movementManager = new SmoothMovementManager(); - + movementManager = new SmoothMovementManager(windowPool, getDisplayById, getCurrentDisplay, updateLayout); + const header = new BrowserWindow({ width: DEFAULT_WINDOW_WIDTH, height: HEADER_HEIGHT, @@ -950,6 +288,7 @@ function createWindows() { y: initialY, frame: false, transparent: true, + vibrancy: false, alwaysOnTop: true, skipTaskbar: true, hiddenInMissionControl: true, @@ -963,23 +302,43 @@ function createWindows() { webSecurity: false, }, }); - - windowPool.set('header', header); - - if (currentHeaderState === 'app') { - createFeatureWindows(header); + header.setWindowButtonVisibility(false); + const headerLoadOptions = {}; + if (!shouldUseLiquidGlass) { + header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions); + } + else { + headerLoadOptions.query = { glass: 'true' }; + header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions); + header.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(header.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); } - - windowPool.set('header', header); + layoutManager = new WindowLayoutManager(windowPool); - if (currentHeaderState === 'app') { + header.webContents.once('dom-ready', () => { + loadAndRegisterShortcuts(movementManager); + }); + + setupIpcHandlers(movementManager); + + if (currentHeaderState === 'main') { createFeatureWindows(header); } header.setContentProtection(isContentProtectionOn); header.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); - header.loadFile(path.join(__dirname, '../app/header.html')); + // header.loadFile(path.join(__dirname, '../app/header.html')); // Open DevTools in development if (!app.isPackaged) { @@ -1005,18 +364,14 @@ function createWindows() { header.on('resize', updateLayout); - header.webContents.once('dom-ready', () => { - loadAndRegisterShortcuts(); - }); + // header.webContents.once('dom-ready', () => { + // loadAndRegisterShortcuts(); + // }); ipcMain.handle('toggle-all-windows-visibility', toggleAllWindowsVisibility); ipcMain.handle('toggle-feature', async (event, featureName) => { - if (!windowPool.get(featureName) && currentHeaderState === 'app') { - createFeatureWindows(windowPool.get('header')); - } - - if (!windowPool.get(featureName) && currentHeaderState === 'app') { + if (!windowPool.get(featureName) && currentHeaderState === 'main') { createFeatureWindows(windowPool.get('header')); } @@ -1208,12 +563,12 @@ function createWindows() { } }); - setupIpcHandlers(); + // setupIpcHandlers(); return windowPool; } -function loadAndRegisterShortcuts() { +function loadAndRegisterShortcuts(movementManager) { const defaultKeybinds = getDefaultKeybinds(); const header = windowPool.get('header'); const sendToRenderer = (channel, ...args) => { @@ -1226,10 +581,9 @@ function loadAndRegisterShortcuts() { }); }; - const openaiSessionRef = { current: null }; if (!header) { - return updateGlobalShortcuts(defaultKeybinds, undefined, sendToRenderer, openaiSessionRef); + return updateGlobalShortcuts(defaultKeybinds, undefined, sendToRenderer, movementManager); } header.webContents @@ -1237,19 +591,13 @@ function loadAndRegisterShortcuts() { .then(saved => (saved ? JSON.parse(saved) : {})) .then(savedKeybinds => { const keybinds = { ...defaultKeybinds, ...savedKeybinds }; - updateGlobalShortcuts(keybinds, header, sendToRenderer, openaiSessionRef); + updateGlobalShortcuts(keybinds, header, sendToRenderer, movementManager); }) - .catch(() => updateGlobalShortcuts(defaultKeybinds, header, sendToRenderer, openaiSessionRef)); + .catch(() => updateGlobalShortcuts(defaultKeybinds, header, sendToRenderer, movementManager)); } -function updateLayout() { - layoutManager.updateLayout(); -} - -function setupIpcHandlers(openaiSessionRef) { - const layoutManager = new WindowLayoutManager(); - // const movementManager = new SmoothMovementManager(); +function setupIpcHandlers(movementManager) { screen.on('display-added', (event, newDisplay) => { console.log('[Display] New display added:', newDisplay.id); }); @@ -1394,9 +742,9 @@ function setupIpcHandlers(openaiSessionRef) { console.log(`[WindowManager] Header state changed to: ${state}`); currentHeaderState = state; - if (state === 'app') { + if (state === 'main') { createFeatureWindows(windowPool.get('header')); - } else { // 'apikey' + } else { // 'apikey' | 'permission' destroyFeatureWindows(); } @@ -1428,7 +776,7 @@ function setupIpcHandlers(openaiSessionRef) { }); }; - updateGlobalShortcuts(keybinds, header, sendToRenderer, { current: null }); + updateGlobalShortcuts(keybinds, header, sendToRenderer, movementManager); }) .catch(console.error); } @@ -1742,7 +1090,6 @@ function setupIpcHandlers(openaiSessionRef) { }); } -let storedProvider = 'openai'; async function setApiKey(apiKey, provider = 'openai') { console.log('[WindowManager] Persisting API key and provider to DB'); @@ -1834,96 +1181,6 @@ function setupApiKeyIPC() { console.log('[WindowManager] API key related IPC handlers registered (SQLite-backed)'); } -function createWindow(sendToRenderer, openaiSessionRef) { - const mainWindow = new BrowserWindow({ - width: DEFAULT_WINDOW_WIDTH, - height: HEADER_HEIGHT, - x: initialX, - y: initialY, - frame: false, - transparent: false, - hasShadow: true, - alwaysOnTop: true, - skipTaskbar: true, - hiddenInMissionControl: true, - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - backgroundThrottling: false, - enableBlinkFeatures: 'GetDisplayMedia', - webSecurity: true, - allowRunningInsecureContent: false, - }, - backgroundColor: '#FF0000', - }); - - const { session, desktopCapturer } = require('electron'); - session.defaultSession.setDisplayMediaRequestHandler( - (request, callback) => { - desktopCapturer.getSources({ types: ['screen'] }).then(sources => { - callback({ video: sources[0], audio: 'loopback' }); - }); - }, - { useSystemPicker: true } - ); - - mainWindow.setResizable(false); - mainWindow.setContentProtection(true); - mainWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); - - const primaryDisplay = screen.getPrimaryDisplay(); - const { width: screenWidth } = primaryDisplay.workAreaSize; - const x = Math.floor((screenWidth - DEFAULT_WINDOW_WIDTH) / 2); - const y = 0; - mainWindow.setPosition(x, y); - - if (process.platform === 'win32') { - mainWindow.setAlwaysOnTop(true, 'screen-saver', 1); - } - - mainWindow.loadFile(path.join(__dirname, '../index.html')); - - mainWindow.webContents.once('dom-ready', () => { - setTimeout(() => { - const defaultKeybinds = getDefaultKeybinds(); - let keybinds = defaultKeybinds; - - mainWindow.webContents - .executeJavaScript( - ` - (() => { - try { - const savedKeybinds = localStorage.getItem('customKeybinds'); - const savedContentProtection = localStorage.getItem('contentProtection'); - - return { - keybinds: savedKeybinds ? JSON.parse(savedKeybinds) : null, - contentProtection: savedContentProtection !== null ? savedContentProtection === 'true' : true - }; - } catch (e) { - return { keybinds: null, contentProtection: true }; - } - })() - ` - ) - .then(savedSettings => { - if (savedSettings.keybinds) { - keybinds = { ...defaultKeybinds, ...savedSettings.keybinds }; - } - mainWindow.setContentProtection(savedSettings.contentProtection); - updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, openaiSessionRef); - }) - .catch(() => { - mainWindow.setContentProtection(true); - updateGlobalShortcuts(defaultKeybinds, mainWindow, sendToRenderer, openaiSessionRef); - }); - }, 150); - }); - - setupWindowIpcHandlers(mainWindow, sendToRenderer, openaiSessionRef); - - return mainWindow; -} function getDefaultKeybinds() { const isMac = process.platform === 'darwin'; @@ -1943,23 +1200,20 @@ function getDefaultKeybinds() { }; } -function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, openaiSessionRef) { +function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementManager) { console.log('Updating global shortcuts with:', keybinds); // Unregister all existing shortcuts globalShortcut.unregisterAll(); - if (movementManager) { - movementManager.destroy(); - } - movementManager = new SmoothMovementManager(); + let toggleVisibilityDebounceTimer = null; const isMac = process.platform === 'darwin'; const modifier = isMac ? 'Cmd' : 'Ctrl'; if (keybinds.toggleVisibility) { try { - globalShortcut.register(keybinds.toggleVisibility, toggleAllWindowsVisibility); + globalShortcut.register(keybinds.toggleVisibility, () => toggleAllWindowsVisibility(movementManager)); console.log(`Registered toggleVisibility: ${keybinds.toggleVisibility}`); } catch (error) { console.error(`Failed to register toggleVisibility (${keybinds.toggleVisibility}):`, error); @@ -1972,9 +1226,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, openaiSessi const key = `${modifier}+Shift+${index + 1}`; try { globalShortcut.register(key, () => { - if (movementManager) { - movementManager.moveToDisplay(display.id); - } + movementManager.moveToDisplay(display.id); }); console.log(`Registered display switch shortcut: ${key} -> Display ${index + 1}`); } catch (error) { @@ -2152,48 +1404,6 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, openaiSessi } } -function setupWindowIpcHandlers(mainWindow, sendToRenderer, openaiSessionRef) { - ipcMain.handle('resize-window', async (event, args) => { - try { - const { isMainViewVisible, view } = args; - let targetHeight = HEADER_HEIGHT; - let targetWidth = DEFAULT_WINDOW_WIDTH; - - if (isMainViewVisible) { - const viewHeights = { - listen: 400, - customize: 600, - help: 550, - history: 550, - setup: 200, - }; - targetHeight = viewHeights[view] || 400; - } - - const [currentWidth, currentHeight] = mainWindow.getSize(); - if (currentWidth !== targetWidth || currentHeight !== targetHeight) { - console.log('Window resize requested but disabled for manual resize prevention'); - } - } catch (error) { - console.error('Error resizing window:', error); - } - }); - - ipcMain.handle('toggle-window-visibility', async event => { - if (mainWindow.isVisible()) { - mainWindow.hide(); - } else { - mainWindow.show(); - } - }); - - ipcMain.handle('quit-application', async () => { - app.quit(); - }); - - // Keep other essential IPC handlers - // ... other handlers like open-external, etc. can be added from the old file if needed -} async function captureScreenshot(options = {}) { if (process.platform === 'darwin') { diff --git a/src/features/ask/AskView.js b/src/features/ask/AskView.js index 78e3ba3..9f125a3 100644 --- a/src/features/ask/AskView.js +++ b/src/features/ask/AskView.js @@ -590,6 +590,43 @@ export class AskView extends LitElement { color: rgba(255, 255, 255, 0.5); font-size: 14px; } + :host-context(body.has-glass) .ask-container, + :host-context(body.has-glass) .response-header, + :host-context(body.has-glass) .response-icon, + :host-context(body.has-glass) .copy-button, + :host-context(body.has-glass) .close-button, + :host-context(body.has-glass) .line-copy-button, + :host-context(body.has-glass) .text-input-container, + :host-context(body.has-glass) .response-container pre, + :host-context(body.has-glass) .response-container p code, + :host-context(body.has-glass) .response-container pre code { + background: transparent !important; + border: none !important; + outline: none !important; + box-shadow: none !important; + filter: none !important; + backdrop-filter: none !important; + } + + /* ask-container 의 블러·그림자 레이어 제거 */ + :host-context(body.has-glass) .ask-container::before { + display: none !important; + } + + /* hover/active 때 다시 생기는 배경도 차단 */ + :host-context(body.has-glass) .copy-button:hover, + :host-context(body.has-glass) .close-button:hover, + :host-context(body.has-glass) .line-copy-button, + :host-context(body.has-glass) .line-copy-button:hover, + :host-context(body.has-glass) .response-line:hover { + background: transparent !important; + } + + /* 스크롤바 트랙·썸 마저 투명화 (원할 경우) */ + :host-context(body.has-glass) .response-container::-webkit-scrollbar-track, + :host-context(body.has-glass) .response-container::-webkit-scrollbar-thumb { + background: transparent !important; + } `; constructor() { @@ -1378,9 +1415,9 @@ export class AskView extends LitElement { const responseHeight = responseEl.scrollHeight; const inputHeight = (inputEl && !inputEl.classList.contains('hidden')) ? inputEl.offsetHeight : 0; - const idealHeight = headerHeight + responseHeight + inputHeight + 20; // padding + const idealHeight = headerHeight + responseHeight + inputHeight; - const targetHeight = Math.min(700, Math.max(200, idealHeight)); + const targetHeight = Math.min(700, idealHeight); const { ipcRenderer } = window.require('electron'); ipcRenderer.invoke('adjust-window-height', targetHeight); diff --git a/src/features/customize/CustomizeView.js b/src/features/customize/CustomizeView.js index b3c6dba..ccba875 100644 --- a/src/features/customize/CustomizeView.js +++ b/src/features/customize/CustomizeView.js @@ -11,7 +11,7 @@ export class CustomizeView extends LitElement { :host { display: block; width: 180px; - min-height: 180px; + height: 100%; color: white; } @@ -234,6 +234,38 @@ export class CustomizeView extends LitElement { font-size: 11px; margin-bottom: 4px; } + :host-context(body.has-glass) .settings-container, + :host-context(body.has-glass) .settings-button, + :host-context(body.has-glass) .cmd-key, + :host-context(body.has-glass) .shortcut-key, + :host-context(body.has-glass) .api-key-section input { + background: transparent !important; + border: none !important; + outline: none !important; + box-shadow: none !important; + filter: none !important; + backdrop-filter: none !important; + } + + /* 블러·그림자·gradient 레이어 제거 */ + :host-context(body.has-glass) .settings-container::before { + display: none !important; + } + + /* hover/active 시 다시 생기는 배경도 차단 */ + :host-context(body.has-glass) .settings-button:hover, + :host-context(body.has-glass) .shortcut-item:hover, + :host-context(body.has-glass) .settings-button.danger:hover { + background: transparent !important; + border-color: transparent !important; + transform: none !important; + } + + /* 스크롤바 트랙·썸 투명화(선택 사항) */ + :host-context(body.has-glass) .settings-container::-webkit-scrollbar-track, + :host-context(body.has-glass) .settings-container::-webkit-scrollbar-thumb { + background: transparent !important; + } `; @@ -390,9 +422,7 @@ export class CustomizeView extends LitElement { updateScrollHeight() { const windowHeight = window.innerHeight; - const headerHeight = 60; - const padding = 40; - const maxHeight = windowHeight - headerHeight - padding; + const maxHeight = windowHeight; this.style.maxHeight = `${maxHeight}px`; } diff --git a/src/features/listen/AssistantView.js b/src/features/listen/AssistantView.js index e1584ca..9c76e34 100644 --- a/src/features/listen/AssistantView.js +++ b/src/features/listen/AssistantView.js @@ -161,7 +161,7 @@ export class AssistantView extends LitElement { /* outline: 0.5px rgba(255, 255, 255, 0.5) solid; */ /* outline-offset: -1px; */ width: 100%; - min-height: 200px; + height: 100%; } .assistant-container::after { @@ -542,6 +542,73 @@ export class AssistantView extends LitElement { font-size: 10px; color: rgba(255, 255, 255, 0.7); } + :host-context(body.has-glass) .assistant-container, + :host-context(body.has-glass) .top-bar, + :host-context(body.has-glass) .toggle-button, + :host-context(body.has-glass) .copy-button, + :host-context(body.has-glass) .transcription-container, + :host-context(body.has-glass) .insights-container, + :host-context(body.has-glass) .stt-message, + :host-context(body.has-glass) .outline-item, + :host-context(body.has-glass) .request-item, + :host-context(body.has-glass) .markdown-content, + :host-context(body.has-glass) .insights-container pre, + :host-context(body.has-glass) .insights-container p code, + :host-context(body.has-glass) .insights-container pre code { + background: transparent !important; + border: none !important; + outline: none !important; + box-shadow: none !important; + filter: none !important; + backdrop-filter: none !important; + } + + /* 가상 레이어·gradient 테두리 제거 */ + :host-context(body.has-glass) .assistant-container::before, + :host-context(body.has-glass) .assistant-container::after { + display: none !important; + } + + /* hover 상태에서 생기는 배경도 차단 */ + :host-context(body.has-glass) .toggle-button:hover, + :host-context(body.has-glass) .copy-button:hover, + :host-context(body.has-glass) .outline-item:hover, + :host-context(body.has-glass) .request-item.clickable:hover, + :host-context(body.has-glass) .markdown-content:hover { + background: transparent !important; + transform: none !important; + } + + /* 스크롤바 트랙·썸도 투명화(선택) */ + :host-context(body.has-glass) .transcription-container::-webkit-scrollbar-track, + :host-context(body.has-glass) .transcription-container::-webkit-scrollbar-thumb, + :host-context(body.has-glass) .insights-container::-webkit-scrollbar-track, + :host-context(body.has-glass) .insights-container::-webkit-scrollbar-thumb { + background: transparent !important; + } + :host-context(body.has-glass) * { + animation: none !important; + transition: none !important; + transform: none !important; + filter: none !important; + backdrop-filter: none !important; + box-shadow: none !important; + } + + /* 추가: 둥근 모서리와 스크롤바도 평면화하려면 */ + :host-context(body.has-glass) .assistant-container, + :host-context(body.has-glass) .stt-message, + :host-context(body.has-glass) .toggle-button, + :host-context(body.has-glass) .copy-button { + border-radius: 0 !important; + } + + :host-context(body.has-glass) ::-webkit-scrollbar, + :host-context(body.has-glass) ::-webkit-scrollbar-track, + :host-context(body.has-glass) ::-webkit-scrollbar-thumb { + background: transparent !important; + width: 0 !important; /* 스크롤바 자체 숨기기 */ + } `; static properties = { @@ -777,9 +844,9 @@ export class AssistantView extends LitElement { const contentHeight = activeContent.scrollHeight; - const idealHeight = topBarHeight + contentHeight + 20; + const idealHeight = topBarHeight + contentHeight; - const targetHeight = Math.min(700, Math.max(200, idealHeight)); + const targetHeight = Math.min(700, idealHeight); console.log( `[Height Adjusted] Mode: ${this.viewMode}, TopBar: ${topBarHeight}px, Content: ${contentHeight}px, Ideal: ${idealHeight}px, Target: ${targetHeight}px` From 045095334e884102fe55176b1612762d8cbae836 Mon Sep 17 00:00:00 2001 From: Emmett Kim <151644571+ekim425@users.noreply.github.com> Date: Sun, 6 Jul 2025 20:28:58 +0900 Subject: [PATCH 09/52] Update README.md --- README.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a05a8bc..e56fe01 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ > This project is a fork of [CheatingDaddy](https://github.com/sohzm/cheating-daddy) with modifications and enhancements. Thanks to [Soham](https://x.com/soham_btw) and all the open-source contributors who made this possible! +> Currently, we're working on a full code refactor and modularization. Once that's completed, we'll jump into addressing the major issues. You can find WIP issues & changelog below this document. + 🤖 **Fast, light & open-source**—Glass lives on your desktop, sees what you see, listens in real time, understands your context, and turns every moment into structured knowledge. 💬 **Proactive in meetings**—it surfaces action items, summaries, and answers the instant you need them. @@ -62,10 +64,15 @@ npm run setup booking-screen -### Use your own OpenAI API key, or sign up to use ours (free) +### Use your own API key, or sign up to use ours (free) booking-screen +**Currently Supporting:** +- OpenAI API +- Gemini API +- Local LLM (Working on + You can visit [here](https://platform.openai.com/api-keys) to get your OpenAI API Key. ### Liquid Glass Design (coming soon) @@ -91,18 +98,23 @@ You can visit [here](https://platform.openai.com/api-keys) to get your OpenAI AP ## Contributing We love contributions! Feel free to open issues for bugs or feature requests. +> Currently, we're working on a full code refactor and modularization. Once that's completed, we'll jump into addressing the major issues. ## 🛠 Current Issues & Improvements | Status | Issue | Description | |--------|--------------------------------|---------------------------------------------------| -| 🚧 WIP | AEC Improvement | Transcription is not working occasionally | | 🚧 WIP | Code Refactoring | Refactoring the entire codebase for better maintainability. | +| 🚧 WIP | Windows Build | Make Glass buildable & runnable in Windows | +| 🚧 WIP | Local LLM Support | Supporting Local LLM to power AI answers | +| 🚧 WIP | AEC Improvement | Transcription is not working occasionally | | 🚧 WIP | Firebase Data Storage Issue | Session & ask should be saved in firebase for signup users | | 🚧 WIP | Login Issue | Currently breaking when switching between local and sign-in mode | | 🚧 WIP | Liquid Glass | Liquid Glass UI for MacOS 26 | -| 🚧 WIP | Permission Issue | Mic & system audio & display capture permission sometimes not working| +## Changelog + +- Jul 5: Now support Gemini, Intel Mac supported ## About Pickle @@ -110,4 +122,4 @@ We love contributions! Feel free to open issues for bugs or feature requests. **Our mission is to build a living digital clone for everyone.** Glass is part of Step 1—a trusted pipeline that transforms your daily data into a scalable clone. Visit [pickle.com](https://pickle.com) to learn more. ## Star History -[![Star History Chart](https://api.star-history.com/svg?repos=pickle-com/glass&type=Date)](https://www.star-history.com/#pickle-com/glass&Date) \ No newline at end of file +[![Star History Chart](https://api.star-history.com/svg?repos=pickle-com/glass&type=Date)](https://www.star-history.com/#pickle-com/glass&Date) From d0c99c297251c6974de60bba695d4a19e00bfeba Mon Sep 17 00:00:00 2001 From: Emmett Kim <151644571+ekim425@users.noreply.github.com> Date: Sun, 6 Jul 2025 20:31:10 +0900 Subject: [PATCH 10/52] Update README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e56fe01..071e8d8 100644 --- a/README.md +++ b/README.md @@ -69,11 +69,9 @@ npm run setup booking-screen **Currently Supporting:** -- OpenAI API -- Gemini API -- Local LLM (Working on - -You can visit [here](https://platform.openai.com/api-keys) to get your OpenAI API Key. +- OpenAI API: Get OpenAI API Key [here](https://platform.openai.com/api-keys) +- Gemini API: Get Gemini API Key [here](https://aistudio.google.com/apikey) +- Local LLM (WIP) ### Liquid Glass Design (coming soon) From db05524ff5a20cfd08b791bcd3508093524da8c1 Mon Sep 17 00:00:00 2001 From: entry-gi Date: Mon, 7 Jul 2025 00:59:22 +0900 Subject: [PATCH 11/52] readme update --- README copy.md | 675 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 11 + 2 files changed, 686 insertions(+) create mode 100644 README copy.md diff --git a/README copy.md b/README copy.md new file mode 100644 index 0000000..456a005 --- /dev/null +++ b/README copy.md @@ -0,0 +1,675 @@ + +

+ + Logo + + +

Cal.com (formerly Calendso)

+ +

+ The open-source Calendly successor. +
+ Learn more » +
+
+ Discussions + · + Website + · + Issues + · + Roadmap +

+

+ +

+ Product Hunt + Checkly QA + Uptime + Github Stars + Hacker News + License + Commits-per-month + Pricing + Jitsu Tracked + Checkly Availability + + + + + + +

+ + + +## About the Project + +booking-screen + +# Scheduling infrastructure for absolutely everyone + +The open source Calendly successor. You are in charge +of your own data, workflow, and appearance. + +Calendly and other scheduling tools are awesome. It made our lives massively easier. We're using it for business meetings, seminars, yoga classes, and even calls with our families. However, most tools are very limited in terms of control and customization. + +That's where Cal.com comes in. Self-hosted or hosted by us. White-label by design. API-driven and ready to be deployed on your own domain. Full control of your events and data. + +## Recognition + +#### [Hacker News](https://news.ycombinator.com/from?site=cal.com) + + + Featured on Hacker News + + + + Featured on Hacker News + + +#### [Product Hunt](https://producthunt.com/products/cal-com?utm_source=badge-top-post-badge&utm_medium=badge) + +Cal.com - The open source Calendly alternative | Product Hunt Cal.com - The open source Calendly alternative | Product Hunt Cal.com - The open source Calendly alternative | Product Hunt + +### Built With + +- [Next.js](https://nextjs.org/?ref=cal.com) +- [tRPC](https://trpc.io/?ref=cal.com) +- [React.js](https://reactjs.org/?ref=cal.com) +- [Tailwind CSS](https://tailwindcss.com/?ref=cal.com) +- [Prisma.io](https://prisma.io/?ref=cal.com) +- [Daily.co](https://go.cal.com/daily) + +## Contact us + +Meet our sales team for any commercial inquiries. + +Book us with Cal.com + +## Stay Up-to-Date + +Cal.com officially launched as v.1.0 on the 15th of September 2021 and we've come a long way so far. Watch **releases** of this repository to be notified of future updates: + +![cal-star-github](https://user-images.githubusercontent.com/8019099/154853944-a9e3c999-3da3-4048-b149-b4f73893c6fb.gif) + + + +## Getting Started + +To get a local copy up and running, please follow these simple steps. + +### Prerequisites + +Here is what you need to be able to run Cal.com. + +- Node.js (Version: >=18.x) +- PostgreSQL (Version: >=13.x) +- Yarn _(recommended)_ + +> If you want to enable any of the available integrations, you may want to obtain additional credentials for each one. More details on this can be found below under the [integrations section](#integrations). + +## Development + +### Setup + +1. Clone the repo into a public GitHub repository (or fork https://github.com/calcom/cal.com/fork). If you plan to distribute the code, keep the source code public to comply with [AGPLv3](https://github.com/calcom/cal.com/blob/main/LICENSE). To clone in a private repository, [acquire a commercial license](https://cal.com/sales) + + ```sh + git clone https://github.com/calcom/cal.com.git + ``` + + > If you are on Windows, run the following command on `gitbash` with admin privileges:
> `git clone -c core.symlinks=true https://github.com/calcom/cal.com.git`
+ > See [docs](https://cal.com/docs/how-to-guides/how-to-troubleshoot-symbolic-link-issues-on-windows#enable-symbolic-links) for more details. + +2. Go to the project folder + + ```sh + cd cal.com + ``` + +3. Install packages with yarn + + ```sh + yarn + ``` + +4. Set up your `.env` file + + - Duplicate `.env.example` to `.env` + - Use `openssl rand -base64 32` to generate a key and add it under `NEXTAUTH_SECRET` in the `.env` file. + - Use `openssl rand -base64 32` to generate a key and add it under `CALENDSO_ENCRYPTION_KEY` in the `.env` file. + +5. Setup Node + If your Node version does not meet the project's requirements as instructed by the docs, "nvm" (Node Version Manager) allows using Node at the version required by the project: + + ```sh + nvm use + ``` + + You first might need to install the specific version and then use it: + + ```sh + nvm install && nvm use + ``` + + You can install nvm from [here](https://github.com/nvm-sh/nvm). + +#### Quick start with `yarn dx` + +> - **Requires Docker and Docker Compose to be installed** +> - Will start a local Postgres instance with a few test users - the credentials will be logged in the console + +```sh +yarn dx +``` + +#### Development tip +1. Add `export NODE_OPTIONS=“--max-old-space-size=16384”` to your shell script to increase the memory limit for the node process. Alternatively, you can run this in your terminal before running the app. Replace 16384 with the amount of RAM you want to allocate to the node process. + +2. Add `NEXT_PUBLIC_LOGGER_LEVEL={level}` to your .env file to control the logging verbosity for all tRPC queries and mutations.\ + Where {level} can be one of the following: + + `0` for silly \ + `1` for trace \ + `2` for debug \ + `3` for info \ + `4` for warn \ + `5` for error \ + `6` for fatal + + When you set `NEXT_PUBLIC_LOGGER_LEVEL={level}` in your .env file, it enables logging at that level and higher. Here's how it works: + + The logger will include all logs that are at the specified level or higher. For example: \ + + - If you set `NEXT_PUBLIC_LOGGER_LEVEL=2`, it will log from level 2 (debug) upwards, meaning levels 2 (debug), 3 (info), 4 (warn), 5 (error), and (fatal) will be logged. \ + - If you set `NEXT_PUBLIC_LOGGER_LEVEL=3`, it will log from level 3 (info) upwards, meaning levels 3 (info), 4 (warn), 5 (error), and 6 (fatal) will be logged, but level 2 (debug) and level 1 (trace) will be ignored. \ + +```sh +echo 'NEXT_PUBLIC_LOGGER_LEVEL=3' >> .env +``` + +for Logger level to be set at info, for example. + +#### Gitpod Setup + +1. Click the button below to open this project in Gitpod. + +2. This will open a fully configured workspace in your browser with all the necessary dependencies already installed. + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/calcom/cal.com) + +#### Manual setup + +1. Configure environment variables in the `.env` file. Replace ``, ``, ``, and `` with their applicable values + + ``` + DATABASE_URL='postgresql://:@:' + ``` + +
+ If you don't know how to configure the DATABASE_URL, then follow the steps here to create a quick local DB + + 1. [Download](https://www.postgresql.org/download/) and install postgres in your local (if you don't have it already). + + 2. Create your own local db by executing `createDB ` + + 3. Now open your psql shell with the DB you created: `psql -h localhost -U postgres -d ` + + 4. Inside the psql shell execute `\conninfo`. And you will get the following info. + ![image](https://user-images.githubusercontent.com/39329182/236612291-51d87f69-6dc1-4a23-bf4d-1ca1754e0a35.png) + + 5. Now extract all the info and add it to your DATABASE_URL. The url would look something like this + `postgresql://postgres:postgres@localhost:5432/Your-DB-Name`. The port is configurable and does not have to be 5432. + +
+ + If you don't want to create a local DB. Then you can also consider using services like railway.app or render. + + - [Setup postgres DB with railway.app](https://docs.railway.app/guides/postgresql) + - [Setup postgres DB with render](https://render.com/docs/databases) + +1. Copy and paste your `DATABASE_URL` from `.env` to `.env.appStore`. + +1. Set up the database using the Prisma schema (found in `packages/prisma/schema.prisma`) + + In a development environment, run: + + ```sh + yarn workspace @calcom/prisma db-migrate + ``` + + In a production environment, run: + + ```sh + yarn workspace @calcom/prisma db-deploy + ``` + +1. Run [mailhog](https://github.com/mailhog/MailHog) to view emails sent during development + + > **_NOTE:_** Required when `E2E_TEST_MAILHOG_ENABLED` is "1" + + ```sh + docker pull mailhog/mailhog + docker run -d -p 8025:8025 -p 1025:1025 mailhog/mailhog + ``` + +1. Run (in development mode) + + ```sh + yarn dev + ``` + +#### Setting up your first user + +##### Approach 1 + +1. Open [Prisma Studio](https://prisma.io/studio) to look at or modify the database content: + + ```sh + yarn db-studio + ``` + +1. Click on the `User` model to add a new user record. +1. Fill out the fields `email`, `username`, `password`, and set `metadata` to empty `{}` (remembering to encrypt your password with [BCrypt](https://bcrypt-generator.com/)) and click `Save 1 Record` to create your first user. + > New users are set on a `TRIAL` plan by default. You might want to adjust this behavior to your needs in the `packages/prisma/schema.prisma` file. +1. Open a browser to [http://localhost:3000](http://localhost:3000) and login with your just created, first user. + +##### Approach 2 + +Seed the local db by running + +```sh +cd packages/prisma +yarn db-seed +``` + +The above command will populate the local db with dummy users. + +### E2E-Testing + +Be sure to set the environment variable `NEXTAUTH_URL` to the correct value. If you are running locally, as the documentation within `.env.example` mentions, the value should be `http://localhost:3000`. + +```sh +# In a terminal just run: +yarn test-e2e + +# To open the last HTML report run: +yarn playwright show-report test-results/reports/playwright-html-report +``` + +#### Resolving issues + +##### E2E test browsers not installed + +Run `npx playwright install` to download test browsers and resolve the error below when running `yarn test-e2e`: + +``` +Executable doesn't exist at /Users/alice/Library/Caches/ms-playwright/chromium-1048/chrome-mac/Chromium.app/Contents/MacOS/Chromium +``` + +### Upgrading from earlier versions + +1. Pull the current version: + + ```sh + git pull + ``` + +1. Check if dependencies got added/updated/removed + + ```sh + yarn + ``` + +1. Apply database migrations by running one of the following commands: + + In a development environment, run: + + ```sh + yarn workspace @calcom/prisma db-migrate + ``` + + (This can clear your development database in some cases) + + In a production environment, run: + + ```sh + yarn workspace @calcom/prisma db-deploy + ``` + +1. Check for `.env` variables changes + + ```sh + yarn predev + ``` + +1. Start the server. In a development environment, just do: + + ```sh + yarn dev + ``` + + For a production build, run for example: + + ```sh + yarn build + yarn start + ``` + +1. Enjoy the new version. + + +## Deployment + +### Docker + +The Docker configuration for Cal.com is an effort powered by people within the community. + +If you want to contribute to the Docker repository, [reply here](https://github.com/calcom/docker/discussions/32). + +The Docker configuration can be found [in our docker repository](https://github.com/calcom/docker). + +Issues with Docker? Find your answer or open a new discussion [here](https://github.com/calcom/docker/discussions) to ask the community. + +Cal.com, Inc. does not provide official support for Docker, but we will accept fixes and documentation. Use at your own risk. + +### Railway + +[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/cal) + +You can deploy Cal.com on [Railway](https://railway.app) using the button above. The team at Railway also have a [detailed blog post](https://blog.railway.app/p/calendso) on deploying Cal.com on their platform. + +### Vercel + +Currently Vercel Pro Plan is required to be able to Deploy this application with Vercel, due to limitations on the number of serverless functions on the free plan. + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fcalcom%2Fcal.com&env=DATABASE_URL,NEXT_PUBLIC_WEBAPP_URL,NEXTAUTH_URL,NEXTAUTH_SECRET,CRON_API_KEY,CALENDSO_ENCRYPTION_KEY&envDescription=See%20all%20available%20env%20vars&envLink=https%3A%2F%2Fgithub.com%2Fcalcom%2Fcal.com%2Fblob%2Fmain%2F.env.example&project-name=cal&repo-name=cal.com&build-command=cd%20../..%20%26%26%20yarn%20build&root-directory=apps%2Fweb%2F) + +### Render + +[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/calcom/docker) + +### Elestio + +[![Deploy on Elestio](https://elest.io/images/logos/deploy-to-elestio-btn.png)](https://elest.io/open-source/cal.com) + + + +## Roadmap + +Cal.com Roadmap + +See the [roadmap project](https://cal.com/roadmap) for a list of proposed features (and known issues). You can change the view to see planned tagged releases. + + + +## License + +Cal.com, Inc. is a commercial open source company, which means some parts of this open source repository require a commercial license. The concept is called "Open Core" where the core technology (99%) is fully open source, licensed under [AGPLv3](https://opensource.org/license/agpl-v3) and the last 1% is covered under a commercial license (["/ee" Enterprise Edition](https://github.com/calcom/cal.com/tree/main/packages/features/ee)) which we believe is entirely relevant for larger organisations that require enterprise features. Enterprise features are built by the core engineering team of Cal.com, Inc. which is hired in full-time. Find their compensation on https://cal.com/open. + +> [!NOTE] +> Our philosophy is simple, all "Singleplayer APIs" are open-source under AGPLv3. All commercial "Multiplayer APIs" are under a commercial license. + +| | AGPLv3 | EE | +| --------------------------------- | ------ | --- | +| Self-host for commercial purposes | ✅ | ✅ | +| Clone privately | ✅ | ✅ | +| Fork publicly | ✅ | ✅ | +| Requires CLA | ✅ | ✅ | +|  Official Support | ❌  | ✅ | +| Derivative work privately | ❌ | ✅ | +|  SSO | ❌ | ✅ | +| Admin Panel | ❌ | ✅ | +| Impersonation | ❌ | ✅ | +| Managed Event Types | ❌ | ✅ | +| Organizations | ❌ | ✅ | +| Payments | ❌ | ✅ | +| Platform | ❌ | ✅ | +| Teams | ❌ | ✅ | +| Users | ❌ | ✅ | +| Video | ❌ | ✅ | +| Workflows | ❌ | ✅ | + +> [!TIP] +> We work closely with the community and always invite feedback about what should be open and what is fine to be commercial. This list is not set and stone and we have moved things from commercial to open in the past. Please open a [discussion](https://github.com/calcom/cal.com/discussions) if you feel like something is wrong. + +## Repo Activity + + + + + +## Contributing + +Please see our [contributing guide](/CONTRIBUTING.md). + +### Good First Issues + +We have a list of [help wanted](https://github.com/calcom/cal.com/issues?q=is:issue+is:open+label:%22%F0%9F%99%8B%F0%9F%8F%BB%E2%80%8D%E2%99%82%EF%B8%8Fhelp+wanted%22) that contain small features and bugs which have a relatively limited scope. This is a great place to get started, gain experience, and get familiar with our contribution process. + + + +### Bounties + + + + + Bounties of cal + + + + + +### Contributors + + + + + + + +### Translations + +Don't code but still want to contribute? Join our [Discussions](https://github.com/calcom/cal.com/discussions) and join the [#Translate channel](https://github.com/calcom/cal.com/discussions/categories/translations) and let us know what language you want to translate. + +![ar translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ar&style=flat&logo=crowdin&query=%24.progress.0.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![bg translation](https://img.shields.io/badge/dynamic/json?color=blue&label=bg&style=flat&logo=crowdin&query=%24.progress.1.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![cs translation](https://img.shields.io/badge/dynamic/json?color=blue&label=cs&style=flat&logo=crowdin&query=%24.progress.2.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![de translation](https://img.shields.io/badge/dynamic/json?color=blue&label=de&style=flat&logo=crowdin&query=%24.progress.3.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![el translation](https://img.shields.io/badge/dynamic/json?color=blue&label=el&style=flat&logo=crowdin&query=%24.progress.4.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![en translation](https://img.shields.io/badge/dynamic/json?color=blue&label=en&style=flat&logo=crowdin&query=%24.progress.5.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![es translation](https://img.shields.io/badge/dynamic/json?color=blue&label=es&style=flat&logo=crowdin&query=%24.progress.6.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![es-419 translation](https://img.shields.io/badge/dynamic/json?color=blue&label=es-419&style=flat&logo=crowdin&query=%24.progress.7.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![fr translation](https://img.shields.io/badge/dynamic/json?color=blue&label=fr&style=flat&logo=crowdin&query=%24.progress.8.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![he translation](https://img.shields.io/badge/dynamic/json?color=blue&label=he&style=flat&logo=crowdin&query=%24.progress.9.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![hu translation](https://img.shields.io/badge/dynamic/json?color=blue&label=hu&style=flat&logo=crowdin&query=%24.progress.10.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![it translation](https://img.shields.io/badge/dynamic/json?color=blue&label=it&style=flat&logo=crowdin&query=%24.progress.11.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![ja translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ja&style=flat&logo=crowdin&query=%24.progress.12.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![ko translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ko&style=flat&logo=crowdin&query=%24.progress.13.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![nl translation](https://img.shields.io/badge/dynamic/json?color=blue&label=nl&style=flat&logo=crowdin&query=%24.progress.14.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![no translation](https://img.shields.io/badge/dynamic/json?color=blue&label=no&style=flat&logo=crowdin&query=%24.progress.15.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![pl translation](https://img.shields.io/badge/dynamic/json?color=blue&label=pl&style=flat&logo=crowdin&query=%24.progress.16.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![pt translation](https://img.shields.io/badge/dynamic/json?color=blue&label=pt&style=flat&logo=crowdin&query=%24.progress.17.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![pt-BR translation](https://img.shields.io/badge/dynamic/json?color=blue&label=pt-BR&style=flat&logo=crowdin&query=%24.progress.18.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![ro translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ro&style=flat&logo=crowdin&query=%24.progress.19.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![ru translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ru&style=flat&logo=crowdin&query=%24.progress.20.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![sr translation](https://img.shields.io/badge/dynamic/json?color=blue&label=sr&style=flat&logo=crowdin&query=%24.progress.21.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![sv translation](https://img.shields.io/badge/dynamic/json?color=blue&label=sv&style=flat&logo=crowdin&query=%24.progress.22.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![tr translation](https://img.shields.io/badge/dynamic/json?color=blue&label=tr&style=flat&logo=crowdin&query=%24.progress.23.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![uk translation](https://img.shields.io/badge/dynamic/json?color=blue&label=uk&style=flat&logo=crowdin&query=%24.progress.24.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![vi translation](https://img.shields.io/badge/dynamic/json?color=blue&label=vi&style=flat&logo=crowdin&query=%24.progress.25.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![zh-CN translation](https://img.shields.io/badge/dynamic/json?color=blue&label=zh-CN&style=flat&logo=crowdin&query=%24.progress.26.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![zh-TW translation](https://img.shields.io/badge/dynamic/json?color=blue&label=zh-TW&style=flat&logo=crowdin&query=%24.progress.27.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) + +## Enabling Content Security Policy + +- Set CSP_POLICY="non-strict" env variable, which enables [Strict CSP](https://web.dev/strict-csp/) except for unsafe-inline in style-src . If you have some custom changes in your instance, you might have to make some code change to make your instance CSP compatible. Right now it enables strict CSP only on login page and on other SSR pages it is enabled in Report only mode to detect possible issues. On, SSG pages it is still not supported. + +## Single Org Mode +If you want to have booker.yourcompany.com to be the domain used for both dashboard(e.g. https://booker.yourcompany.com/event-types) and booking pages(e.g. https://booker.yourcompany.com/john.joe/15min). +- Set the `NEXT_PUBLIC_SINGLE_ORG_SLUG` environment variable to the slug of the organization you want to use. `NEXT_PUBLIC_SINGLE_ORG_SLUG=booker` +- Set the `NEXT_PUBLIC_WEBAPP_URL` environment variable to the URL of the Cal.com self-hosted instance e.g. `NEXT_PUBLIC_WEBAPP_URL=https://booker.yourcompany.com`. +- Set the `NEXT_PUBLIC_WEBSITE_URL` environment variable to the URL of the Cal.com self-hosted instance e.g. `NEXT_PUBLIC_WEBSITE_URL=https://booker.yourcompany.com`. +- Set the `NEXTAUTH_URL` environment variable to the URL of the Cal.com self-hosted instance e.g. `NEXTAUTH_URL=https://booker.yourcompany.com`. + +Note: It causes root to serve the dashboard and not the organization profile page which shows all bookable users in the organization. + +## Integrations + +### Obtaining the Google API Credentials + +1. Open [Google API Console](https://console.cloud.google.com/apis/dashboard). If you don't have a project in your Google Cloud subscription, you'll need to create one before proceeding further. Under Dashboard pane, select Enable APIS and Services. +2. In the search box, type calendar and select the Google Calendar API search result. +3. Enable the selected API. +4. Next, go to the [OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent) from the side pane. Select the app type (Internal or External) and enter the basic app details on the first page. +5. In the second page on Scopes, select Add or Remove Scopes. Search for Calendar.event and select the scope with scope value `.../auth/calendar.events`, `.../auth/calendar.readonly` and select Update. +6. In the third page (Test Users), add the Google account(s) you'll be using. Make sure the details are correct on the last page of the wizard and your consent screen will be configured. +7. Now select [Credentials](https://console.cloud.google.com/apis/credentials) from the side pane and then select Create Credentials. Select the OAuth Client ID option. +8. Select Web Application as the Application Type. +9. Under Authorized redirect URI's, select Add URI and then add the URI `/api/integrations/googlecalendar/callback` and `/api/auth/callback/google` replacing Cal.com URL with the URI at which your application runs. +10. The key will be created and you will be redirected back to the Credentials page. Select the newly generated client ID under OAuth 2.0 Client IDs. +11. Select Download JSON. Copy the contents of this file and paste the entire JSON string in the `.env` file as the value for `GOOGLE_API_CREDENTIALS` key. + +#### _Adding google calendar to Cal.com App Store_ + +After adding Google credentials, you can now Google Calendar App to the app store. +You can repopulate the App store by running + +``` +cd packages/prisma +yarn seed-app-store +``` + +You will need to complete a few more steps to activate Google Calendar App. +Make sure to complete section "Obtaining the Google API Credentials". After that do the +following + +1. Add extra redirect URL `/api/auth/callback/google` +1. Under 'OAuth consent screen', click "PUBLISH APP" + +### Obtaining Microsoft Graph Client ID and Secret + +1. Open [Azure App Registration](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps) and select New registration +2. Name your application +3. Set **Who can use this application or access this API?** to **Accounts in any organizational directory (Any Azure AD directory - Multitenant)** +4. Set the **Web** redirect URI to `/api/integrations/office365calendar/callback` replacing Cal.com URL with the URI at which your application runs. +5. Use **Application (client) ID** as the **MS_GRAPH_CLIENT_ID** attribute value in .env +6. Click **Certificates & secrets** create a new client secret and use the value as the **MS_GRAPH_CLIENT_SECRET** attribute + +### Obtaining Zoom Client ID and Secret + +1. Open [Zoom Marketplace](https://marketplace.zoom.us/) and sign in with your Zoom account. +2. On the upper right, click "Develop" => "Build App". +3. Select "General App" , click "Create". +4. Name your App. +5. Choose "User-managed app" for "Select how the app is managed". +6. De-select the option to publish the app on the Zoom App Marketplace, if asked. +7. Now copy the Client ID and Client Secret to your `.env` file into the `ZOOM_CLIENT_ID` and `ZOOM_CLIENT_SECRET` fields. +8. Set the "OAuth Redirect URL" under "OAuth Information" as `/api/integrations/zoomvideo/callback` replacing Cal.com URL with the URI at which your application runs. +9. Also add the redirect URL given above as an allow list URL and enable "Subdomain check". Make sure, it says "saved" below the form. +10. You don't need to provide basic information about your app. Instead click on "Scopes" and then on "+ Add Scopes". On the left, + 1. click the category "Meeting" and check the scope `meeting:write:meeting`. + 2. click the category "User" and check the scope `user:read:settings`. +11. Click "Done". +12. You're good to go. Now you can easily add your Zoom integration in the Cal.com settings. + +### Obtaining Daily API Credentials + +1. Visit our [Daily.co Partnership Form](https://go.cal.com/daily) and enter your information +2. From within your dashboard, go to the [developers](https://dashboard.daily.co/developers) tab. +3. Copy your API key. +4. Now paste the API key to your `.env` file into the `DAILY_API_KEY` field in your `.env` file. +5. If you have the [Daily Scale Plan](https://daily.co/pricing) set the `DAILY_SCALE_PLAN` variable to `true` in order to use features like video recording. + +### Obtaining Basecamp Client ID and Secret + +1. Visit the [37 Signals Integrations Dashboard](launchpad.37signals.com/integrations) and sign in. +2. Register a new application by clicking the Register one now link. +3. Fill in your company details. +4. Select Basecamp 4 as the product to integrate with. +5. Set the Redirect URL for OAuth `/api/integrations/basecamp3/callback` replacing Cal.com URL with the URI at which your application runs. +6. Click on done and copy the Client ID and secret into the `BASECAMP3_CLIENT_ID` and `BASECAMP3_CLIENT_SECRET` fields. +7. Set the `BASECAMP3_CLIENT_SECRET` env variable to `{your_domain} ({support_email})`. + For example, `Cal.com (support@cal.com)`. + +### Obtaining HubSpot Client ID and Secret + +1. Open [HubSpot Developer](https://developer.hubspot.com/) and sign into your account, or create a new one. +2. From within the home of the Developer account page, go to "Manage apps". +3. Click "Create app" button top right. +4. Fill in any information you want in the "App info" tab +5. Go to tab "Auth" +6. Now copy the Client ID and Client Secret to your `.env` file into the `HUBSPOT_CLIENT_ID` and `HUBSPOT_CLIENT_SECRET` fields. +7. Set the Redirect URL for OAuth `/api/integrations/hubspot/callback` replacing Cal.com URL with the URI at which your application runs. +8. In the "Scopes" section at the bottom of the page, make sure you select "Read" and "Write" for scope called `crm.objects.contacts` +9. Click the "Save" button at the bottom footer. +10. You're good to go. Now you can see any booking in Cal.com created as a meeting in HubSpot for your contacts. + +### Obtaining Webex Client ID and Secret + +[See Webex Readme](./packages/app-store/webex/) + +### Obtaining ZohoCRM Client ID and Secret + +1. Open [Zoho API Console](https://api-console.zoho.com/) and sign into your account, or create a new one. +2. From within the API console page, go to "Applications". +3. Click "ADD CLIENT" button top right and select "Server-based Applications". +4. Fill in any information you want in the "Client Details" tab +5. Go to tab "Client Secret" tab. +6. Now copy the Client ID and Client Secret to your `.env` file into the `ZOHOCRM_CLIENT_ID` and `ZOHOCRM_CLIENT_SECRET` fields. +7. Set the Redirect URL for OAuth `/api/integrations/zohocrm/callback` replacing Cal.com URL with the URI at which your application runs. +8. In the "Settings" section check the "Multi-DC" option if you wish to use the same OAuth credentials for all data centers. +9. Click the "Save"/ "UPDATE" button at the bottom footer. +10. You're good to go. Now you can easily add your ZohoCRM integration in the Cal.com settings. + +### Obtaining Zoho Calendar Client ID and Secret + +[Follow these steps](./packages/app-store/zohocalendar/) + +### Obtaining Zoho Bigin Client ID and Secret + +[Follow these steps](./packages/app-store/zoho-bigin/) + +### Obtaining Pipedrive Client ID and Secret + +[Follow these steps](./packages/app-store/pipedrive-crm/) + +## Workflows + +### Setting up SendGrid for Email reminders + +1. Create a SendGrid account (https://signup.sendgrid.com/) +2. Go to Settings -> API keys and create an API key +3. Copy API key to your `.env` file into the `SENDGRID_API_KEY` field +4. Go to Settings -> Sender Authentication and verify a single sender +5. Copy the verified E-Mail to your `.env` file into the `SENDGRID_EMAIL` field +6. Add your custom sender name to the `.env` file into the `NEXT_PUBLIC_SENDGRID_SENDER_NAME` field (fallback is Cal.com) + +### Setting up Twilio for SMS reminders + +1. Create a Twilio account (https://twilio.com/try-twilio) +2. Click ‘Get a Twilio phone number’ +3. Copy Account SID to your `.env` file into the `TWILIO_SID` field +4. Copy Auth Token to your `.env` file into the `TWILIO_TOKEN` field +5. Copy your Twilio phone number to your `.env` file into the `TWILIO_PHONE_NUMBER` field +6. Add your own sender ID to the `.env` file into the `NEXT_PUBLIC_SENDER_ID` field (fallback is Cal.com) +7. Create a messaging service (Develop -> Messaging -> Services) +8. Choose any name for the messaging service +9. Click 'Add Senders' +10. Choose phone number as sender type +11. Add the listed phone number +12. Leave all other fields as they are +13. Complete setup and click ‘View my new Messaging Service’ +14. Copy Messaging Service SID to your `.env` file into the `TWILIO_MESSAGING_SID` field +15. Create a verify service +16. Copy Verify Service SID to your `.env` file into the `TWILIO_VERIFY_SID` field + +## Changesets + +We use changesets to generate changelogs and publish public packages (packages with `private: true` are ignored). + +An example of good readme is [atoms readme](https://github.com/calcom/cal.com/blob/main/packages/platform/atoms/README.md). Every public package must: +1. Follow semantic versioning when using changesets. +2. Mark breaking changes using `❗️Breaking change` + + + +## License + +Distributed under the [AGPLv3 License](https://github.com/calcom/cal.com/blob/main/LICENSE). See `LICENSE` for more information. + + + +## Acknowledgements + +Special thanks to these amazing projects which help power Cal.com: + +- [Vercel](https://vercel.com/?utm_source=calend-so&utm_campaign=oss) +- [Next.js](https://nextjs.org/) +- [Day.js](https://day.js.org/) +- [Tailwind CSS](https://tailwindcss.com/) +- [Prisma](https://prisma.io/) + +Cal.com is an [open startup](https://cal.com/open) and [Jitsu](https://github.com/jitsucom/jitsu) (an open-source Segment alternative) helps us to track most of the usage metrics. \ No newline at end of file diff --git a/README.md b/README.md index 071e8d8..f33faa2 100644 --- a/README.md +++ b/README.md @@ -93,11 +93,22 @@ npm run setup `Ctrl/Cmd + Arrows` : move main window position +## Repo Activity + +![Alt](https://repobeats.axiom.co/api/embed/a23e342faafa84fa8797fa57762885d82fac1180.svg "Repobeats analytics image") + ## Contributing We love contributions! Feel free to open issues for bugs or feature requests. > Currently, we're working on a full code refactor and modularization. Once that's completed, we'll jump into addressing the major issues. +## Contributors + + + + + + ## 🛠 Current Issues & Improvements | Status | Issue | Description | From 076474480cee46c4fe8de5c28685ff318a4190eb Mon Sep 17 00:00:00 2001 From: entry-gi Date: Mon, 7 Jul 2025 01:10:32 +0900 Subject: [PATCH 12/52] readme contribution update --- README copy.md | 675 ------------------------------------------------- README.md | 10 +- 2 files changed, 7 insertions(+), 678 deletions(-) delete mode 100644 README copy.md diff --git a/README copy.md b/README copy.md deleted file mode 100644 index 456a005..0000000 --- a/README copy.md +++ /dev/null @@ -1,675 +0,0 @@ - -

- - Logo - - -

Cal.com (formerly Calendso)

- -

- The open-source Calendly successor. -
- Learn more » -
-
- Discussions - · - Website - · - Issues - · - Roadmap -

-

- -

- Product Hunt - Checkly QA - Uptime - Github Stars - Hacker News - License - Commits-per-month - Pricing - Jitsu Tracked - Checkly Availability - - - - - - -

- - - -## About the Project - -booking-screen - -# Scheduling infrastructure for absolutely everyone - -The open source Calendly successor. You are in charge -of your own data, workflow, and appearance. - -Calendly and other scheduling tools are awesome. It made our lives massively easier. We're using it for business meetings, seminars, yoga classes, and even calls with our families. However, most tools are very limited in terms of control and customization. - -That's where Cal.com comes in. Self-hosted or hosted by us. White-label by design. API-driven and ready to be deployed on your own domain. Full control of your events and data. - -## Recognition - -#### [Hacker News](https://news.ycombinator.com/from?site=cal.com) - - - Featured on Hacker News - - - - Featured on Hacker News - - -#### [Product Hunt](https://producthunt.com/products/cal-com?utm_source=badge-top-post-badge&utm_medium=badge) - -Cal.com - The open source Calendly alternative | Product Hunt Cal.com - The open source Calendly alternative | Product Hunt Cal.com - The open source Calendly alternative | Product Hunt - -### Built With - -- [Next.js](https://nextjs.org/?ref=cal.com) -- [tRPC](https://trpc.io/?ref=cal.com) -- [React.js](https://reactjs.org/?ref=cal.com) -- [Tailwind CSS](https://tailwindcss.com/?ref=cal.com) -- [Prisma.io](https://prisma.io/?ref=cal.com) -- [Daily.co](https://go.cal.com/daily) - -## Contact us - -Meet our sales team for any commercial inquiries. - -Book us with Cal.com - -## Stay Up-to-Date - -Cal.com officially launched as v.1.0 on the 15th of September 2021 and we've come a long way so far. Watch **releases** of this repository to be notified of future updates: - -![cal-star-github](https://user-images.githubusercontent.com/8019099/154853944-a9e3c999-3da3-4048-b149-b4f73893c6fb.gif) - - - -## Getting Started - -To get a local copy up and running, please follow these simple steps. - -### Prerequisites - -Here is what you need to be able to run Cal.com. - -- Node.js (Version: >=18.x) -- PostgreSQL (Version: >=13.x) -- Yarn _(recommended)_ - -> If you want to enable any of the available integrations, you may want to obtain additional credentials for each one. More details on this can be found below under the [integrations section](#integrations). - -## Development - -### Setup - -1. Clone the repo into a public GitHub repository (or fork https://github.com/calcom/cal.com/fork). If you plan to distribute the code, keep the source code public to comply with [AGPLv3](https://github.com/calcom/cal.com/blob/main/LICENSE). To clone in a private repository, [acquire a commercial license](https://cal.com/sales) - - ```sh - git clone https://github.com/calcom/cal.com.git - ``` - - > If you are on Windows, run the following command on `gitbash` with admin privileges:
> `git clone -c core.symlinks=true https://github.com/calcom/cal.com.git`
- > See [docs](https://cal.com/docs/how-to-guides/how-to-troubleshoot-symbolic-link-issues-on-windows#enable-symbolic-links) for more details. - -2. Go to the project folder - - ```sh - cd cal.com - ``` - -3. Install packages with yarn - - ```sh - yarn - ``` - -4. Set up your `.env` file - - - Duplicate `.env.example` to `.env` - - Use `openssl rand -base64 32` to generate a key and add it under `NEXTAUTH_SECRET` in the `.env` file. - - Use `openssl rand -base64 32` to generate a key and add it under `CALENDSO_ENCRYPTION_KEY` in the `.env` file. - -5. Setup Node - If your Node version does not meet the project's requirements as instructed by the docs, "nvm" (Node Version Manager) allows using Node at the version required by the project: - - ```sh - nvm use - ``` - - You first might need to install the specific version and then use it: - - ```sh - nvm install && nvm use - ``` - - You can install nvm from [here](https://github.com/nvm-sh/nvm). - -#### Quick start with `yarn dx` - -> - **Requires Docker and Docker Compose to be installed** -> - Will start a local Postgres instance with a few test users - the credentials will be logged in the console - -```sh -yarn dx -``` - -#### Development tip -1. Add `export NODE_OPTIONS=“--max-old-space-size=16384”` to your shell script to increase the memory limit for the node process. Alternatively, you can run this in your terminal before running the app. Replace 16384 with the amount of RAM you want to allocate to the node process. - -2. Add `NEXT_PUBLIC_LOGGER_LEVEL={level}` to your .env file to control the logging verbosity for all tRPC queries and mutations.\ - Where {level} can be one of the following: - - `0` for silly \ - `1` for trace \ - `2` for debug \ - `3` for info \ - `4` for warn \ - `5` for error \ - `6` for fatal - - When you set `NEXT_PUBLIC_LOGGER_LEVEL={level}` in your .env file, it enables logging at that level and higher. Here's how it works: - - The logger will include all logs that are at the specified level or higher. For example: \ - - - If you set `NEXT_PUBLIC_LOGGER_LEVEL=2`, it will log from level 2 (debug) upwards, meaning levels 2 (debug), 3 (info), 4 (warn), 5 (error), and (fatal) will be logged. \ - - If you set `NEXT_PUBLIC_LOGGER_LEVEL=3`, it will log from level 3 (info) upwards, meaning levels 3 (info), 4 (warn), 5 (error), and 6 (fatal) will be logged, but level 2 (debug) and level 1 (trace) will be ignored. \ - -```sh -echo 'NEXT_PUBLIC_LOGGER_LEVEL=3' >> .env -``` - -for Logger level to be set at info, for example. - -#### Gitpod Setup - -1. Click the button below to open this project in Gitpod. - -2. This will open a fully configured workspace in your browser with all the necessary dependencies already installed. - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/calcom/cal.com) - -#### Manual setup - -1. Configure environment variables in the `.env` file. Replace ``, ``, ``, and `` with their applicable values - - ``` - DATABASE_URL='postgresql://:@:' - ``` - -
- If you don't know how to configure the DATABASE_URL, then follow the steps here to create a quick local DB - - 1. [Download](https://www.postgresql.org/download/) and install postgres in your local (if you don't have it already). - - 2. Create your own local db by executing `createDB ` - - 3. Now open your psql shell with the DB you created: `psql -h localhost -U postgres -d ` - - 4. Inside the psql shell execute `\conninfo`. And you will get the following info. - ![image](https://user-images.githubusercontent.com/39329182/236612291-51d87f69-6dc1-4a23-bf4d-1ca1754e0a35.png) - - 5. Now extract all the info and add it to your DATABASE_URL. The url would look something like this - `postgresql://postgres:postgres@localhost:5432/Your-DB-Name`. The port is configurable and does not have to be 5432. - -
- - If you don't want to create a local DB. Then you can also consider using services like railway.app or render. - - - [Setup postgres DB with railway.app](https://docs.railway.app/guides/postgresql) - - [Setup postgres DB with render](https://render.com/docs/databases) - -1. Copy and paste your `DATABASE_URL` from `.env` to `.env.appStore`. - -1. Set up the database using the Prisma schema (found in `packages/prisma/schema.prisma`) - - In a development environment, run: - - ```sh - yarn workspace @calcom/prisma db-migrate - ``` - - In a production environment, run: - - ```sh - yarn workspace @calcom/prisma db-deploy - ``` - -1. Run [mailhog](https://github.com/mailhog/MailHog) to view emails sent during development - - > **_NOTE:_** Required when `E2E_TEST_MAILHOG_ENABLED` is "1" - - ```sh - docker pull mailhog/mailhog - docker run -d -p 8025:8025 -p 1025:1025 mailhog/mailhog - ``` - -1. Run (in development mode) - - ```sh - yarn dev - ``` - -#### Setting up your first user - -##### Approach 1 - -1. Open [Prisma Studio](https://prisma.io/studio) to look at or modify the database content: - - ```sh - yarn db-studio - ``` - -1. Click on the `User` model to add a new user record. -1. Fill out the fields `email`, `username`, `password`, and set `metadata` to empty `{}` (remembering to encrypt your password with [BCrypt](https://bcrypt-generator.com/)) and click `Save 1 Record` to create your first user. - > New users are set on a `TRIAL` plan by default. You might want to adjust this behavior to your needs in the `packages/prisma/schema.prisma` file. -1. Open a browser to [http://localhost:3000](http://localhost:3000) and login with your just created, first user. - -##### Approach 2 - -Seed the local db by running - -```sh -cd packages/prisma -yarn db-seed -``` - -The above command will populate the local db with dummy users. - -### E2E-Testing - -Be sure to set the environment variable `NEXTAUTH_URL` to the correct value. If you are running locally, as the documentation within `.env.example` mentions, the value should be `http://localhost:3000`. - -```sh -# In a terminal just run: -yarn test-e2e - -# To open the last HTML report run: -yarn playwright show-report test-results/reports/playwright-html-report -``` - -#### Resolving issues - -##### E2E test browsers not installed - -Run `npx playwright install` to download test browsers and resolve the error below when running `yarn test-e2e`: - -``` -Executable doesn't exist at /Users/alice/Library/Caches/ms-playwright/chromium-1048/chrome-mac/Chromium.app/Contents/MacOS/Chromium -``` - -### Upgrading from earlier versions - -1. Pull the current version: - - ```sh - git pull - ``` - -1. Check if dependencies got added/updated/removed - - ```sh - yarn - ``` - -1. Apply database migrations by running one of the following commands: - - In a development environment, run: - - ```sh - yarn workspace @calcom/prisma db-migrate - ``` - - (This can clear your development database in some cases) - - In a production environment, run: - - ```sh - yarn workspace @calcom/prisma db-deploy - ``` - -1. Check for `.env` variables changes - - ```sh - yarn predev - ``` - -1. Start the server. In a development environment, just do: - - ```sh - yarn dev - ``` - - For a production build, run for example: - - ```sh - yarn build - yarn start - ``` - -1. Enjoy the new version. - - -## Deployment - -### Docker - -The Docker configuration for Cal.com is an effort powered by people within the community. - -If you want to contribute to the Docker repository, [reply here](https://github.com/calcom/docker/discussions/32). - -The Docker configuration can be found [in our docker repository](https://github.com/calcom/docker). - -Issues with Docker? Find your answer or open a new discussion [here](https://github.com/calcom/docker/discussions) to ask the community. - -Cal.com, Inc. does not provide official support for Docker, but we will accept fixes and documentation. Use at your own risk. - -### Railway - -[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/cal) - -You can deploy Cal.com on [Railway](https://railway.app) using the button above. The team at Railway also have a [detailed blog post](https://blog.railway.app/p/calendso) on deploying Cal.com on their platform. - -### Vercel - -Currently Vercel Pro Plan is required to be able to Deploy this application with Vercel, due to limitations on the number of serverless functions on the free plan. - -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fcalcom%2Fcal.com&env=DATABASE_URL,NEXT_PUBLIC_WEBAPP_URL,NEXTAUTH_URL,NEXTAUTH_SECRET,CRON_API_KEY,CALENDSO_ENCRYPTION_KEY&envDescription=See%20all%20available%20env%20vars&envLink=https%3A%2F%2Fgithub.com%2Fcalcom%2Fcal.com%2Fblob%2Fmain%2F.env.example&project-name=cal&repo-name=cal.com&build-command=cd%20../..%20%26%26%20yarn%20build&root-directory=apps%2Fweb%2F) - -### Render - -[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/calcom/docker) - -### Elestio - -[![Deploy on Elestio](https://elest.io/images/logos/deploy-to-elestio-btn.png)](https://elest.io/open-source/cal.com) - - - -## Roadmap - -Cal.com Roadmap - -See the [roadmap project](https://cal.com/roadmap) for a list of proposed features (and known issues). You can change the view to see planned tagged releases. - - - -## License - -Cal.com, Inc. is a commercial open source company, which means some parts of this open source repository require a commercial license. The concept is called "Open Core" where the core technology (99%) is fully open source, licensed under [AGPLv3](https://opensource.org/license/agpl-v3) and the last 1% is covered under a commercial license (["/ee" Enterprise Edition](https://github.com/calcom/cal.com/tree/main/packages/features/ee)) which we believe is entirely relevant for larger organisations that require enterprise features. Enterprise features are built by the core engineering team of Cal.com, Inc. which is hired in full-time. Find their compensation on https://cal.com/open. - -> [!NOTE] -> Our philosophy is simple, all "Singleplayer APIs" are open-source under AGPLv3. All commercial "Multiplayer APIs" are under a commercial license. - -| | AGPLv3 | EE | -| --------------------------------- | ------ | --- | -| Self-host for commercial purposes | ✅ | ✅ | -| Clone privately | ✅ | ✅ | -| Fork publicly | ✅ | ✅ | -| Requires CLA | ✅ | ✅ | -|  Official Support | ❌  | ✅ | -| Derivative work privately | ❌ | ✅ | -|  SSO | ❌ | ✅ | -| Admin Panel | ❌ | ✅ | -| Impersonation | ❌ | ✅ | -| Managed Event Types | ❌ | ✅ | -| Organizations | ❌ | ✅ | -| Payments | ❌ | ✅ | -| Platform | ❌ | ✅ | -| Teams | ❌ | ✅ | -| Users | ❌ | ✅ | -| Video | ❌ | ✅ | -| Workflows | ❌ | ✅ | - -> [!TIP] -> We work closely with the community and always invite feedback about what should be open and what is fine to be commercial. This list is not set and stone and we have moved things from commercial to open in the past. Please open a [discussion](https://github.com/calcom/cal.com/discussions) if you feel like something is wrong. - -## Repo Activity - - - - - -## Contributing - -Please see our [contributing guide](/CONTRIBUTING.md). - -### Good First Issues - -We have a list of [help wanted](https://github.com/calcom/cal.com/issues?q=is:issue+is:open+label:%22%F0%9F%99%8B%F0%9F%8F%BB%E2%80%8D%E2%99%82%EF%B8%8Fhelp+wanted%22) that contain small features and bugs which have a relatively limited scope. This is a great place to get started, gain experience, and get familiar with our contribution process. - - - -### Bounties - - - - - Bounties of cal - - - - - -### Contributors - - - - - - - -### Translations - -Don't code but still want to contribute? Join our [Discussions](https://github.com/calcom/cal.com/discussions) and join the [#Translate channel](https://github.com/calcom/cal.com/discussions/categories/translations) and let us know what language you want to translate. - -![ar translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ar&style=flat&logo=crowdin&query=%24.progress.0.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![bg translation](https://img.shields.io/badge/dynamic/json?color=blue&label=bg&style=flat&logo=crowdin&query=%24.progress.1.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![cs translation](https://img.shields.io/badge/dynamic/json?color=blue&label=cs&style=flat&logo=crowdin&query=%24.progress.2.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![de translation](https://img.shields.io/badge/dynamic/json?color=blue&label=de&style=flat&logo=crowdin&query=%24.progress.3.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![el translation](https://img.shields.io/badge/dynamic/json?color=blue&label=el&style=flat&logo=crowdin&query=%24.progress.4.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![en translation](https://img.shields.io/badge/dynamic/json?color=blue&label=en&style=flat&logo=crowdin&query=%24.progress.5.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![es translation](https://img.shields.io/badge/dynamic/json?color=blue&label=es&style=flat&logo=crowdin&query=%24.progress.6.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![es-419 translation](https://img.shields.io/badge/dynamic/json?color=blue&label=es-419&style=flat&logo=crowdin&query=%24.progress.7.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![fr translation](https://img.shields.io/badge/dynamic/json?color=blue&label=fr&style=flat&logo=crowdin&query=%24.progress.8.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![he translation](https://img.shields.io/badge/dynamic/json?color=blue&label=he&style=flat&logo=crowdin&query=%24.progress.9.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![hu translation](https://img.shields.io/badge/dynamic/json?color=blue&label=hu&style=flat&logo=crowdin&query=%24.progress.10.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![it translation](https://img.shields.io/badge/dynamic/json?color=blue&label=it&style=flat&logo=crowdin&query=%24.progress.11.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![ja translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ja&style=flat&logo=crowdin&query=%24.progress.12.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![ko translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ko&style=flat&logo=crowdin&query=%24.progress.13.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![nl translation](https://img.shields.io/badge/dynamic/json?color=blue&label=nl&style=flat&logo=crowdin&query=%24.progress.14.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![no translation](https://img.shields.io/badge/dynamic/json?color=blue&label=no&style=flat&logo=crowdin&query=%24.progress.15.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![pl translation](https://img.shields.io/badge/dynamic/json?color=blue&label=pl&style=flat&logo=crowdin&query=%24.progress.16.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![pt translation](https://img.shields.io/badge/dynamic/json?color=blue&label=pt&style=flat&logo=crowdin&query=%24.progress.17.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![pt-BR translation](https://img.shields.io/badge/dynamic/json?color=blue&label=pt-BR&style=flat&logo=crowdin&query=%24.progress.18.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![ro translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ro&style=flat&logo=crowdin&query=%24.progress.19.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![ru translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ru&style=flat&logo=crowdin&query=%24.progress.20.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![sr translation](https://img.shields.io/badge/dynamic/json?color=blue&label=sr&style=flat&logo=crowdin&query=%24.progress.21.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![sv translation](https://img.shields.io/badge/dynamic/json?color=blue&label=sv&style=flat&logo=crowdin&query=%24.progress.22.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![tr translation](https://img.shields.io/badge/dynamic/json?color=blue&label=tr&style=flat&logo=crowdin&query=%24.progress.23.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![uk translation](https://img.shields.io/badge/dynamic/json?color=blue&label=uk&style=flat&logo=crowdin&query=%24.progress.24.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![vi translation](https://img.shields.io/badge/dynamic/json?color=blue&label=vi&style=flat&logo=crowdin&query=%24.progress.25.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![zh-CN translation](https://img.shields.io/badge/dynamic/json?color=blue&label=zh-CN&style=flat&logo=crowdin&query=%24.progress.26.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) ![zh-TW translation](https://img.shields.io/badge/dynamic/json?color=blue&label=zh-TW&style=flat&logo=crowdin&query=%24.progress.27.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-200011276-1.json) - -## Enabling Content Security Policy - -- Set CSP_POLICY="non-strict" env variable, which enables [Strict CSP](https://web.dev/strict-csp/) except for unsafe-inline in style-src . If you have some custom changes in your instance, you might have to make some code change to make your instance CSP compatible. Right now it enables strict CSP only on login page and on other SSR pages it is enabled in Report only mode to detect possible issues. On, SSG pages it is still not supported. - -## Single Org Mode -If you want to have booker.yourcompany.com to be the domain used for both dashboard(e.g. https://booker.yourcompany.com/event-types) and booking pages(e.g. https://booker.yourcompany.com/john.joe/15min). -- Set the `NEXT_PUBLIC_SINGLE_ORG_SLUG` environment variable to the slug of the organization you want to use. `NEXT_PUBLIC_SINGLE_ORG_SLUG=booker` -- Set the `NEXT_PUBLIC_WEBAPP_URL` environment variable to the URL of the Cal.com self-hosted instance e.g. `NEXT_PUBLIC_WEBAPP_URL=https://booker.yourcompany.com`. -- Set the `NEXT_PUBLIC_WEBSITE_URL` environment variable to the URL of the Cal.com self-hosted instance e.g. `NEXT_PUBLIC_WEBSITE_URL=https://booker.yourcompany.com`. -- Set the `NEXTAUTH_URL` environment variable to the URL of the Cal.com self-hosted instance e.g. `NEXTAUTH_URL=https://booker.yourcompany.com`. - -Note: It causes root to serve the dashboard and not the organization profile page which shows all bookable users in the organization. - -## Integrations - -### Obtaining the Google API Credentials - -1. Open [Google API Console](https://console.cloud.google.com/apis/dashboard). If you don't have a project in your Google Cloud subscription, you'll need to create one before proceeding further. Under Dashboard pane, select Enable APIS and Services. -2. In the search box, type calendar and select the Google Calendar API search result. -3. Enable the selected API. -4. Next, go to the [OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent) from the side pane. Select the app type (Internal or External) and enter the basic app details on the first page. -5. In the second page on Scopes, select Add or Remove Scopes. Search for Calendar.event and select the scope with scope value `.../auth/calendar.events`, `.../auth/calendar.readonly` and select Update. -6. In the third page (Test Users), add the Google account(s) you'll be using. Make sure the details are correct on the last page of the wizard and your consent screen will be configured. -7. Now select [Credentials](https://console.cloud.google.com/apis/credentials) from the side pane and then select Create Credentials. Select the OAuth Client ID option. -8. Select Web Application as the Application Type. -9. Under Authorized redirect URI's, select Add URI and then add the URI `/api/integrations/googlecalendar/callback` and `/api/auth/callback/google` replacing Cal.com URL with the URI at which your application runs. -10. The key will be created and you will be redirected back to the Credentials page. Select the newly generated client ID under OAuth 2.0 Client IDs. -11. Select Download JSON. Copy the contents of this file and paste the entire JSON string in the `.env` file as the value for `GOOGLE_API_CREDENTIALS` key. - -#### _Adding google calendar to Cal.com App Store_ - -After adding Google credentials, you can now Google Calendar App to the app store. -You can repopulate the App store by running - -``` -cd packages/prisma -yarn seed-app-store -``` - -You will need to complete a few more steps to activate Google Calendar App. -Make sure to complete section "Obtaining the Google API Credentials". After that do the -following - -1. Add extra redirect URL `/api/auth/callback/google` -1. Under 'OAuth consent screen', click "PUBLISH APP" - -### Obtaining Microsoft Graph Client ID and Secret - -1. Open [Azure App Registration](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps) and select New registration -2. Name your application -3. Set **Who can use this application or access this API?** to **Accounts in any organizational directory (Any Azure AD directory - Multitenant)** -4. Set the **Web** redirect URI to `/api/integrations/office365calendar/callback` replacing Cal.com URL with the URI at which your application runs. -5. Use **Application (client) ID** as the **MS_GRAPH_CLIENT_ID** attribute value in .env -6. Click **Certificates & secrets** create a new client secret and use the value as the **MS_GRAPH_CLIENT_SECRET** attribute - -### Obtaining Zoom Client ID and Secret - -1. Open [Zoom Marketplace](https://marketplace.zoom.us/) and sign in with your Zoom account. -2. On the upper right, click "Develop" => "Build App". -3. Select "General App" , click "Create". -4. Name your App. -5. Choose "User-managed app" for "Select how the app is managed". -6. De-select the option to publish the app on the Zoom App Marketplace, if asked. -7. Now copy the Client ID and Client Secret to your `.env` file into the `ZOOM_CLIENT_ID` and `ZOOM_CLIENT_SECRET` fields. -8. Set the "OAuth Redirect URL" under "OAuth Information" as `/api/integrations/zoomvideo/callback` replacing Cal.com URL with the URI at which your application runs. -9. Also add the redirect URL given above as an allow list URL and enable "Subdomain check". Make sure, it says "saved" below the form. -10. You don't need to provide basic information about your app. Instead click on "Scopes" and then on "+ Add Scopes". On the left, - 1. click the category "Meeting" and check the scope `meeting:write:meeting`. - 2. click the category "User" and check the scope `user:read:settings`. -11. Click "Done". -12. You're good to go. Now you can easily add your Zoom integration in the Cal.com settings. - -### Obtaining Daily API Credentials - -1. Visit our [Daily.co Partnership Form](https://go.cal.com/daily) and enter your information -2. From within your dashboard, go to the [developers](https://dashboard.daily.co/developers) tab. -3. Copy your API key. -4. Now paste the API key to your `.env` file into the `DAILY_API_KEY` field in your `.env` file. -5. If you have the [Daily Scale Plan](https://daily.co/pricing) set the `DAILY_SCALE_PLAN` variable to `true` in order to use features like video recording. - -### Obtaining Basecamp Client ID and Secret - -1. Visit the [37 Signals Integrations Dashboard](launchpad.37signals.com/integrations) and sign in. -2. Register a new application by clicking the Register one now link. -3. Fill in your company details. -4. Select Basecamp 4 as the product to integrate with. -5. Set the Redirect URL for OAuth `/api/integrations/basecamp3/callback` replacing Cal.com URL with the URI at which your application runs. -6. Click on done and copy the Client ID and secret into the `BASECAMP3_CLIENT_ID` and `BASECAMP3_CLIENT_SECRET` fields. -7. Set the `BASECAMP3_CLIENT_SECRET` env variable to `{your_domain} ({support_email})`. - For example, `Cal.com (support@cal.com)`. - -### Obtaining HubSpot Client ID and Secret - -1. Open [HubSpot Developer](https://developer.hubspot.com/) and sign into your account, or create a new one. -2. From within the home of the Developer account page, go to "Manage apps". -3. Click "Create app" button top right. -4. Fill in any information you want in the "App info" tab -5. Go to tab "Auth" -6. Now copy the Client ID and Client Secret to your `.env` file into the `HUBSPOT_CLIENT_ID` and `HUBSPOT_CLIENT_SECRET` fields. -7. Set the Redirect URL for OAuth `/api/integrations/hubspot/callback` replacing Cal.com URL with the URI at which your application runs. -8. In the "Scopes" section at the bottom of the page, make sure you select "Read" and "Write" for scope called `crm.objects.contacts` -9. Click the "Save" button at the bottom footer. -10. You're good to go. Now you can see any booking in Cal.com created as a meeting in HubSpot for your contacts. - -### Obtaining Webex Client ID and Secret - -[See Webex Readme](./packages/app-store/webex/) - -### Obtaining ZohoCRM Client ID and Secret - -1. Open [Zoho API Console](https://api-console.zoho.com/) and sign into your account, or create a new one. -2. From within the API console page, go to "Applications". -3. Click "ADD CLIENT" button top right and select "Server-based Applications". -4. Fill in any information you want in the "Client Details" tab -5. Go to tab "Client Secret" tab. -6. Now copy the Client ID and Client Secret to your `.env` file into the `ZOHOCRM_CLIENT_ID` and `ZOHOCRM_CLIENT_SECRET` fields. -7. Set the Redirect URL for OAuth `/api/integrations/zohocrm/callback` replacing Cal.com URL with the URI at which your application runs. -8. In the "Settings" section check the "Multi-DC" option if you wish to use the same OAuth credentials for all data centers. -9. Click the "Save"/ "UPDATE" button at the bottom footer. -10. You're good to go. Now you can easily add your ZohoCRM integration in the Cal.com settings. - -### Obtaining Zoho Calendar Client ID and Secret - -[Follow these steps](./packages/app-store/zohocalendar/) - -### Obtaining Zoho Bigin Client ID and Secret - -[Follow these steps](./packages/app-store/zoho-bigin/) - -### Obtaining Pipedrive Client ID and Secret - -[Follow these steps](./packages/app-store/pipedrive-crm/) - -## Workflows - -### Setting up SendGrid for Email reminders - -1. Create a SendGrid account (https://signup.sendgrid.com/) -2. Go to Settings -> API keys and create an API key -3. Copy API key to your `.env` file into the `SENDGRID_API_KEY` field -4. Go to Settings -> Sender Authentication and verify a single sender -5. Copy the verified E-Mail to your `.env` file into the `SENDGRID_EMAIL` field -6. Add your custom sender name to the `.env` file into the `NEXT_PUBLIC_SENDGRID_SENDER_NAME` field (fallback is Cal.com) - -### Setting up Twilio for SMS reminders - -1. Create a Twilio account (https://twilio.com/try-twilio) -2. Click ‘Get a Twilio phone number’ -3. Copy Account SID to your `.env` file into the `TWILIO_SID` field -4. Copy Auth Token to your `.env` file into the `TWILIO_TOKEN` field -5. Copy your Twilio phone number to your `.env` file into the `TWILIO_PHONE_NUMBER` field -6. Add your own sender ID to the `.env` file into the `NEXT_PUBLIC_SENDER_ID` field (fallback is Cal.com) -7. Create a messaging service (Develop -> Messaging -> Services) -8. Choose any name for the messaging service -9. Click 'Add Senders' -10. Choose phone number as sender type -11. Add the listed phone number -12. Leave all other fields as they are -13. Complete setup and click ‘View my new Messaging Service’ -14. Copy Messaging Service SID to your `.env` file into the `TWILIO_MESSAGING_SID` field -15. Create a verify service -16. Copy Verify Service SID to your `.env` file into the `TWILIO_VERIFY_SID` field - -## Changesets - -We use changesets to generate changelogs and publish public packages (packages with `private: true` are ignored). - -An example of good readme is [atoms readme](https://github.com/calcom/cal.com/blob/main/packages/platform/atoms/README.md). Every public package must: -1. Follow semantic versioning when using changesets. -2. Mark breaking changes using `❗️Breaking change` - - - -## License - -Distributed under the [AGPLv3 License](https://github.com/calcom/cal.com/blob/main/LICENSE). See `LICENSE` for more information. - - - -## Acknowledgements - -Special thanks to these amazing projects which help power Cal.com: - -- [Vercel](https://vercel.com/?utm_source=calend-so&utm_campaign=oss) -- [Next.js](https://nextjs.org/) -- [Day.js](https://day.js.org/) -- [Tailwind CSS](https://tailwindcss.com/) -- [Prisma](https://prisma.io/) - -Cal.com is an [open startup](https://cal.com/open) and [Jitsu](https://github.com/jitsucom/jitsu) (an open-source Segment alternative) helps us to track most of the usage metrics. \ No newline at end of file diff --git a/README.md b/README.md index f33faa2..db05c9d 100644 --- a/README.md +++ b/README.md @@ -102,14 +102,18 @@ npm run setup We love contributions! Feel free to open issues for bugs or feature requests. > Currently, we're working on a full code refactor and modularization. Once that's completed, we'll jump into addressing the major issues. -## Contributors +### Contributors +### Help Wanted Issues -## 🛠 Current Issues & Improvements +We have a list of [help wanted](https://github.com/pickle-com/glass/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22%F0%9F%99%8B%E2%80%8D%E2%99%82%EF%B8%8Fhelp%20wanted%22) that contain small features and bugs which have a relatively limited scope. This is a great place to get started, gain experience, and get familiar with our contribution process. + + +### 🛠 Current Issues & Improvements | Status | Issue | Description | |--------|--------------------------------|---------------------------------------------------| @@ -121,7 +125,7 @@ We love contributions! Feel free to open issues for bugs or feature requests. | 🚧 WIP | Login Issue | Currently breaking when switching between local and sign-in mode | | 🚧 WIP | Liquid Glass | Liquid Glass UI for MacOS 26 | -## Changelog +### Changelog - Jul 5: Now support Gemini, Intel Mac supported From 1f2eda1ee162c34659f96916daab0c821d02b766 Mon Sep 17 00:00:00 2001 From: entry-gi Date: Mon, 7 Jul 2025 05:05:42 +0900 Subject: [PATCH 13/52] contribution guide update --- CONTRIBUTING.md | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 +- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..26ad1a2 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,95 @@ +# Contributing to Glass + +Thank you for considering contributing to **Glass by Pickle**! Contributions make the open-source community vibrant, innovative, and collaborative. We appreciate every contribution you make—big or small. + +## 📌 Contribution Guidelines + +### 👥 Avoid Work Duplication + +Before creating an issue or submitting a pull request (PR), please check existing [Issues](https://github.com/pickle-com/glass/issues) and [Pull Requests](https://github.com/pickle-com/glass/pulls) to prevent duplicate efforts. + +### ✅ Start with Approved Issues + +- **Feature Requests**: Please wait for approval from core maintainers before starting work. Issues needing approval are marked with the `🚨 needs approval` label. +- **Bugs & Improvements**: You may begin immediately without explicit approval. + +### 📝 Clearly Document Your Work + +Provide enough context and detail to allow easy understanding. Issues and PRs should clearly communicate the problem or feature and stand alone without external references. + +### 💡 Summarize Pull Requests + +Include a brief summary at the top of your PR, describing the intent and scope of your changes. + +### 🔗 Link Related Issues + +Use GitHub keywords (`Closes #123`, `Fixes #456`) to auto-link and close issues upon PR merge. + +### 🧪 Include Testing Information + +Clearly state how your changes were tested. + +> Example: +> "Tested locally on macOS 14, confirmed all features working as expected." + +### 🧠 Future-Proof Your Descriptions + +Document trade-offs, edge cases, and temporary workarounds clearly to help future maintainers understand your decisions. + +--- + +## 🔖 Issue Priorities + +| Issue Type | Priority | +|----------------------------------------------------|---------------------| +| Minor enhancements & non-core feature requests | 🟢 Low Priority | +| UX improvements & minor bugs | 🟡 Medium Priority | +| Core functionalities & essential features | 🟠 High Priority | +| Critical bugs & breaking issues | 🔴 Urgent | +| + + +# Developing + +### Prerequisites + +Ensure the following are installed: +- [Node.js v20.x.x](https://nodejs.org/en/download) +- [Python](https://www.python.org/downloads/) +- (Windows users) [Build Tools for Visual Studio](https://visualstudio.microsoft.com/downloads/) + +Ensure you're using Node.js version 20.x.x to avoid build errors with native dependencies. + +```bash +# Check your Node.js version +node --version + +# If you need to install Node.js 20.x.x, we recommend using nvm: +# curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash +# nvm install 20 +# nvm use 20 +``` + +## Setup and Build + +```bash +npm run setup +``` +Please ensure that you can make a full production build before pushing code. + + + +## Linting + +```bash +npm run lint +``` + +If you get errors, be sure to fix them before committing. + + +## Making a Pull Request + +- Be sure to [check the "Allow edits from maintainers" option](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork) when creating your PR. (This option isn't available if you're [contributing from a fork belonging to an organization](https://github.com/orgs/community/discussions/5634)) +- If your PR refers to or fixes an issue, add `refs #XXX` or `fixes #XXX` to the PR description. Replace `XXX` with the respective issue number. See more about [linking a pull request to an issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue). +- Lastly, make sure to keep your branches updated (e.g., click the `Update branch` button on the GitHub PR page). \ No newline at end of file diff --git a/README.md b/README.md index db05c9d..8397aec 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ npm run setup ## Contributing -We love contributions! Feel free to open issues for bugs or feature requests. +We love contributions! Feel free to open issues for bugs or feature requests. For detailed guide, please see our [contributing guide](/CONTRIBUTING.md). > Currently, we're working on a full code refactor and modularization. Once that's completed, we'll jump into addressing the major issues. ### Contributors From 6bbca0371952bf5d0fd7ef93e6dbd1b63ef96abd Mon Sep 17 00:00:00 2001 From: samtiz Date: Mon, 7 Jul 2025 09:04:40 +0900 Subject: [PATCH 14/52] release v0.2.0 - refactoring done --- IPC_CHANNELS.md | 87 ----------------------------- REFACTORING_PLAN.md | 119 ---------------------------------------- REFACTORING_STATUS.md | 80 --------------------------- db_backup.js | 33 ----------- package.json | 2 +- test-code-formatting.md | 50 ----------------- 6 files changed, 1 insertion(+), 370 deletions(-) delete mode 100644 IPC_CHANNELS.md delete mode 100644 REFACTORING_PLAN.md delete mode 100644 REFACTORING_STATUS.md delete mode 100644 db_backup.js delete mode 100644 test-code-formatting.md diff --git a/IPC_CHANNELS.md b/IPC_CHANNELS.md deleted file mode 100644 index 5c4cf7f..0000000 --- a/IPC_CHANNELS.md +++ /dev/null @@ -1,87 +0,0 @@ -# IPC Channel Reference - -This document lists all the IPC channels used for communication between the main process and renderer processes in the Glass application. It serves as a central reference for developers. - ---- - -## 1. Two-Way Channels (`ipcMain.handle` / `ipcRenderer.invoke`) - -These channels are used for request-response communication where the renderer process expects a value to be returned from the main process. - -### Window & System Management -- `get-header-position`: Gets the current [x, y] coordinates of the header window. -- `move-header-to`: Moves the header window to a specific [x, y] coordinate. -- `resize-header-window`: Resizes the header window to a specific width and height. -- `move-window-step`: Moves the header window by a predefined step in a given direction. -- `is-window-visible`: Checks if a specific feature window (e.g., 'ask') is currently visible. -- `force-close-window`: Forces a specific feature window to hide. -- `toggle-all-windows-visibility`: Toggles the visibility of all application windows. -- `toggle-feature`: Shows or hides a specific feature window (e.g., 'ask', 'listen'). -- `quit-application`: Quits the entire application. - -### Authentication & User -- `get-current-user`: Retrieves the full state of the current user (Firebase or local). -- `start-firebase-auth`: Opens the Firebase login flow in the system browser. -- `firebase-logout`: Initiates the user logout process. -- `save-api-key`: Saves a user-provided API key. -- `remove-api-key`: Removes the currently stored API key. -- `get-stored-api-key`: Retrieves the currently active API key. -- `get-ai-provider`: Gets the currently configured AI provider (e.g., 'openai'). - -### Permissions & Settings -- `get-content-protection-status`: Checks if window content protection is enabled. -- `check-system-permissions`: Checks for microphone and screen recording permissions. -- `request-microphone-permission`: Prompts the user for microphone access. -- `open-system-preferences`: Opens the macOS System Preferences for a specific privacy setting. -- `mark-permissions-completed`: Marks the initial permission setup as completed. -- `check-permissions-completed`: Checks if the initial permission setup was completed. -- `update-google-search-setting`: Updates the setting for Google Search integration. - -### Data & Content -- `get-user-presets`: Fetches all custom prompt presets for the current user. -- `get-preset-templates`: Fetches the default prompt preset templates. -- `save-ask-message`: Saves a user question and AI response pair to the database. -- `get-web-url`: Gets the dynamically assigned URLs for the backend and web frontend. - -### Features (Listen, Ask, etc.) -- `initialize-openai`: Initializes the STT and other AI services for a new session. -- `is-session-active`: Checks if a listen/summary session is currently active. -- `send-audio-content`: Sends a chunk of audio data from renderer to main for processing. -- `start-macos-audio`, `stop-macos-audio`: Controls the background process for system audio capture on macOS. -- `close-session`: Stops the current listen session. -- `message-sending`: Notifies the main process that an 'ask' message is being sent. -- `send-question-to-ask`: Sends a question from one feature window (e.g., listen) to the 'ask' window. -- `capture-screenshot`: Requests the main process to take a screenshot. -- `get-current-screenshot`: Retrieves the most recent screenshot. -- `adjust-window-height`: Requests the main process to resize a window to a specific height. - ---- - -## 2. One-Way Channels (`ipcMain.on` / `ipcRenderer.send` / `webContents.send`) - -These channels are used for events or commands that do not require a direct response. - -### Main to Renderer (Events & Updates) -- `user-state-changed`: Notifies all windows that the user's authentication state has changed. -- `auth-failed`: Informs the UI that a Firebase authentication attempt failed. -- `session-state-changed`: Broadcasts whether a listen session is active or inactive. -- `api-key-validated`, `api-key-updated`, `api-key-removed`: Events related to the lifecycle of the API key. -- `stt-update`: Sends real-time speech-to-text transcription updates to the UI. -- `update-structured-data`: Sends processed data (summaries, topics) to the UI. -- `ask-response-chunk`, `ask-response-stream-end`: Sends streaming AI responses for the 'ask' feature. -- `window-show-animation`: Triggers a show/fade-in animation. -- `window-hide-animation`, `settings-window-hide-animation`: Triggers a hide/fade-out animation. -- `window-blur`: Notifies a window that it has lost focus. -- `window-did-show`: Confirms to a window that it is now visible. -- `click-through-toggled`: Informs the UI about the status of click-through mode. -- `start-listening-session`: Commands to control the main application view. -- `receive-question-from-assistant`: Delivers a question to the `AskView`. -- `ask-global-send`, `toggle-text-input`, `clear-ask-response`, `hide-text-input`: Commands for controlling the state of the `AskView`. - -### Renderer to Main (Commands & Events) -- `header-state-changed`: Informs the `windowManager` that the header's state (e.g., `apikey` vs `app`) has changed. -- `update-keybinds`: Sends updated keybinding preferences to the main process. -- `view-changed`: Notifies the main process that the visible view in `PickleGlassApp` has changed. -- `header-animation-complete`: Lets the main process know that a show/hide animation has finished. -- `cancel-hide-window`, `show-window`, `hide-window`: Commands to manage feature window visibility from the renderer. -- `session-did-close`: Notifies the main process that the user has manually closed the listen session. \ No newline at end of file diff --git a/REFACTORING_PLAN.md b/REFACTORING_PLAN.md deleted file mode 100644 index fea86d5..0000000 --- a/REFACTORING_PLAN.md +++ /dev/null @@ -1,119 +0,0 @@ -# DB & Architecture Refactoring Plan - -## 1. Goal - -DB 접근 로직을 **Electron 메인 프로세스로 중앙화**하고, **Feature 중심의 계층형 아키텍처**를 도입하여 코드의 안정성과 유지보수성을 극대화한다. - ---- - -## 2. Architecture: AS-IS → TO-BE - -```mermaid -graph TD - subgraph "AS-IS: 다중 접근 (충돌 위험)" - A_Main[Main Process] --> A_DB[(DB)] - A_Backend[Web Backend] --> A_DB - A_Browser[Browser] -- HTTP --> A_Backend - style A_Backend fill:#f99 - end - - subgraph "TO-BE: 단일 접근 (안정)" - B_Main[Main Process] --> B_DB[(DB)] - B_Backend[Web Backend] -- IPC --> B_Main - B_Browser[Browser] -- HTTP --> B_Backend - style B_Main fill:#9f9 - end -``` - ---- - -## 3. Target Folder Structure - -- `features` : 기능별로 View, Service, Repository를 그룹화하여 응집도 상승 -- `common`: 여러 기능이 공유하는 Repository 및 저수준 Service 배치 - -``` -src/ -├── features/ -│ └── listen/ -│ ├── listenView.js # View (UI) -│ ├── listenService.js # ViewModel (Logic) -│ └── repositories/ # Model (Feature-Data) -│ ├── index.js # <- 저장소 전략 선택 -│ ├── sqlite.repository.js -│ └── firebase.repository.js -│ -└── common/ - ├── services/ - │ └── sqliteClient.js # <- DB 연결/관리 - └── repositories/ # <- 공통 데이터 - ├── user/ - └── session/ -``` ---- - -## 4. Key Changes - -- **DB 접근 단일화** - - 모든 DB Read/Write는 **Electron 메인 프로세스**에서만 수행. - - 웹 백엔드(`backend_node`)는 IPC 통신을 통해 메인 프로세스에 데이터를 요청. - - 웹 백엔드의 DB 직접 연결 (`better-sqlite3`, `db.js`) 코드 전부 제거. - -- **Repository 패턴 도입** - - 모든 SQL 쿼리는 `*.repository.js` 파일로 분리 및 이동. - - **공통 Repository:** `common/repositories/` (e.g., `user`, `session`) - - **기능별 Repository:** `features/*/repositories/` (e.g., `transcript`, `summary`) - -- **Service 역할 명확화** - - `*Service.js`는 비즈니스 로직만 담당. Repository를 호출하여 데이터를 요청/저장하지만, **직접 SQL을 다루지 않음.** - -- **`renderer.js` 제거** - - `renderer.js`의 기능들을 각 책임에 맞는 View, Service로 이전 후 최종적으로 파일 삭제. - ---- - -## 5. Future-Proofing: 저장소 전략 패턴 - -로그인 여부에 따라 `SQLite`와 `Firebase` 저장소를 동적으로 스위칭할 수 있는 기반을 마련한다. Service 코드는 수정할 필요 없이, Repository 구현체만 추가하면 된다. - -```javascript -// e.g., common/repositories/session/index.js - -const sqliteRepo = require('./sqlite.repository.js'); -const firebaseRepo = require('./firebase.repository.js'); - -// 현재 상태에 따라 적절한 저장소를 동적으로 반환 -exports.getRepository = () => { - return isUserLoggedIn() ? firebaseRepo : sqliteRepo; -}; -``` - ---- - -## 6. Design Pattern & Feature Structure Guide - -각 Feature는 아래의 3-Layer 구조를 따르며, 이는 MVVM 패턴의 정신을 차용한 것입니다. - -| 파일 / 폴더 | 계층 (Layer) | 역할 (Role) & 책임 (Responsibilities) | -| ---------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -| `*View.js` | **View** | - **UI 렌더링:** Service로부터 받은 데이터를 화면에 표시.
- **사용자 입력:** 클릭, 입력 등의 이벤트를 감지하여 Service에 명령 전달. | -| `*Service.js` | **ViewModel** | - **상태 관리:** Feature에 필요한 모든 상태(State)를 소유하고 관리.
- **비즈니스 로직:** View의 요청을 받아 로직 수행.
- **데이터 조율:** Repository를 통해 데이터를 요청/저장하고, Main 프로세스와 IPC 통신. | -| `repositories/` | **Model / Data** | - **데이터 추상화:** DB(SQLite/Firebase)의 복잡한 쿼리를 숨기고, Service에 간단한 함수(`getById`, `save` 등)를 제공. | - -### 확장성 가이드: 파일이 너무 커진다면? - -"단일 책임 원칙"에 따라, 한 파일이 너무 많은 일을 하게 되면 주저 없이 분리합니다. - -- **Service Layer 분할:** - - **언제?** `listenService.js`가 STT 연결, 오디오 처리, 텍스트 분석 등 너무 많은 역할을 맡게 될 때. - - **어떻게?** 책임을 기준으로 더 작은 서비스로 분리합니다. - - `listenService.js` → **`sttService.js`**, **`audioService.js`**, **`analysisService.js`** - - 이때, 최상위 `listenService.js`는 여러 하위 서비스를 조율하는 **"Orchestrator(조정자)"**의 역할을 맡게 됩니다. - -- **View Layer 분할:** - - **언제?** `AssistantView.js` 하나의 파일이 너무 많은 UI 요소를 포함하고 복잡해질 때. - - **어떻게?** 재사용 가능한 UI 조각으로 분리합니다. - - `AssistantView.js` → **`TranscriptLog.js`**, **`SummaryDisplay.js`**, **`ActionButtons.js`** - -이 가이드를 따르면, 기능이 추가되거나 복잡해지더라도 코드베이스 전체가 일관되고 예측 가능한 구조를 유지할 수 있습니다. - diff --git a/REFACTORING_STATUS.md b/REFACTORING_STATUS.md deleted file mode 100644 index 6637ce0..0000000 --- a/REFACTORING_STATUS.md +++ /dev/null @@ -1,80 +0,0 @@ -# 리팩터링 진행 상황 보고서 - -> 이 문서는 `REFACTORING_PLAN.md`를 기준으로 현재까지의 진행 상황과 남은 과제를 추적합니다. - -### Phase 1: 아키텍처 기반 구축 (완료) - -이 단계의 목표는 **DB 접근을 메인 프로세스로 중앙화**하고, **계층형 아키텍처의 뼈대를 구축**하는 것이었습니다. 이 목표는 성공적으로 달성되었습니다. - -- **[✓] DB 접근 단일화:** - - `dataService.js`와 웹 백엔드의 DB 직접 접근 코드를 모두 제거했습니다. - - 이제 모든 DB 접근은 메인 프로세스의 `Repository` 계층을 통해서만 안전하게 이루어집니다. - -- **[✓] Repository 패턴 도입:** - - `userRepository`, `systemSettingsRepository`, `presetRepository` 등 공통 데이터 관리를 위한 저장소 계층을 성공적으로 구현하고 적용했습니다. - -- **[✓] Service 역할 명확화:** - - `authService`를 도입하여 모든 인증 로직을 중앙에서 관리하도록 했습니다. - - `liveSummaryService` 등 기존 서비스들이 더 이상 직접 DB에 접근하지 않고 Repository에 의존하도록 수정했습니다. - -### Phase 1.5: 인증 시스템 현대화 및 안정화 (완료) - -1단계에서 구축한 뼈대 위에, 앱의 핵심인 인증 시스템을 더욱 견고하고 사용자 친화적으로 만드는 작업을 완료했습니다. - -- **[✓] 완전한 인증 생명주기 관리:** - - `authService`가 Firebase 로그인 시 가상 API 키를 **자동으로 발급/저장**하고, 로그아웃 시 **자동으로 삭제**하는 전체 흐름을 구현했습니다. - -- **[✓] 상태 관리 중앙화 및 전파:** - - `authService`가 **유일한 진실의 원천(Single Source of Truth)**이 되어, `isLoggedIn`과 `hasApiKey` 상태를 명확히 구분하여 관리합니다. - - `user-state-changed`라는 단일 이벤트를 통해 모든 UI 컴포넌트가 일관된 상태 정보를 받도록 데이터 흐름을 정리했습니다. - -- **[✓] 레거시 코드 제거:** - - `windowManager`와 여러 렌더러 파일에 흩어져 있던 레거시 인증 로직, API 키 캐싱, 불필요한 IPC 핸들러들을 모두 제거하여 코드베이스를 깔끔하게 정리했습니다. - -- **[✓] 사용자 경험 최적화:** - - 로그인 세션을 영속화하여 **자동 로그인**을 구현했으며, 느린 네트워크 요청을 **비동기 백그라운드 처리**하여 UI 반응성을 극대화했습니다. - ---- - -### Phase 2: 기능별 모듈화 및 레거시 코드 완전 제거 (진행 예정) - -핵심 아키텍처가 안정화된 지금, 남아있는 기술 부채를 청산하고 앱 전체에 일관된 구조를 적용하는 마지막 단계를 진행합니다. - -#### 1. `renderer.js` 책임 분산 및 제거 (최우선 과제) - -- **최종 목표:** 거대 파일 `renderer.js` (1100+줄)를 완전히 제거하여, 각 기능의 UI 로직이 독립적인 모듈에서 관리되도록 합니다. -- **현황:** 현재 `renderer.js`는 `ask` 기능의 AI 메시지 전송, `listen` 기능의 오디오/스크린 캡처 및 전처리, 상태 관리 등 여러 책임이 복잡하게 얽혀있습니다. -- **수행 작업:** - 1. **`ask` 기능 책임 이전:** - - `renderer.js`의 `sendMessage`, `PICKLE_GLASS_SYSTEM_PROMPT`, 관련 유틸 함수(`formatRealtimeConversationHistory`, `getCurrentScreenshot` 등)를 `features/ask/askService.js` (또는 유사 모듈)로 이전합니다. - - `liveSummaryService.js`의 `save-ask-message` IPC 핸들러 로직을 `features/ask/repositories/askRepository.js`를 사용하는 `askService.js`로 이동시킵니다. - 2. **`listen` 기능 책임 이전:** - - `renderer.js`의 `startCapture`, `stopCapture`, `setupMicProcessing` 등 오디오/스크린 캡처 및 처리 관련 로직을 `features/listen/` 폴더 내의 적절한 파일 (예: `listenView.js` 또는 신규 `listenCaptureService.js`)로 이전합니다. - 3. **`renderer.js` 최종 제거:** - - 위 1, 2번 작업이 완료되어 `renderer.js`에 더 이상 의존하는 코드가 없을 때, 이 파일을 프로젝트에서 **삭제**합니다. - -#### 2. `listen` 기능 심화 리팩터링 - -- **목표:** 거대해진 `liveSummaryService.js`를 단일 책임 원칙에 따라 여러 개의 작은 서비스로 분리하여 유지보수성을 극대화합니다. -- **수행 작업:** - - `sttService.js`: STT 세션 연결 및 데이터 스트리밍을 전담합니다. - - `analysisService.js`: STT 텍스트를 받아 AI 모델에게 분석/요약을 요청하는 로직을 전담합니다. - - `listenService.js`: 상위 서비스로서, `sttService`와 `analysisService`를 조율하고 전체 "Listen" 기능의 상태를 관리하는 **조정자(Orchestrator)** 역할을 수행합니다. - -#### 3. `windowManager` 모듈화 - -- **목표:** 비대해진 `windowManager.js`의 책임들을 기능별로 분리하여, 각 모듈이 자신의 창 관련 로직만 책임지도록 구조를 개선합니다. -- **현황:** 현재 `windowManager.js`는 모든 창의 생성, 위치 계산, 단축키 등록, IPC 핸들링 등 너무 많은 역할을 수행하고 있습니다. -- **수행 작업:** - - **`windowLayoutManager.js`:** 여러 창의 위치를 동적으로 계산하고 배치하는 로직을 분리합니다. - - **`shortcutManager.js`:** 전역 단축키를 등록하고 관리하는 로직을 분리합니다. - - **`featureWindowManager.js` (가칭):** `ask`, `listen` 등 각 기능 창의 생성/소멸 및 관련 IPC 핸들러를 관리하는 로직을 분리합니다. - - `windowManager.js`: 최상위 관리자로서, `header` 창과 각 하위 관리자 모듈을 총괄하는 역할만 남깁니다. - ---- - -### Phase 3: 최종 정리 및 고도화 (향후) - -- **[ ] 전체 기능 회귀 테스트:** 모든 리팩터링 완료 후, 앱의 모든 기능이 의도대로 동작하는지 검증합니다. -- **[ ] 코드 클린업:** 디버깅용 `console.log`, 불필요한 주석 등을 최종적으로 정리합니다. -- **[ ] 문서 최신화:** `IPC_CHANNELS.md`를 포함한 모든 관련 문서를 최종 아키텍처에 맞게 업데이트합니다. \ No newline at end of file diff --git a/db_backup.js b/db_backup.js deleted file mode 100644 index d59636a..0000000 --- a/db_backup.js +++ /dev/null @@ -1,33 +0,0 @@ -const path = require('path'); -const databaseInitializer = require('../../src/common/services/databaseInitializer'); -const Database = require('better-sqlite3'); - -const dbPath = databaseInitializer.getDatabasePath(); -const db = new Database(dbPath); - -db.pragma('journal_mode = WAL'); - -// The schema is now managed by the main Electron process on startup. -// This file can assume the schema is correct and up-to-date. - -const defaultPresets = [ - ['school', 'School', 'You are a school and lecture assistant. Your goal is to help the user, a student, understand academic material and answer questions.\n\nWhenever a question appears on the user\'s screen or is asked aloud, you provide a direct, step-by-step answer, showing all necessary reasoning or calculations.\n\nIf the user is watching a lecture or working through new material, you offer concise explanations of key concepts and clarify definitions as they come up.', 1], - ['meetings', 'Meetings', 'You are a meeting assistant. Your goal is to help the user capture key information during meetings and follow up effectively.\n\nYou help capture meeting notes, track action items, identify key decisions, and summarize important points discussed during meetings.', 1], - ['sales', 'Sales', 'You are a real-time AI sales assistant, and your goal is to help the user close deals during sales interactions.\n\nYou provide real-time sales support, suggest responses to objections, help identify customer needs, and recommend strategies to advance deals.', 1], - ['recruiting', 'Recruiting', 'You are a recruiting assistant. Your goal is to help the user interview candidates and evaluate talent effectively.\n\nYou help evaluate candidates, suggest interview questions, analyze responses, and provide insights about candidate fit for positions.', 1], - ['customer-support', 'Customer Support', 'You are a customer support assistant. Your goal is to help resolve customer issues efficiently and thoroughly.\n\nYou help diagnose customer problems, suggest solutions, provide step-by-step troubleshooting guidance, and ensure customer satisfaction.', 1], -]; - -const stmt = db.prepare(` -INSERT OR IGNORE INTO prompt_presets (id, uid, title, prompt, is_default, created_at) -VALUES (@id, 'default_user', @title, @prompt, @is_default, strftime('%s','now')); -`); -db.transaction(() => defaultPresets.forEach(([id, title, prompt, is_default]) => stmt.run({ id, title, prompt, is_default })))(); - -const defaultUserStmt = db.prepare(` -INSERT OR IGNORE INTO users (uid, display_name, email, created_at) -VALUES ('default_user', 'Default User', 'contact@pickle.com', strftime('%s','now')); -`); -defaultUserStmt.run(); - -module.exports = db; diff --git a/package.json b/package.json index 75a89c0..3a6f218 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pickle-glass", "productName": "Glass", - "version": "0.1.2", + "version": "0.2.0", "description": "Cl*ely for Free", "main": "src/index.js", "scripts": { diff --git a/test-code-formatting.md b/test-code-formatting.md deleted file mode 100644 index a30d020..0000000 --- a/test-code-formatting.md +++ /dev/null @@ -1,50 +0,0 @@ -# Code Formatting Test - -Test various code blocks to ensure proper formatting: - -## Python Example (from screenshot) -```python -class Solution: - def subsets(self, nums: List[int]) -> List[List[int]]: - res = [] - - def backtrack(start, path): - res.append(path[:]) - for i in range(start, len(nums)): - path.append(nums[i]) - backtrack(i + 1, path) - path.pop() - - backtrack(0, []) - return res -``` - -## JavaScript Example -```javascript -function calculateSum(numbers) { - let sum = 0; - for (let i = 0; i < numbers.length; i++) { - sum += numbers[i]; - } - return sum; -} -``` - -## Indented Code with Complex Structure -```python -def complex_function(): - if True: - for i in range(10): - if i % 2 == 0: - print(f"Even: {i}") - else: - print(f"Odd: {i}") - if i > 5: - print(" Greater than 5") - nested = { - "key": "value", - "nested": { - "deep": "structure" - } - } -``` \ No newline at end of file From 86e903ec4b53500cb6e7561494259f30d89c9db8 Mon Sep 17 00:00:00 2001 From: entry-gi Date: Mon, 7 Jul 2025 16:33:19 +0900 Subject: [PATCH 15/52] header animation removed, crash fix --- src/app/content.html | 14 +-- src/electron/smoothMovementManager.js | 163 ++++++-------------------- src/electron/windowManager.js | 17 +-- 3 files changed, 55 insertions(+), 139 deletions(-) diff --git a/src/app/content.html b/src/app/content.html index 61768e1..130c7ac 100644 --- a/src/app/content.html +++ b/src/app/content.html @@ -100,13 +100,13 @@ } .window-sliding-down { - animation: slideDownFromHeader 0.25s cubic-bezier(0.23, 1, 0.32, 1) forwards; + animation: slideDownFromHeader 0.12s cubic-bezier(0.23, 1, 0.32, 1) forwards; will-change: transform, opacity; transform-style: preserve-3d; } .window-sliding-up { - animation: slideUpToHeader 0.18s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards; + animation: slideUpToHeader 0.10s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards; will-change: transform, opacity; transform-style: preserve-3d; } @@ -156,14 +156,14 @@ } .settings-window-show { - animation: settingsPopFromButton 0.22s cubic-bezier(0.23, 1, 0.32, 1) forwards; + animation: settingsPopFromButton 0.12s cubic-bezier(0.23, 1, 0.32, 1) forwards; transform-origin: 85% 0%; will-change: transform, opacity; transform-style: preserve-3d; } .settings-window-hide { - animation: settingsCollapseToButton 0.18s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards; + animation: settingsCollapseToButton 0.10s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards; transform-origin: 85% 0%; will-change: transform, opacity; transform-style: preserve-3d; @@ -250,7 +250,7 @@ if (animationTimeout) clearTimeout(animationTimeout); animationTimeout = setTimeout(() => { app.classList.remove('window-sliding-down'); - }, 250); + }, 120); }); ipcRenderer.on('window-hide-animation', () => { @@ -262,7 +262,7 @@ animationTimeout = setTimeout(() => { app.classList.remove('window-sliding-up'); app.classList.add('window-hidden'); - }, 180); + }, 100); }); ipcRenderer.on('settings-window-hide-animation', () => { @@ -274,7 +274,7 @@ animationTimeout = setTimeout(() => { app.classList.remove('settings-window-hide'); app.classList.add('window-hidden'); - }, 180); + }, 100); }); ipcRenderer.on('listen-window-move-to-center', () => { diff --git a/src/electron/smoothMovementManager.js b/src/electron/smoothMovementManager.js index 2550d0a..a676c82 100644 --- a/src/electron/smoothMovementManager.js +++ b/src/electron/smoothMovementManager.js @@ -60,140 +60,55 @@ class SmoothMovementManager { this.currentDisplayId = targetDisplay.id; } - hideToEdge(edge, callback) { + hideToEdge(edge, callback, { instant = false } = {}) { const header = this.windowPool.get('header'); - if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return; - - const currentBounds = header.getBounds(); - const display = this.getCurrentDisplay(header); - - if ( - !currentBounds || typeof currentBounds.x !== 'number' || typeof currentBounds.y !== 'number' || - !display || !display.workArea || !display.workAreaSize || - typeof display.workArea.x !== 'number' || typeof display.workArea.y !== 'number' || - typeof display.workAreaSize.width !== 'number' || typeof display.workAreaSize.height !== 'number' - ) { - console.error('[MovementManager] Invalid bounds or display info for hideToEdge. Aborting.'); + if (!header || header.isDestroyed()) { + if (typeof callback === 'function') callback(); return; } - - this.lastVisiblePosition = { x: currentBounds.x, y: currentBounds.y }; - this.headerPosition = { x: currentBounds.x, y: currentBounds.y }; - - const { width: screenWidth, height: screenHeight } = display.workAreaSize; - const { x: workAreaX, y: workAreaY } = display.workArea; - - let targetX = this.headerPosition.x; - let targetY = this.headerPosition.y; - - switch (edge) { - case 'top': targetY = workAreaY - currentBounds.height - 20; break; - case 'bottom': targetY = workAreaY + screenHeight + 20; break; - case 'left': targetX = workAreaX - currentBounds.width - 20; break; - case 'right': targetX = workAreaX + screenWidth + 20; break; + + const { x, y } = header.getBounds(); + this.lastVisiblePosition = { x, y }; + this.hiddenPosition = { edge }; + + if (instant) { + header.hide(); + if (typeof callback === 'function') callback(); + return; } - - this.hiddenPosition = { x: targetX, y: targetY, edge }; - this.isAnimating = true; - const startX = this.headerPosition.x; - const startY = this.headerPosition.y; - const duration = 400; - const startTime = Date.now(); - - const animate = () => { - if (!this._isWindowValid(header)) return; - const elapsed = Date.now() - startTime; - const progress = Math.min(elapsed / duration, 1); - const eased = progress * progress * progress; - const currentX = startX + (targetX - startX) * eased; - const currentY = startY + (targetY - startY) * eased; - - if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { - this.isAnimating = false; - return; - } - - if (!this._isWindowValid(header)) return; - header.setPosition(Math.round(currentX), Math.round(currentY)); - - if (progress < 1) { - this.animationFrameId = setTimeout(animate, 8); - } else { - this.animationFrameId = null; - this.headerPosition = { x: targetX, y: targetY }; - if (Number.isFinite(targetX) && Number.isFinite(targetY)) { - if (!this._isWindowValid(header)) return; - header.setPosition(Math.round(targetX), Math.round(targetY)); - } - this.isAnimating = false; - if (typeof callback === 'function') callback(); - } - }; - animate(); + header.webContents.send('window-hide-animation'); + + setTimeout(() => { + if (!header.isDestroyed()) header.hide(); + if (typeof callback === 'function') callback(); + }, 5); } - + showFromEdge(callback) { const header = this.windowPool.get('header'); - if ( - !this._isWindowValid(header) || this.isAnimating || - !this.hiddenPosition || !this.lastVisiblePosition || - typeof this.hiddenPosition.x !== 'number' || typeof this.hiddenPosition.y !== 'number' || - typeof this.lastVisiblePosition.x !== 'number' || typeof this.lastVisiblePosition.y !== 'number' - ) { - console.error('[MovementManager] Invalid state for showFromEdge. Aborting.'); - this.isAnimating = false; - this.hiddenPosition = null; - this.lastVisiblePosition = null; + if (!header || header.isDestroyed()) { + if (typeof callback === 'function') callback(); return; } - - if (!this._isWindowValid(header)) return; - header.setPosition(this.hiddenPosition.x, this.hiddenPosition.y); - - this.headerPosition = { x: this.hiddenPosition.x, y: this.hiddenPosition.y }; - const targetX = this.lastVisiblePosition.x; - const targetY = this.lastVisiblePosition.y; - this.isAnimating = true; - const startX = this.headerPosition.x; - const startY = this.headerPosition.y; - const duration = 500; - const startTime = Date.now(); - - const animate = () => { - if (!this._isWindowValid(header)) return; - - const elapsed = Date.now() - startTime; - const progress = Math.min(elapsed / duration, 1); - const c1 = 1.70158; - const c3 = c1 + 1; - const eased = 1 + c3 * Math.pow(progress - 1, 3) + c1 * Math.pow(progress - 1, 2); - const currentX = startX + (targetX - startX) * eased; - const currentY = startY + (targetY - startY) * eased; - if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { - this.isAnimating = false; - return; - } - - if (!this._isWindowValid(header)) return; - header.setPosition(Math.round(currentX), Math.round(currentY)); - - if (progress < 1) { - this.animationFrameId = setTimeout(animate, 8); - } else { - this.animationFrameId = null; - this.headerPosition = { x: targetX, y: targetY }; - if (Number.isFinite(targetX) && Number.isFinite(targetY)) { - if (!this._isWindowValid(header)) return; - header.setPosition(Math.round(targetX), Math.round(targetY)); - } - this.isAnimating = false; - this.hiddenPosition = null; - this.lastVisiblePosition = null; - if (callback) callback(); - } - }; - animate(); + + // 숨기기 전에 기억해둔 위치 복구 + if (this.lastVisiblePosition) { + header.setPosition( + this.lastVisiblePosition.x, + this.lastVisiblePosition.y, + false // animate: false + ); + } + + header.show(); + header.webContents.send('window-show-animation'); + + // 내부 상태 초기화 + this.hiddenPosition = null; + this.lastVisiblePosition = null; + + if (typeof callback === 'function') callback(); } moveStep(direction) { diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 9d74334..6c74a0f 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -236,12 +236,13 @@ function toggleAllWindowsVisibility(movementManager) { if (win.isVisible()) { lastVisibleWindows.add(name); if (name !== 'header') { - win.webContents.send('window-hide-animation'); - setTimeout(() => { - if (!win.isDestroyed()) { - win.hide(); - } - }, 200); + // win.webContents.send('window-hide-animation'); + // setTimeout(() => { + // if (!win.isDestroyed()) { + // win.hide(); + // } + // }, 200); + win.hide(); } } }); @@ -251,7 +252,7 @@ function toggleAllWindowsVisibility(movementManager) { movementManager.hideToEdge(nearestEdge, () => { header.hide(); console.log('[Visibility] Smart hide completed'); - }); + }, { instant: true }); } else { console.log('[Visibility] Smart showing from hidden position'); console.log('[Visibility] Restoring windows:', Array.from(lastVisibleWindows)); @@ -372,7 +373,7 @@ function createWindows() { // loadAndRegisterShortcuts(); // }); - ipcMain.handle('toggle-all-windows-visibility', toggleAllWindowsVisibility); + ipcMain.handle('toggle-all-windows-visibility', () => toggleAllWindowsVisibility(movementManager)); ipcMain.handle('toggle-feature', async (event, featureName) => { if (!windowPool.get(featureName) && currentHeaderState === 'main') { From 427be2a2937baa29ada5cf9389540fbab249f1b2 Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Mon, 7 Jul 2025 16:38:37 +0900 Subject: [PATCH 16/52] fix dependency --- .npmrc | 1 - package.json | 8 +- .../repositories/preset/sqlite.repository.js | 98 ++++--- .../repositories/session/sqlite.repository.js | 164 ++++------- .../repositories/user/sqlite.repository.js | 102 +++---- src/common/services/authService.js | 2 +- src/common/services/sqliteClient.js | 262 +++++++----------- src/electron/windowManager.js | 12 +- .../ask/repositories/sqlite.repository.js | 34 +-- .../stt/repositories/sqlite.repository.js | 36 +-- .../summary/repositories/sqlite.repository.js | 56 ++-- .../repositories/sqlite.repository.js | 150 +++++----- src/index.js | 211 +++++++------- 13 files changed, 477 insertions(+), 659 deletions(-) diff --git a/.npmrc b/.npmrc index d422cf4..5307c42 100644 --- a/.npmrc +++ b/.npmrc @@ -1,3 +1,2 @@ better-sqlite3:ignore-scripts=true -electron-deeplink:ignore-scripts=true sharp:ignore-scripts=true \ No newline at end of file diff --git a/package.json b/package.json index 3a6f218..0d27b52 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "package": "npm run build:renderer && electron-forge package", "make": "npm run build:renderer && electron-forge make", "build": "npm run build:renderer && electron-builder --config electron-builder.yml --publish never", + "build:win": "npm run build:renderer && electron-builder --win --x64 --publish never", "publish": "npm run build:renderer && electron-builder --config electron-builder.yml --publish always", "lint": "eslint --ext .ts,.tsx,.js .", "postinstall": "electron-builder install-app-deps", @@ -35,7 +36,7 @@ "better-sqlite3": "^9.4.3", "cors": "^2.8.5", "dotenv": "^17.0.0", - "electron-deeplink": "^1.0.10", + "electron-squirrel-startup": "^1.0.1", "electron-store": "^8.2.0", "electron-updater": "^6.6.2", @@ -47,7 +48,6 @@ "openai": "^4.70.0", "react-hot-toast": "^2.5.2", "sharp": "^0.34.2", - "sqlite3": "^5.1.7", "validator": "^13.11.0", "wait-on": "^8.0.3", "ws": "^8.18.0" @@ -69,8 +69,6 @@ "esbuild": "^0.25.5" }, "optionalDependencies": { - "@img/sharp-darwin-x64": "^0.34.2", - "@img/sharp-libvips-darwin-x64": "^1.1.0", "electron-liquid-glass": "^1.0.1" } -} +} \ No newline at end of file diff --git a/src/common/repositories/preset/sqlite.repository.js b/src/common/repositories/preset/sqlite.repository.js index 579fcbd..97ee1ca 100644 --- a/src/common/repositories/preset/sqlite.repository.js +++ b/src/common/repositories/preset/sqlite.repository.js @@ -2,40 +2,34 @@ const sqliteClient = require('../../services/sqliteClient'); function getPresets(uid) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = ` - SELECT * FROM prompt_presets - WHERE uid = ? OR is_default = 1 - ORDER BY is_default DESC, title ASC - `; - db.all(query, [uid], (err, rows) => { - if (err) { - console.error('SQLite: Failed to get presets:', err); - reject(err); - } else { - resolve(rows); - } - }); - }); + const query = ` + SELECT * FROM prompt_presets + WHERE uid = ? OR is_default = 1 + ORDER BY is_default DESC, title ASC + `; + + try { + return db.prepare(query).all(uid); + } catch (err) { + console.error('SQLite: Failed to get presets:', err); + throw err; + } } function getPresetTemplates() { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = ` - SELECT * FROM prompt_presets - WHERE is_default = 1 - ORDER BY title ASC - `; - db.all(query, [], (err, rows) => { - if (err) { - console.error('SQLite: Failed to get preset templates:', err); - reject(err); - } else { - resolve(rows); - } - }); - }); + const query = ` + SELECT * FROM prompt_presets + WHERE is_default = 1 + ORDER BY title ASC + `; + + try { + return db.prepare(query).all(); + } catch (err) { + console.error('SQLite: Failed to get preset templates:', err); + throw err; + } } function create({ uid, title, prompt }) { @@ -44,38 +38,42 @@ function create({ uid, title, prompt }) { const now = Math.floor(Date.now() / 1000); const query = `INSERT INTO prompt_presets (id, uid, title, prompt, is_default, created_at, sync_state) VALUES (?, ?, ?, ?, 0, ?, 'dirty')`; - return new Promise((resolve, reject) => { - db.run(query, [presetId, uid, title, prompt, now], function(err) { - if (err) reject(err); - else resolve({ id: presetId }); - }); - }); + try { + db.prepare(query).run(presetId, uid, title, prompt, now); + return { id: presetId }; + } catch (err) { + throw err; + } } function update(id, { title, prompt }, uid) { const db = sqliteClient.getDb(); const query = `UPDATE prompt_presets SET title = ?, prompt = ?, sync_state = 'dirty' WHERE id = ? AND uid = ? AND is_default = 0`; - return new Promise((resolve, reject) => { - db.run(query, [title, prompt, id, uid], function(err) { - if (err) reject(err); - else if (this.changes === 0) reject(new Error("Preset not found or permission denied.")); - else resolve({ changes: this.changes }); - }); - }); + try { + const result = db.prepare(query).run(title, prompt, id, uid); + if (result.changes === 0) { + throw new Error("Preset not found or permission denied."); + } + return { changes: result.changes }; + } catch (err) { + throw err; + } } function del(id, uid) { const db = sqliteClient.getDb(); const query = `DELETE FROM prompt_presets WHERE id = ? AND uid = ? AND is_default = 0`; - return new Promise((resolve, reject) => { - db.run(query, [id, uid], function(err) { - if (err) reject(err); - else if (this.changes === 0) reject(new Error("Preset not found or permission denied.")); - else resolve({ changes: this.changes }); - }); - }); + try { + const result = db.prepare(query).run(id, uid); + if (result.changes === 0) { + throw new Error("Preset not found or permission denied."); + } + return { changes: result.changes }; + } catch (err) { + throw err; + } } module.exports = { diff --git a/src/common/repositories/session/sqlite.repository.js b/src/common/repositories/session/sqlite.repository.js index 3f3ecac..509ba98 100644 --- a/src/common/repositories/session/sqlite.repository.js +++ b/src/common/repositories/session/sqlite.repository.js @@ -2,124 +2,79 @@ const sqliteClient = require('../../services/sqliteClient'); function getById(id) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - db.get('SELECT * FROM sessions WHERE id = ?', [id], (err, row) => { - if (err) reject(err); - else resolve(row); - }); - }); + return db.prepare('SELECT * FROM sessions WHERE id = ?').get(id); } function create(uid, type = 'ask') { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const sessionId = require('crypto').randomUUID(); - const now = Math.floor(Date.now() / 1000); - const query = `INSERT INTO sessions (id, uid, title, session_type, started_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)`; - - db.run(query, [sessionId, uid, `Session @ ${new Date().toLocaleTimeString()}`, type, now, now], function(err) { - if (err) { - console.error('SQLite: Failed to create session:', err); - reject(err); - } else { - console.log(`SQLite: Created session ${sessionId} for user ${uid} (type: ${type})`); - resolve(sessionId); - } - }); - }); + const sessionId = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = `INSERT INTO sessions (id, uid, title, session_type, started_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)`; + + try { + db.prepare(query).run(sessionId, uid, `Session @ ${new Date().toLocaleTimeString()}`, type, now, now); + console.log(`SQLite: Created session ${sessionId} for user ${uid} (type: ${type})`); + return sessionId; + } catch (err) { + console.error('SQLite: Failed to create session:', err); + throw err; + } } function getAllByUserId(uid) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = "SELECT id, uid, title, session_type, started_at, ended_at, sync_state, updated_at FROM sessions WHERE uid = ? ORDER BY started_at DESC"; - db.all(query, [uid], (err, rows) => { - if (err) reject(err); - else resolve(rows); - }); - }); + const query = "SELECT id, uid, title, session_type, started_at, ended_at, sync_state, updated_at FROM sessions WHERE uid = ? ORDER BY started_at DESC"; + return db.prepare(query).all(uid); } function updateTitle(id, title) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - db.run('UPDATE sessions SET title = ? WHERE id = ?', [title, id], function(err) { - if (err) reject(err); - else resolve({ changes: this.changes }); - }); - }); + const result = db.prepare('UPDATE sessions SET title = ? WHERE id = ?').run(title, id); + return { changes: result.changes }; } function deleteWithRelatedData(id) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - db.serialize(() => { - db.run("BEGIN TRANSACTION;"); - const queries = [ - "DELETE FROM transcripts WHERE session_id = ?", - "DELETE FROM ai_messages WHERE session_id = ?", - "DELETE FROM summaries WHERE session_id = ?", - "DELETE FROM sessions WHERE id = ?" - ]; - queries.forEach(query => { - db.run(query, [id], (err) => { - if (err) { - db.run("ROLLBACK;"); - return reject(err); - } - }); - }); - db.run("COMMIT;", (err) => { - if (err) { - db.run("ROLLBACK;"); - return reject(err); - } - resolve({ success: true }); - }); - }); + const transaction = db.transaction(() => { + db.prepare("DELETE FROM transcripts WHERE session_id = ?").run(id); + db.prepare("DELETE FROM ai_messages WHERE session_id = ?").run(id); + db.prepare("DELETE FROM summaries WHERE session_id = ?").run(id); + db.prepare("DELETE FROM sessions WHERE id = ?").run(id); }); + + try { + transaction(); + return { success: true }; + } catch (err) { + throw err; + } } function end(id) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const query = `UPDATE sessions SET ended_at = ?, updated_at = ? WHERE id = ?`; - db.run(query, [now, now, id], function(err) { - if (err) reject(err); - else resolve({ changes: this.changes }); - }); - }); + const now = Math.floor(Date.now() / 1000); + const query = `UPDATE sessions SET ended_at = ?, updated_at = ? WHERE id = ?`; + const result = db.prepare(query).run(now, now, id); + return { changes: result.changes }; } function updateType(id, type) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const query = 'UPDATE sessions SET session_type = ?, updated_at = ? WHERE id = ?'; - db.run(query, [type, now, id], function(err) { - if (err) { - reject(err); - } else { - resolve({ changes: this.changes }); - } - }); - }); + const now = Math.floor(Date.now() / 1000); + const query = 'UPDATE sessions SET session_type = ?, updated_at = ? WHERE id = ?'; + const result = db.prepare(query).run(type, now, id); + return { changes: result.changes }; } function touch(id) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const query = 'UPDATE sessions SET updated_at = ? WHERE id = ?'; - db.run(query, [now, id], function(err) { - if (err) reject(err); - else resolve({ changes: this.changes }); - }); - }); + const now = Math.floor(Date.now() / 1000); + const query = 'UPDATE sessions SET updated_at = ? WHERE id = ?'; + const result = db.prepare(query).run(now, id); + return { changes: result.changes }; } -async function getOrCreateActive(uid, requestedType = 'ask') { +function getOrCreateActive(uid, requestedType = 'ask') { const db = sqliteClient.getDb(); // 1. Look for ANY active session for the user (ended_at IS NULL). @@ -131,12 +86,7 @@ async function getOrCreateActive(uid, requestedType = 'ask') { LIMIT 1 `; - const activeSession = await new Promise((resolve, reject) => { - db.get(findQuery, [uid], (err, row) => { - if (err) reject(err); - else resolve(row); - }); - }); + const activeSession = db.prepare(findQuery).get(uid); if (activeSession) { // An active session exists. @@ -144,12 +94,12 @@ async function getOrCreateActive(uid, requestedType = 'ask') { // 2. Promotion Logic: If it's an 'ask' session and we need 'listen', promote it. if (activeSession.session_type === 'ask' && requestedType === 'listen') { - await updateType(activeSession.id, 'listen'); + updateType(activeSession.id, 'listen'); console.log(`[Repo] Promoted session ${activeSession.id} to 'listen' type.`); } // 3. Touch the session and return its ID. - await touch(activeSession.id); + touch(activeSession.id); return activeSession.id; } else { // 4. No active session found, create a new one. @@ -160,19 +110,17 @@ async function getOrCreateActive(uid, requestedType = 'ask') { function endAllActiveSessions() { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const query = `UPDATE sessions SET ended_at = ?, updated_at = ? WHERE ended_at IS NULL`; - db.run(query, [now, now], function(err) { - if (err) { - console.error('SQLite: Failed to end all active sessions:', err); - reject(err); - } else { - console.log(`[Repo] Ended ${this.changes} active session(s).`); - resolve({ changes: this.changes }); - } - }); - }); + const now = Math.floor(Date.now() / 1000); + const query = `UPDATE sessions SET ended_at = ?, updated_at = ? WHERE ended_at IS NULL`; + + try { + const result = db.prepare(query).run(now, now); + console.log(`[Repo] Ended ${result.changes} active session(s).`); + return { changes: result.changes }; + } catch (err) { + console.error('SQLite: Failed to end all active sessions:', err); + throw err; + } } module.exports = { diff --git a/src/common/repositories/user/sqlite.repository.js b/src/common/repositories/user/sqlite.repository.js index 47da7ad..2bb0ad7 100644 --- a/src/common/repositories/user/sqlite.repository.js +++ b/src/common/repositories/user/sqlite.repository.js @@ -13,89 +13,61 @@ function findOrCreate(user) { email=excluded.email `; - return new Promise((resolve, reject) => { - db.run(query, [uid, displayName, email, now], (err) => { - if (err) { - console.error('SQLite: Failed to find or create user:', err); - return reject(err); - } - getById(uid).then(resolve).catch(reject); - }); - }); + try { + db.prepare(query).run(uid, displayName, email, now); + return getById(uid); + } catch (err) { + console.error('SQLite: Failed to find or create user:', err); + throw err; + } } function getById(uid) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - db.get('SELECT * FROM users WHERE uid = ?', [uid], (err, row) => { - if (err) reject(err); - else resolve(row); - }); - }); + return db.prepare('SELECT * FROM users WHERE uid = ?').get(uid); } function saveApiKey(apiKey, uid, provider = 'openai') { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - db.run( - 'UPDATE users SET api_key = ?, provider = ? WHERE uid = ?', - [apiKey, provider, uid], - function(err) { - if (err) { - console.error('SQLite: Failed to save API key:', err); - reject(err); - } else { - console.log(`SQLite: API key saved for user ${uid} with provider ${provider}.`); - resolve({ changes: this.changes }); - } - } - ); - }); + try { + const result = db.prepare('UPDATE users SET api_key = ?, provider = ? WHERE uid = ?').run(apiKey, provider, uid); + console.log(`SQLite: API key saved for user ${uid} with provider ${provider}.`); + return { changes: result.changes }; + } catch (err) { + console.error('SQLite: Failed to save API key:', err); + throw err; + } } function update({ uid, displayName }) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - db.run('UPDATE users SET display_name = ? WHERE uid = ?', [displayName, uid], function(err) { - if (err) reject(err); - else resolve({ changes: this.changes }); - }); - }); + const result = db.prepare('UPDATE users SET display_name = ? WHERE uid = ?').run(displayName, uid); + return { changes: result.changes }; } function deleteById(uid) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const userSessions = db.prepare('SELECT id FROM sessions WHERE uid = ?').all(uid); - const sessionIds = userSessions.map(s => s.id); + const userSessions = db.prepare('SELECT id FROM sessions WHERE uid = ?').all(uid); + const sessionIds = userSessions.map(s => s.id); - db.serialize(() => { - db.run("BEGIN TRANSACTION;"); - - try { - if (sessionIds.length > 0) { - const placeholders = sessionIds.map(() => '?').join(','); - db.prepare(`DELETE FROM transcripts WHERE session_id IN (${placeholders})`).run(...sessionIds); - db.prepare(`DELETE FROM ai_messages WHERE session_id IN (${placeholders})`).run(...sessionIds); - db.prepare(`DELETE FROM summaries WHERE session_id IN (${placeholders})`).run(...sessionIds); - db.prepare(`DELETE FROM sessions WHERE uid = ?`).run(uid); - } - db.prepare('DELETE FROM prompt_presets WHERE uid = ? AND is_default = 0').run(uid); - db.prepare('DELETE FROM users WHERE uid = ?').run(uid); - - db.run("COMMIT;", (err) => { - if (err) { - db.run("ROLLBACK;"); - return reject(err); - } - resolve({ success: true }); - }); - } catch (err) { - db.run("ROLLBACK;"); - reject(err); - } - }); + const transaction = db.transaction(() => { + if (sessionIds.length > 0) { + const placeholders = sessionIds.map(() => '?').join(','); + db.prepare(`DELETE FROM transcripts WHERE session_id IN (${placeholders})`).run(...sessionIds); + db.prepare(`DELETE FROM ai_messages WHERE session_id IN (${placeholders})`).run(...sessionIds); + db.prepare(`DELETE FROM summaries WHERE session_id IN (${placeholders})`).run(...sessionIds); + db.prepare(`DELETE FROM sessions WHERE uid = ?`).run(uid); + } + db.prepare('DELETE FROM prompt_presets WHERE uid = ? AND is_default = 0').run(uid); + db.prepare('DELETE FROM users WHERE uid = ?').run(uid); }); + + try { + transaction(); + return { success: true }; + } catch (err) { + throw err; + } } module.exports = { diff --git a/src/common/services/authService.js b/src/common/services/authService.js index c7aab4e..f41f87e 100644 --- a/src/common/services/authService.js +++ b/src/common/services/authService.js @@ -123,7 +123,7 @@ class AuthService { const userState = this.getCurrentUser(); console.log('[AuthService] Broadcasting user state change:', userState); BrowserWindow.getAllWindows().forEach(win => { - if (win && !win.isDestroyed()) { + if (win && !win.isDestroyed() && win.webContents && !win.webContents.isDestroyed()) { win.webContents.send('user-state-changed', userState); } }); diff --git a/src/common/services/sqliteClient.js b/src/common/services/sqliteClient.js index a022159..afd64f3 100644 --- a/src/common/services/sqliteClient.js +++ b/src/common/services/sqliteClient.js @@ -1,4 +1,4 @@ -const sqlite3 = require('sqlite3').verbose(); +const Database = require('better-sqlite3'); const path = require('path'); const LATEST_SCHEMA = require('../config/schema'); @@ -10,28 +10,20 @@ class SQLiteClient { } connect(dbPath) { - return new Promise((resolve, reject) => { - if (this.db) { - console.log('[SQLiteClient] Already connected.'); - return resolve(); - } + if (this.db) { + console.log('[SQLiteClient] Already connected.'); + return; + } + try { this.dbPath = dbPath; - this.db = new sqlite3.Database(this.dbPath, (err) => { - if (err) { - console.error('[SQLiteClient] Could not connect to database', err); - return reject(err); - } - console.log('[SQLiteClient] Connected successfully to:', this.dbPath); - - this.db.run('PRAGMA journal_mode = WAL;', (err) => { - if (err) { - return reject(err); - } - resolve(); - }); - }); - }); + this.db = new Database(this.dbPath); + this.db.pragma('journal_mode = WAL'); + console.log('[SQLiteClient] Connected successfully to:', this.dbPath); + } catch (err) { + console.error('[SQLiteClient] Could not connect to database', err); + throw err; + } } getDb() { @@ -41,80 +33,56 @@ class SQLiteClient { return this.db; } - async synchronizeSchema() { + synchronizeSchema() { console.log('[DB Sync] Starting schema synchronization...'); - const tablesInDb = await this.getTablesFromDb(); + const tablesInDb = this.getTablesFromDb(); for (const tableName of Object.keys(LATEST_SCHEMA)) { const tableSchema = LATEST_SCHEMA[tableName]; if (!tablesInDb.includes(tableName)) { // Table doesn't exist, create it - await this.createTable(tableName, tableSchema); + this.createTable(tableName, tableSchema); } else { // Table exists, check for missing columns - await this.updateTable(tableName, tableSchema); + this.updateTable(tableName, tableSchema); } } console.log('[DB Sync] Schema synchronization finished.'); } - async getTablesFromDb() { - return new Promise((resolve, reject) => { - this.db.all("SELECT name FROM sqlite_master WHERE type='table'", (err, tables) => { - if (err) return reject(err); - resolve(tables.map(t => t.name)); - }); - }); + getTablesFromDb() { + const tables = this.db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all(); + return tables.map(t => t.name); } - async createTable(tableName, tableSchema) { - return new Promise((resolve, reject) => { - const columnDefs = tableSchema.columns.map(col => `"${col.name}" ${col.type}`).join(', '); - const query = `CREATE TABLE IF NOT EXISTS "${tableName}" (${columnDefs})`; + createTable(tableName, tableSchema) { + const columnDefs = tableSchema.columns.map(col => `"${col.name}" ${col.type}`).join(', '); + const query = `CREATE TABLE IF NOT EXISTS "${tableName}" (${columnDefs})`; - console.log(`[DB Sync] Creating table: ${tableName}`); - this.db.run(query, (err) => { - if (err) return reject(err); - resolve(); - }); - }); + console.log(`[DB Sync] Creating table: ${tableName}`); + this.db.prepare(query).run(); } - async updateTable(tableName, tableSchema) { - return new Promise((resolve, reject) => { - this.db.all(`PRAGMA table_info("${tableName}")`, async (err, existingColumns) => { - if (err) return reject(err); + updateTable(tableName, tableSchema) { + const existingColumns = this.db.prepare(`PRAGMA table_info("${tableName}")`).all(); + const existingColumnNames = existingColumns.map(c => c.name); + const columnsToAdd = tableSchema.columns.filter(col => !existingColumnNames.includes(col.name)); - const existingColumnNames = existingColumns.map(c => c.name); - const columnsToAdd = tableSchema.columns.filter(col => !existingColumnNames.includes(col.name)); - - if (columnsToAdd.length > 0) { - console.log(`[DB Sync] Updating table: ${tableName}. Adding columns: ${columnsToAdd.map(c=>c.name).join(', ')}`); - for (const column of columnsToAdd) { - const addColumnQuery = `ALTER TABLE "${tableName}" ADD COLUMN "${column.name}" ${column.type}`; - try { - await this.runQuery(addColumnQuery); - } catch (alterErr) { - return reject(alterErr); - } - } - } - resolve(); - }); - }); + if (columnsToAdd.length > 0) { + console.log(`[DB Sync] Updating table: ${tableName}. Adding columns: ${columnsToAdd.map(c=>c.name).join(', ')}`); + for (const column of columnsToAdd) { + const addColumnQuery = `ALTER TABLE "${tableName}" ADD COLUMN "${column.name}" ${column.type}`; + this.db.prepare(addColumnQuery).run(); + } + } } - async runQuery(query, params = []) { - return new Promise((resolve, reject) => { - this.db.run(query, params, function(err) { - if (err) return reject(err); - resolve(this); - }); - }); + runQuery(query, params = []) { + return this.db.prepare(query).run(params); } - async cleanupEmptySessions() { + cleanupEmptySessions() { console.log('[DB Cleanup] Checking for empty sessions...'); const query = ` SELECT s.id FROM sessions s @@ -124,92 +92,65 @@ class SQLiteClient { WHERE t.id IS NULL AND a.id IS NULL AND su.session_id IS NULL `; - return new Promise((resolve, reject) => { - this.db.all(query, [], (err, rows) => { - if (err) { - console.error('[DB Cleanup] Error finding empty sessions:', err); - return reject(err); - } + const rows = this.db.prepare(query).all(); - if (rows.length === 0) { - console.log('[DB Cleanup] No empty sessions found.'); - return resolve(); - } + if (rows.length === 0) { + console.log('[DB Cleanup] No empty sessions found.'); + return; + } - const idsToDelete = rows.map(r => r.id); - const placeholders = idsToDelete.map(() => '?').join(','); - const deleteQuery = `DELETE FROM sessions WHERE id IN (${placeholders})`; + const idsToDelete = rows.map(r => r.id); + const placeholders = idsToDelete.map(() => '?').join(','); + const deleteQuery = `DELETE FROM sessions WHERE id IN (${placeholders})`; - console.log(`[DB Cleanup] Found ${idsToDelete.length} empty sessions. Deleting...`); - this.db.run(deleteQuery, idsToDelete, function(deleteErr) { - if (deleteErr) { - console.error('[DB Cleanup] Error deleting empty sessions:', deleteErr); - return reject(deleteErr); - } - console.log(`[DB Cleanup] Successfully deleted ${this.changes} empty sessions.`); - resolve(); - }); - }); - }); + console.log(`[DB Cleanup] Found ${idsToDelete.length} empty sessions. Deleting...`); + const result = this.db.prepare(deleteQuery).run(idsToDelete); + console.log(`[DB Cleanup] Successfully deleted ${result.changes} empty sessions.`); } - async initTables() { - await this.synchronizeSchema(); - await this.initDefaultData(); + initTables() { + this.synchronizeSchema(); + this.initDefaultData(); } - async initDefaultData() { - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const initUserQuery = ` - INSERT OR IGNORE INTO users (uid, display_name, email, created_at) - VALUES (?, ?, ?, ?) - `; + initDefaultData() { + const now = Math.floor(Date.now() / 1000); + const initUserQuery = ` + INSERT OR IGNORE INTO users (uid, display_name, email, created_at) + VALUES (?, ?, ?, ?) + `; - this.db.run(initUserQuery, [this.defaultUserId, 'Default User', 'contact@pickle.com', now], (err) => { - if (err) { - console.error('Failed to initialize default user:', err); - return reject(err); - } + this.db.prepare(initUserQuery).run(this.defaultUserId, 'Default User', 'contact@pickle.com', now); - const defaultPresets = [ - ['school', 'School', 'You are a school and lecture assistant. Your goal is to help the user, a student, understand academic material and answer questions.\n\nWhenever a question appears on the user\'s screen or is asked aloud, you provide a direct, step-by-step answer, showing all necessary reasoning or calculations.\n\nIf the user is watching a lecture or working through new material, you offer concise explanations of key concepts and clarify definitions as they come up.', 1], - ['meetings', 'Meetings', 'You are a meeting assistant. Your goal is to help the user capture key information during meetings and follow up effectively.\n\nYou help capture meeting notes, track action items, identify key decisions, and summarize important points discussed during meetings.', 1], - ['sales', 'Sales', 'You are a real-time AI sales assistant, and your goal is to help the user close deals during sales interactions.\n\nYou provide real-time sales support, suggest responses to objections, help identify customer needs, and recommend strategies to advance deals.', 1], - ['recruiting', 'Recruiting', 'You are a recruiting assistant. Your goal is to help the user interview candidates and evaluate talent effectively.\n\nYou help evaluate candidates, suggest interview questions, analyze responses, and provide insights about candidate fit for positions.', 1], - ['customer-support', 'Customer Support', 'You are a customer support assistant. Your goal is to help resolve customer issues efficiently and thoroughly.\n\nYou help diagnose customer problems, suggest solutions, provide step-by-step troubleshooting guidance, and ensure customer satisfaction.', 1], - ]; + const defaultPresets = [ + ['school', 'School', 'You are a school and lecture assistant. Your goal is to help the user, a student, understand academic material and answer questions.\n\nWhenever a question appears on the user\'s screen or is asked aloud, you provide a direct, step-by-step answer, showing all necessary reasoning or calculations.\n\nIf the user is watching a lecture or working through new material, you offer concise explanations of key concepts and clarify definitions as they come up.', 1], + ['meetings', 'Meetings', 'You are a meeting assistant. Your goal is to help the user capture key information during meetings and follow up effectively.\n\nYou help capture meeting notes, track action items, identify key decisions, and summarize important points discussed during meetings.', 1], + ['sales', 'Sales', 'You are a real-time AI sales assistant, and your goal is to help the user close deals during sales interactions.\n\nYou provide real-time sales support, suggest responses to objections, help identify customer needs, and recommend strategies to advance deals.', 1], + ['recruiting', 'Recruiting', 'You are a recruiting assistant. Your goal is to help the user interview candidates and evaluate talent effectively.\n\nYou help evaluate candidates, suggest interview questions, analyze responses, and provide insights about candidate fit for positions.', 1], + ['customer-support', 'Customer Support', 'You are a customer support assistant. Your goal is to help resolve customer issues efficiently and thoroughly.\n\nYou help diagnose customer problems, suggest solutions, provide step-by-step troubleshooting guidance, and ensure customer satisfaction.', 1], + ]; - const stmt = this.db.prepare(` - INSERT OR IGNORE INTO prompt_presets (id, uid, title, prompt, is_default, created_at) - VALUES (?, ?, ?, ?, ?, ?) - `); + const stmt = this.db.prepare(` + INSERT OR IGNORE INTO prompt_presets (id, uid, title, prompt, is_default, created_at) + VALUES (?, ?, ?, ?, ?, ?) + `); - for (const preset of defaultPresets) { - stmt.run(preset[0], this.defaultUserId, preset[1], preset[2], preset[3], now); - } + for (const preset of defaultPresets) { + stmt.run(preset[0], this.defaultUserId, preset[1], preset[2], preset[3], now); + } - stmt.finalize((err) => { - if (err) { - console.error('Failed to finalize preset statement:', err); - return reject(err); - } - console.log('Default data initialized.'); - resolve(); - }); - }); - }); + console.log('Default data initialized.'); } - async markPermissionsAsCompleted() { + markPermissionsAsCompleted() { return this.query( 'INSERT OR REPLACE INTO system_settings (key, value) VALUES (?, ?)', ['permissions_completed', 'true'] ); } - async checkPermissionsCompleted() { - const result = await this.query( + checkPermissionsCompleted() { + const result = this.query( 'SELECT value FROM system_settings WHERE key = ?', ['permissions_completed'] ); @@ -218,43 +159,32 @@ class SQLiteClient { close() { if (this.db) { - this.db.close((err) => { - if (err) { - console.error('SQLite connection close failed:', err); - } else { - console.log('SQLite connection closed.'); - } - }); + try { + this.db.close(); + console.log('SQLite connection closed.'); + } catch (err) { + console.error('SQLite connection close failed:', err); + } this.db = null; } } - async query(sql, params = []) { - return new Promise((resolve, reject) => { - if (!this.db) { - return reject(new Error('Database not connected')); - } + query(sql, params = []) { + if (!this.db) { + throw new Error('Database not connected'); + } + try { if (sql.toUpperCase().startsWith('SELECT')) { - this.db.all(sql, params, (err, rows) => { - if (err) { - console.error('Query error:', err); - reject(err); - } else { - resolve(rows); - } - }); + return this.db.prepare(sql).all(params); } else { - this.db.run(sql, params, function(err) { - if (err) { - console.error('Query error:', err); - reject(err); - } else { - resolve({ changes: this.changes, lastID: this.lastID }); - } - }); + const result = this.db.prepare(sql).run(params); + return { changes: result.changes, lastID: result.lastID }; } - }); + } catch (err) { + console.error('Query error:', err); + throw err; + } } } diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 6c74a0f..f60d83f 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -1,7 +1,6 @@ const { BrowserWindow, globalShortcut, ipcMain, screen, app, shell, desktopCapturer } = require('electron'); const WindowLayoutManager = require('./windowLayoutManager'); const SmoothMovementManager = require('./smoothMovementManager'); -const liquidGlass = require('electron-liquid-glass'); const path = require('node:path'); const fs = require('node:fs'); const os = require('os'); @@ -15,6 +14,7 @@ const fetch = require('node-fetch'); /* ────────────────[ GLASS BYPASS ]─────────────── */ +let liquidGlass; const isLiquidGlassSupported = () => { if (process.platform !== 'darwin') { return false; @@ -23,7 +23,15 @@ const isLiquidGlassSupported = () => { // return majorVersion >= 25; // macOS 26+ (Darwin 25+) return majorVersion >= 26; // See you soon! }; -const shouldUseLiquidGlass = isLiquidGlassSupported(); +let shouldUseLiquidGlass = isLiquidGlassSupported(); +if (shouldUseLiquidGlass) { + try { + liquidGlass = require('electron-liquid-glass'); + } catch (e) { + console.warn('Could not load optional dependency "electron-liquid-glass". The feature will be disabled.'); + shouldUseLiquidGlass = false; + } +} /* ────────────────[ GLASS BYPASS ]─────────────── */ let isContentProtectionOn = true; diff --git a/src/features/ask/repositories/sqlite.repository.js b/src/features/ask/repositories/sqlite.repository.js index a9af8ee..bbab3fb 100644 --- a/src/features/ask/repositories/sqlite.repository.js +++ b/src/features/ask/repositories/sqlite.repository.js @@ -2,31 +2,23 @@ const sqliteClient = require('../../../common/services/sqliteClient'); function addAiMessage({ sessionId, role, content, model = 'gpt-4.1' }) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const messageId = require('crypto').randomUUID(); - const now = Math.floor(Date.now() / 1000); - const query = `INSERT INTO ai_messages (id, session_id, sent_at, role, content, model, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)`; - db.run(query, [messageId, sessionId, now, role, content, model, now], function(err) { - if (err) { - console.error('SQLite: Failed to add AI message:', err); - reject(err); - } - else { - resolve({ id: messageId }); - } - }); - }); + const messageId = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = `INSERT INTO ai_messages (id, session_id, sent_at, role, content, model, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)`; + + try { + db.prepare(query).run(messageId, sessionId, now, role, content, model, now); + return { id: messageId }; + } catch (err) { + console.error('SQLite: Failed to add AI message:', err); + throw err; + } } function getAllAiMessagesBySessionId(sessionId) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = "SELECT * FROM ai_messages WHERE session_id = ? ORDER BY sent_at ASC"; - db.all(query, [sessionId], (err, rows) => { - if (err) reject(err); - else resolve(rows); - }); - }); + const query = "SELECT * FROM ai_messages WHERE session_id = ? ORDER BY sent_at ASC"; + return db.prepare(query).all(sessionId); } module.exports = { diff --git a/src/features/listen/stt/repositories/sqlite.repository.js b/src/features/listen/stt/repositories/sqlite.repository.js index 4de47bd..80c838f 100644 --- a/src/features/listen/stt/repositories/sqlite.repository.js +++ b/src/features/listen/stt/repositories/sqlite.repository.js @@ -2,33 +2,23 @@ const sqliteClient = require('../../../../common/services/sqliteClient'); function addTranscript({ sessionId, speaker, text }) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const transcriptId = require('crypto').randomUUID(); - const now = Math.floor(Date.now() / 1000); - const query = `INSERT INTO transcripts (id, session_id, start_at, speaker, text, created_at) VALUES (?, ?, ?, ?, ?, ?)`; - db.run(query, [transcriptId, sessionId, now, speaker, text, now], function(err) { - if (err) { - console.error('Error adding transcript:', err); - reject(err); - } else { - resolve({ id: transcriptId }); - } - }); - }); + const transcriptId = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = `INSERT INTO transcripts (id, session_id, start_at, speaker, text, created_at) VALUES (?, ?, ?, ?, ?, ?)`; + + try { + db.prepare(query).run(transcriptId, sessionId, now, speaker, text, now); + return { id: transcriptId }; + } catch (err) { + console.error('Error adding transcript:', err); + throw err; + } } function getAllTranscriptsBySessionId(sessionId) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = "SELECT * FROM transcripts WHERE session_id = ? ORDER BY start_at ASC"; - db.all(query, [sessionId], (err, rows) => { - if (err) { - reject(err); - } else { - resolve(rows); - } - }); - }); + const query = "SELECT * FROM transcripts WHERE session_id = ? ORDER BY start_at ASC"; + return db.prepare(query).all(sessionId); } module.exports = { diff --git a/src/features/listen/summary/repositories/sqlite.repository.js b/src/features/listen/summary/repositories/sqlite.repository.js index d7a2266..b365090 100644 --- a/src/features/listen/summary/repositories/sqlite.repository.js +++ b/src/features/listen/summary/repositories/sqlite.repository.js @@ -2,43 +2,33 @@ const sqliteClient = require('../../../../common/services/sqliteClient'); function saveSummary({ sessionId, tldr, text, bullet_json, action_json, model = 'gpt-4.1' }) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const query = ` - INSERT INTO summaries (session_id, generated_at, model, text, tldr, bullet_json, action_json, updated_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(session_id) DO UPDATE SET - generated_at=excluded.generated_at, - model=excluded.model, - text=excluded.text, - tldr=excluded.tldr, - bullet_json=excluded.bullet_json, - action_json=excluded.action_json, - updated_at=excluded.updated_at - `; - db.run(query, [sessionId, now, model, text, tldr, bullet_json, action_json, now], function(err) { - if (err) { - console.error('Error saving summary:', err); - reject(err); - } else { - resolve({ changes: this.changes }); - } - }); - }); + const now = Math.floor(Date.now() / 1000); + const query = ` + INSERT INTO summaries (session_id, generated_at, model, text, tldr, bullet_json, action_json, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(session_id) DO UPDATE SET + generated_at=excluded.generated_at, + model=excluded.model, + text=excluded.text, + tldr=excluded.tldr, + bullet_json=excluded.bullet_json, + action_json=excluded.action_json, + updated_at=excluded.updated_at + `; + + try { + const result = db.prepare(query).run(sessionId, now, model, text, tldr, bullet_json, action_json, now); + return { changes: result.changes }; + } catch (err) { + console.error('Error saving summary:', err); + throw err; + } } function getSummaryBySessionId(sessionId) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = "SELECT * FROM summaries WHERE session_id = ?"; - db.get(query, [sessionId], (err, row) => { - if (err) { - reject(err); - } else { - resolve(row || null); - } - }); - }); + const query = "SELECT * FROM summaries WHERE session_id = ?"; + return db.prepare(query).get(sessionId) || null; } module.exports = { diff --git a/src/features/settings/repositories/sqlite.repository.js b/src/features/settings/repositories/sqlite.repository.js index 82d0c01..6611346 100644 --- a/src/features/settings/repositories/sqlite.repository.js +++ b/src/features/settings/repositories/sqlite.repository.js @@ -2,102 +2,92 @@ const sqliteClient = require('../../../common/services/sqliteClient'); function getPresets(uid) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = ` - SELECT * FROM prompt_presets - WHERE uid = ? OR is_default = 1 - ORDER BY is_default DESC, title ASC - `; - db.all(query, [uid], (err, rows) => { - if (err) { - console.error('SQLite: Failed to get presets:', err); - reject(err); - } else { - resolve(rows || []); - } - }); - }); + const query = ` + SELECT * FROM prompt_presets + WHERE uid = ? OR is_default = 1 + ORDER BY is_default DESC, title ASC + `; + + try { + return db.prepare(query).all(uid) || []; + } catch (err) { + console.error('SQLite: Failed to get presets:', err); + throw err; + } } function getPresetTemplates() { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = ` - SELECT * FROM prompt_presets - WHERE is_default = 1 - ORDER BY title ASC - `; - db.all(query, [], (err, rows) => { - if (err) { - console.error('SQLite: Failed to get preset templates:', err); - reject(err); - } else { - resolve(rows || []); - } - }); - }); + const query = ` + SELECT * FROM prompt_presets + WHERE is_default = 1 + ORDER BY title ASC + `; + + try { + return db.prepare(query).all() || []; + } catch (err) { + console.error('SQLite: Failed to get preset templates:', err); + throw err; + } } function createPreset({ uid, title, prompt }) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const id = require('crypto').randomUUID(); - const now = Math.floor(Date.now() / 1000); - const query = ` - INSERT INTO prompt_presets (id, uid, title, prompt, is_default, created_at, sync_state) - VALUES (?, ?, ?, ?, 0, ?, 'dirty') - `; - db.run(query, [id, uid, title, prompt, now], function(err) { - if (err) { - console.error('SQLite: Failed to create preset:', err); - reject(err); - } else { - resolve({ id }); - } - }); - }); + const id = require('crypto').randomUUID(); + const now = Math.floor(Date.now() / 1000); + const query = ` + INSERT INTO prompt_presets (id, uid, title, prompt, is_default, created_at, sync_state) + VALUES (?, ?, ?, ?, 0, ?, 'dirty') + `; + + try { + db.prepare(query).run(id, uid, title, prompt, now); + return { id }; + } catch (err) { + console.error('SQLite: Failed to create preset:', err); + throw err; + } } function updatePreset(id, { title, prompt }, uid) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const now = Math.floor(Date.now() / 1000); - const query = ` - UPDATE prompt_presets - SET title = ?, prompt = ?, sync_state = 'dirty', updated_at = ? - WHERE id = ? AND uid = ? AND is_default = 0 - `; - db.run(query, [title, prompt, now, id, uid], function(err) { - if (err) { - console.error('SQLite: Failed to update preset:', err); - reject(err); - } else if (this.changes === 0) { - reject(new Error('Preset not found, is default, or permission denied')); - } else { - resolve({ changes: this.changes }); - } - }); - }); + const now = Math.floor(Date.now() / 1000); + const query = ` + UPDATE prompt_presets + SET title = ?, prompt = ?, sync_state = 'dirty', updated_at = ? + WHERE id = ? AND uid = ? AND is_default = 0 + `; + + try { + const result = db.prepare(query).run(title, prompt, now, id, uid); + if (result.changes === 0) { + throw new Error('Preset not found, is default, or permission denied'); + } + return { changes: result.changes }; + } catch (err) { + console.error('SQLite: Failed to update preset:', err); + throw err; + } } function deletePreset(id, uid) { const db = sqliteClient.getDb(); - return new Promise((resolve, reject) => { - const query = ` - DELETE FROM prompt_presets - WHERE id = ? AND uid = ? AND is_default = 0 - `; - db.run(query, [id, uid], function(err) { - if (err) { - console.error('SQLite: Failed to delete preset:', err); - reject(err); - } else if (this.changes === 0) { - reject(new Error('Preset not found, is default, or permission denied')); - } else { - resolve({ changes: this.changes }); - } - }); - }); + const query = ` + DELETE FROM prompt_presets + WHERE id = ? AND uid = ? AND is_default = 0 + `; + + try { + const result = db.prepare(query).run(id, uid); + if (result.changes === 0) { + throw new Error('Preset not found, is default, or permission denied'); + } + return { changes: result.changes }; + } catch (err) { + console.error('SQLite: Failed to delete preset:', err); + throw err; + } } module.exports = { diff --git a/src/index.js b/src/index.js index eb6e89c..a2d8e4d 100644 --- a/src/index.js +++ b/src/index.js @@ -18,7 +18,6 @@ const { initializeFirebase } = require('./common/services/firebaseClient'); const databaseInitializer = require('./common/services/databaseInitializer'); const authService = require('./common/services/authService'); const path = require('node:path'); -const { Deeplink } = require('electron-deeplink'); const express = require('express'); const fetch = require('node-fetch'); const { autoUpdater } = require('electron-updater'); @@ -33,72 +32,86 @@ let WEB_PORT = 3000; const listenService = new ListenService(); // Make listenService globally accessible so other modules (e.g., windowManager, askService) can reuse the same instance global.listenService = listenService; -let deeplink = null; // Initialize as null -let pendingDeepLinkUrl = null; // Store any deep link that arrives before initialization -function createMainWindows() { - createWindows(); +// Native deep link handling - cross-platform compatible +let pendingDeepLinkUrl = null; - const { windowPool } = require('./electron/windowManager'); - const headerWindow = windowPool.get('header'); - - // Initialize deeplink after windows are created - if (!deeplink && headerWindow) { - try { - deeplink = new Deeplink({ - app, - mainWindow: headerWindow, - protocol: 'pickleglass', - isDev: !app.isPackaged, - debugLogging: true - }); - - deeplink.on('received', (url) => { - console.log('[deeplink] received:', url); - handleCustomUrl(url); - }); - - console.log('[deeplink] Initialized with main window'); - - // Handle any pending deep link - if (pendingDeepLinkUrl) { - console.log('[deeplink] Processing pending deep link:', pendingDeepLinkUrl); - handleCustomUrl(pendingDeepLinkUrl); - pendingDeepLinkUrl = null; - } - } catch (error) { - console.error('[deeplink] Failed to initialize deep link:', error); - deeplink = null; - } +function setupProtocolHandling() { + // Protocol registration - must be done before app is ready + if (!app.isDefaultProtocolClient('pickleglass')) { + app.setAsDefaultProtocolClient('pickleglass'); + console.log('[Protocol] Set as default protocol client for pickleglass://'); } + + // Handle protocol URLs on Windows/Linux + app.on('second-instance', (event, commandLine, workingDirectory) => { + // Focus existing window first + focusMainWindow(); + + // Look for protocol URL in command line arguments + const protocolUrl = commandLine.find(arg => arg.startsWith('pickleglass://')); + if (protocolUrl) { + console.log('[Protocol] Received URL from second instance:', protocolUrl); + handleCustomUrl(protocolUrl); + } + }); + + // Handle protocol URLs on macOS + app.on('open-url', (event, url) => { + event.preventDefault(); + console.log('[Protocol] Received URL via open-url:', url); + + if (!url || !url.startsWith('pickleglass://')) { + console.warn('[Protocol] Invalid URL format:', url); + return; + } + + if (app.isReady()) { + handleCustomUrl(url); + } else { + pendingDeepLinkUrl = url; + console.log('[Protocol] App not ready, storing URL for later'); + } + }); } +function focusMainWindow() { + const { windowPool } = require('./electron/windowManager'); + if (windowPool) { + const header = windowPool.get('header'); + if (header && !header.isDestroyed()) { + if (header.isMinimized()) header.restore(); + header.focus(); + return true; + } + } + + // Fallback: focus any available window + const windows = BrowserWindow.getAllWindows(); + if (windows.length > 0) { + const mainWindow = windows[0]; + if (!mainWindow.isDestroyed()) { + if (mainWindow.isMinimized()) mainWindow.restore(); + mainWindow.focus(); + return true; + } + } + + return false; +} + +// Setup protocol handling before app.whenReady() +setupProtocolHandling(); + app.whenReady().then(async () => { + // Single instance lock - must be first const gotTheLock = app.requestSingleInstanceLock(); if (!gotTheLock) { app.quit(); return; - } else { - app.on('second-instance', (event, commandLine, workingDirectory) => { - const { windowPool } = require('./electron/windowManager'); - if (windowPool) { - const header = windowPool.get('header'); - if (header) { - if (header.isMinimized()) header.restore(); - header.focus(); - return; - } - } - - const windows = BrowserWindow.getAllWindows(); - if (windows.length > 0) { - const mainWindow = windows[0]; - if (mainWindow.isMinimized()) mainWindow.restore(); - mainWindow.focus(); - } - }); } + // Initialize core services initializeFirebase(); databaseInitializer.initialize() @@ -121,9 +134,16 @@ app.whenReady().then(async () => { WEB_PORT = await startWebStack(); console.log('Web front-end listening on', WEB_PORT); - createMainWindows(); + createWindows(); initAutoUpdater(); + + // Process any pending deep link after everything is initialized + if (pendingDeepLinkUrl) { + console.log('[Protocol] Processing pending URL:', pendingDeepLinkUrl); + handleCustomUrl(pendingDeepLinkUrl); + pendingDeepLinkUrl = null; + } }); app.on('window-all-closed', () => { @@ -142,34 +162,17 @@ app.on('before-quit', async () => { app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { - createMainWindows(); + createWindows(); } }); -// Add macOS native deep link handling as fallback -app.on('open-url', (event, url) => { - event.preventDefault(); - console.log('[app] open-url received:', url); - - if (!deeplink) { - // Store the URL if deeplink isn't ready yet - pendingDeepLinkUrl = url; - console.log('[app] Deep link stored for later processing'); - } else { - handleCustomUrl(url); - } -}); - -// Ensure app can handle the protocol -app.setAsDefaultProtocolClient('pickleglass'); - function setupGeneralIpcHandlers() { const userRepository = require('./common/repositories/user'); const presetRepository = require('./common/repositories/preset'); - ipcMain.handle('save-api-key', async (event, apiKey) => { + ipcMain.handle('save-api-key', (event, apiKey) => { try { - await userRepository.saveApiKey(apiKey, authService.getCurrentUserId()); + userRepository.saveApiKey(apiKey, authService.getCurrentUserId()); BrowserWindow.getAllWindows().forEach(win => { win.webContents.send('api-key-updated'); }); @@ -180,12 +183,12 @@ function setupGeneralIpcHandlers() { } }); - ipcMain.handle('get-user-presets', async () => { - return await presetRepository.getPresets(authService.getCurrentUserId()); + ipcMain.handle('get-user-presets', () => { + return presetRepository.getPresets(authService.getCurrentUserId()); }); - ipcMain.handle('get-preset-templates', async () => { - return await presetRepository.getPresetTemplates(); + ipcMain.handle('get-preset-templates', () => { + return presetRepository.getPresetTemplates(); }); ipcMain.handle('start-firebase-auth', async () => { @@ -204,7 +207,7 @@ function setupGeneralIpcHandlers() { return process.env.pickleglass_WEB_URL || 'http://localhost:3000'; }); - ipcMain.handle('get-current-user', async () => { + ipcMain.handle('get-current-user', () => { return authService.getCurrentUser(); }); @@ -220,72 +223,72 @@ function setupWebDataHandlers() { const userRepository = require('./common/repositories/user'); const presetRepository = require('./common/repositories/preset'); - const handleRequest = async (channel, responseChannel, payload) => { + const handleRequest = (channel, responseChannel, payload) => { let result; const currentUserId = authService.getCurrentUserId(); try { switch (channel) { // SESSION case 'get-sessions': - result = await sessionRepository.getAllByUserId(currentUserId); + result = sessionRepository.getAllByUserId(currentUserId); break; case 'get-session-details': - const session = await sessionRepository.getById(payload); + const session = sessionRepository.getById(payload); if (!session) { result = null; break; } - const transcripts = await sttRepository.getAllTranscriptsBySessionId(payload); - const ai_messages = await askRepository.getAllAiMessagesBySessionId(payload); - const summary = await summaryRepository.getSummaryBySessionId(payload); + const transcripts = sttRepository.getAllTranscriptsBySessionId(payload); + const ai_messages = askRepository.getAllAiMessagesBySessionId(payload); + const summary = summaryRepository.getSummaryBySessionId(payload); result = { session, transcripts, ai_messages, summary }; break; case 'delete-session': - result = await sessionRepository.deleteWithRelatedData(payload); + result = sessionRepository.deleteWithRelatedData(payload); break; case 'create-session': - const id = await sessionRepository.create(currentUserId, 'ask'); + const id = sessionRepository.create(currentUserId, 'ask'); if (payload.title) { - await sessionRepository.updateTitle(id, payload.title); + sessionRepository.updateTitle(id, payload.title); } result = { id }; break; // USER case 'get-user-profile': - result = await userRepository.getById(currentUserId); + result = userRepository.getById(currentUserId); break; case 'update-user-profile': - result = await userRepository.update({ uid: currentUserId, ...payload }); + result = userRepository.update({ uid: currentUserId, ...payload }); break; case 'find-or-create-user': - result = await userRepository.findOrCreate(payload); + result = userRepository.findOrCreate(payload); break; case 'save-api-key': - result = await userRepository.saveApiKey(payload, currentUserId); + result = userRepository.saveApiKey(payload, currentUserId); break; case 'check-api-key-status': - const user = await userRepository.getById(currentUserId); + const user = userRepository.getById(currentUserId); result = { hasApiKey: !!user?.api_key && user.api_key.length > 0 }; break; case 'delete-account': - result = await userRepository.deleteById(currentUserId); + result = userRepository.deleteById(currentUserId); break; // PRESET case 'get-presets': - result = await presetRepository.getPresets(currentUserId); + result = presetRepository.getPresets(currentUserId); break; case 'create-preset': - result = await presetRepository.create({ ...payload, uid: currentUserId }); + result = presetRepository.create({ ...payload, uid: currentUserId }); settingsService.notifyPresetUpdate('created', result.id, payload.title); break; case 'update-preset': - result = await presetRepository.update(payload.id, payload.data, currentUserId); + result = presetRepository.update(payload.id, payload.data, currentUserId); settingsService.notifyPresetUpdate('updated', payload.id, payload.data.title); break; case 'delete-preset': - result = await presetRepository.delete(payload, currentUserId); + result = presetRepository.delete(payload, currentUserId); settingsService.notifyPresetUpdate('deleted', payload); break; @@ -295,13 +298,13 @@ function setupWebDataHandlers() { const batchResult = {}; if (includes.includes('profile')) { - batchResult.profile = await userRepository.getById(currentUserId); + batchResult.profile = userRepository.getById(currentUserId); } if (includes.includes('presets')) { - batchResult.presets = await presetRepository.getPresets(currentUserId); + batchResult.presets = presetRepository.getPresets(currentUserId); } if (includes.includes('sessions')) { - batchResult.sessions = await sessionRepository.getAllByUserId(currentUserId); + batchResult.sessions = sessionRepository.getAllByUserId(currentUserId); } result = batchResult; break; @@ -392,7 +395,7 @@ async function handleFirebaseAuthCallback(params) { }; // 1. Sync user data to local DB - await userRepository.findOrCreate(firebaseUser); + userRepository.findOrCreate(firebaseUser); console.log('[Auth] User data synced with local DB.'); // 2. Sign in using the authService in the main process From 995d4d014e4eea6ecd3b1007869977a2457a3bc7 Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Mon, 7 Jul 2025 16:59:46 +0900 Subject: [PATCH 17/52] fix method for windows --- src/electron/windowManager.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index f60d83f..a069099 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -91,7 +91,9 @@ function createFeatureWindows(header) { }); listen.setContentProtection(isContentProtectionOn); listen.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - listen.setWindowButtonVisibility(false); + if (process.platform === 'darwin') { + listen.setWindowButtonVisibility(false); + } const listenLoadOptions = { query: { view: 'listen' } }; if (!shouldUseLiquidGlass) { listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); @@ -120,7 +122,9 @@ function createFeatureWindows(header) { const ask = new BrowserWindow({ ...commonChildOptions, width:600 }); ask.setContentProtection(isContentProtectionOn); ask.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - ask.setWindowButtonVisibility(false); + if (process.platform === 'darwin') { + ask.setWindowButtonVisibility(false); + } const askLoadOptions = { query: { view: 'ask' } }; if (!shouldUseLiquidGlass) { ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); @@ -154,7 +158,9 @@ function createFeatureWindows(header) { const settings = new BrowserWindow({ ...commonChildOptions, width:240, maxHeight:400, parent:undefined }); settings.setContentProtection(isContentProtectionOn); settings.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - settings.setWindowButtonVisibility(false); + if (process.platform === 'darwin') { + settings.setWindowButtonVisibility(false); + } const settingsLoadOptions = { query: { view: 'settings' } }; if (!shouldUseLiquidGlass) { settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) @@ -315,7 +321,9 @@ function createWindows() { webSecurity: false, }, }); - header.setWindowButtonVisibility(false); + if (process.platform === 'darwin') { + header.setWindowButtonVisibility(false); + } const headerLoadOptions = {}; if (!shouldUseLiquidGlass) { header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions); From d2ca68b177d176fd2d381e11c4d7e3af623bf561 Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Mon, 7 Jul 2025 18:04:46 +0900 Subject: [PATCH 18/52] fix winodws deeplink pharse --- src/index.js | 77 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/src/index.js b/src/index.js index a2d8e4d..700e7b2 100644 --- a/src/index.js +++ b/src/index.js @@ -38,21 +38,43 @@ let pendingDeepLinkUrl = null; function setupProtocolHandling() { // Protocol registration - must be done before app is ready - if (!app.isDefaultProtocolClient('pickleglass')) { - app.setAsDefaultProtocolClient('pickleglass'); - console.log('[Protocol] Set as default protocol client for pickleglass://'); + try { + if (!app.isDefaultProtocolClient('pickleglass')) { + const success = app.setAsDefaultProtocolClient('pickleglass'); + if (success) { + console.log('[Protocol] Successfully set as default protocol client for pickleglass://'); + } else { + console.warn('[Protocol] Failed to set as default protocol client - this may affect deep linking'); + } + } else { + console.log('[Protocol] Already registered as default protocol client for pickleglass://'); + } + } catch (error) { + console.error('[Protocol] Error during protocol registration:', error); } // Handle protocol URLs on Windows/Linux app.on('second-instance', (event, commandLine, workingDirectory) => { + console.log('[Protocol] Second instance command line:', commandLine); + // Focus existing window first focusMainWindow(); - // Look for protocol URL in command line arguments - const protocolUrl = commandLine.find(arg => arg.startsWith('pickleglass://')); + // Look for protocol URL in command line arguments - filter out invalid paths + const protocolUrl = commandLine.find(arg => { + return arg && + typeof arg === 'string' && + arg.startsWith('pickleglass://') && + arg.includes('://') && + !arg.includes('\\') && // Exclude Windows paths + !arg.includes('₩'); // Exclude corrupted characters + }); + if (protocolUrl) { - console.log('[Protocol] Received URL from second instance:', protocolUrl); + console.log('[Protocol] Valid URL found from second instance:', protocolUrl); handleCustomUrl(protocolUrl); + } else { + console.log('[Protocol] No valid protocol URL found in command line arguments'); } }); @@ -100,16 +122,31 @@ function focusMainWindow() { return false; } -// Setup protocol handling before app.whenReady() +if (process.platform === 'win32') { + const protocolArg = process.argv.find(arg => + arg && + typeof arg === 'string' && + arg.startsWith('pickleglass://') && + !arg.includes('\\') && + !arg.includes('₩') + ); + + if (protocolArg) { + console.log('[Protocol] Found protocol URL in initial arguments:', protocolArg); + pendingDeepLinkUrl = protocolArg; + } +} + +const gotTheLock = app.requestSingleInstanceLock(); +if (!gotTheLock) { + app.quit(); + process.exit(0); +} + +// setup protocol after single instance lock setupProtocolHandling(); app.whenReady().then(async () => { - // Single instance lock - must be first - const gotTheLock = app.requestSingleInstanceLock(); - if (!gotTheLock) { - app.quit(); - return; - } // Initialize core services initializeFirebase(); @@ -118,7 +155,7 @@ app.whenReady().then(async () => { .then(() => { console.log('>>> [index.js] Database initialized successfully'); - // Clean up any zombie sessions from previous runs first + // Clean up zombie sessions from previous runs first sessionRepository.endAllActiveSessions(); authService.initialize(); @@ -326,6 +363,18 @@ async function handleCustomUrl(url) { try { console.log('[Custom URL] Processing URL:', url); + // val url + if (!url || typeof url !== 'string' || !url.startsWith('pickleglass://')) { + console.error('[Custom URL] Invalid URL format:', url); + return; + } + + // val url + if (url.includes('\\') || url.includes('₩')) { + console.error('[Custom URL] URL contains invalid path characters:', url); + return; + } + const urlObj = new URL(url); const action = urlObj.hostname; const params = Object.fromEntries(urlObj.searchParams); From a089a5f98beba1ca60b02703985c15855436e889 Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Mon, 7 Jul 2025 18:39:24 +0900 Subject: [PATCH 19/52] fix windows --- src/index.js | 55 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/index.js b/src/index.js index 700e7b2..e943a55 100644 --- a/src/index.js +++ b/src/index.js @@ -57,24 +57,36 @@ function setupProtocolHandling() { app.on('second-instance', (event, commandLine, workingDirectory) => { console.log('[Protocol] Second instance command line:', commandLine); - // Focus existing window first focusMainWindow(); - // Look for protocol URL in command line arguments - filter out invalid paths - const protocolUrl = commandLine.find(arg => { - return arg && - typeof arg === 'string' && - arg.startsWith('pickleglass://') && - arg.includes('://') && - !arg.includes('\\') && // Exclude Windows paths - !arg.includes('₩'); // Exclude corrupted characters - }); + let protocolUrl = null; + + if (process.platform === 'win32') { + // Windows + const lastArg = commandLine.length > 0 ? commandLine[commandLine.length - 1] : null; + if (lastArg && + typeof lastArg === 'string' && + lastArg.startsWith('pickleglass://') && + !lastArg.includes('\\') && + !lastArg.includes('₩')) { + protocolUrl = lastArg; + } + } else { + // Linux or etc + const lastArg = commandLine.length > 0 ? commandLine[commandLine.length - 1] : null; + if (lastArg && + typeof lastArg === 'string' && + lastArg.startsWith('pickleglass://')) { + protocolUrl = lastArg; + } + } if (protocolUrl) { - console.log('[Protocol] Valid URL found from second instance:', protocolUrl); + console.log('[Protocol] Valid URL found from second instance (last arg):', protocolUrl); handleCustomUrl(protocolUrl); } else { console.log('[Protocol] No valid protocol URL found in command line arguments'); + console.log('[Protocol] Command line args:', commandLine); } }); @@ -123,18 +135,19 @@ function focusMainWindow() { } if (process.platform === 'win32') { - const protocolArg = process.argv.find(arg => - arg && - typeof arg === 'string' && - arg.startsWith('pickleglass://') && - !arg.includes('\\') && - !arg.includes('₩') - ); + const lastArg = process.argv.length > 0 ? process.argv[process.argv.length - 1] : null; - if (protocolArg) { - console.log('[Protocol] Found protocol URL in initial arguments:', protocolArg); - pendingDeepLinkUrl = protocolArg; + if (lastArg && + typeof lastArg === 'string' && + lastArg.startsWith('pickleglass://') && + !lastArg.includes('\\') && + !lastArg.includes('₩')) { + + console.log('[Protocol] Found protocol URL in initial arguments (last arg):', lastArg); + pendingDeepLinkUrl = lastArg; } + + console.log('[Protocol] Initial process.argv:', process.argv); } const gotTheLock = app.requestSingleInstanceLock(); From 4c02969e93a4a2a78f742a6353d7efad1627c7b2 Mon Sep 17 00:00:00 2001 From: Aditya U Date: Mon, 7 Jul 2025 16:06:59 +0530 Subject: [PATCH 20/52] fix(gemini): correct streaming implementation and request format --- src/common/ai/providers/gemini.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/common/ai/providers/gemini.js b/src/common/ai/providers/gemini.js index a2284a1..c3c4743 100644 --- a/src/common/ai/providers/gemini.js +++ b/src/common/ai/providers/gemini.js @@ -262,7 +262,27 @@ function createStreamingLLM({ apiKey, model = 'gemini-2.5-flash', temperature = let chunkCount = 0; let totalContent = ''; - for await (const chunk of chat.sendMessageStream(geminiContent)) { + const contentParts = geminiContent.map(part => { + if (typeof part === 'string') { + return { text: part }; + } else if (part.inlineData) { + return { inlineData: part.inlineData }; + } + return part; + }); + + const result = await geminiModel.generateContentStream({ + contents: [{ + role: 'user', + parts: contentParts + }], + generationConfig: { + temperature, + maxOutputTokens: maxTokens || 8192, + } + }); + + for await (const chunk of result.stream) { chunkCount++; const chunkText = chunk.text() || ''; totalContent += chunkText; @@ -307,4 +327,4 @@ module.exports = { createSTT, createLLM, createStreamingLLM -}; \ No newline at end of file +}; From 17b10b1ad0bc5d3bff34dcc48b4ccc84cdae49bd Mon Sep 17 00:00:00 2001 From: Surya Date: Mon, 7 Jul 2025 16:23:30 +0530 Subject: [PATCH 21/52] Feature:Anthropic AI Integration --- package.json | 1 + src/app/ApiKeyHeader.js | 609 ++++++++++++++------------- src/common/ai/factory.js | 37 +- src/common/ai/providers/anthropic.js | 280 ++++++++++++ src/electron/windowManager.js | 47 ++- 5 files changed, 656 insertions(+), 318 deletions(-) create mode 100644 src/common/ai/providers/anthropic.js diff --git a/package.json b/package.json index 3a6f218..2bdaca8 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ }, "license": "GPL-3.0", "dependencies": { + "@anthropic-ai/sdk": "^0.56.0", "@google/genai": "^1.8.0", "@google/generative-ai": "^0.24.1", "axios": "^1.10.0", diff --git a/src/app/ApiKeyHeader.js b/src/app/ApiKeyHeader.js index 39598bd..25f1571 100644 --- a/src/app/ApiKeyHeader.js +++ b/src/app/ApiKeyHeader.js @@ -1,14 +1,14 @@ -import { html, css, LitElement } from '../assets/lit-core-2.7.4.min.js'; +import { html, css, LitElement } from "../assets/lit-core-2.7.4.min.js" export class ApiKeyHeader extends LitElement { - static properties = { - apiKey: { type: String }, - isLoading: { type: Boolean }, - errorMessage: { type: String }, - selectedProvider: { type: String }, - }; + static properties = { + apiKey: { type: String }, + isLoading: { type: Boolean }, + errorMessage: { type: String }, + selectedProvider: { type: String }, + } - static styles = css` + static styles = css` :host { display: block; transform: translate3d(0, 0, 0); @@ -272,304 +272,336 @@ export class ApiKeyHeader extends LitElement { :host-context(body.has-glass) .close-button:hover { background: transparent !important; } - `; + ` - constructor() { - super(); - this.dragState = null; - this.wasJustDragged = false; - this.apiKey = ''; - this.isLoading = false; - this.errorMessage = ''; - this.validatedApiKey = null; - this.selectedProvider = 'openai'; + constructor() { + super() + this.dragState = null + this.wasJustDragged = false + this.apiKey = "" + this.isLoading = false + this.errorMessage = "" + this.validatedApiKey = null + this.selectedProvider = "openai" - this.handleMouseMove = this.handleMouseMove.bind(this); - this.handleMouseUp = this.handleMouseUp.bind(this); - this.handleKeyPress = this.handleKeyPress.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); - this.handleInput = this.handleInput.bind(this); - this.handleAnimationEnd = this.handleAnimationEnd.bind(this); - this.handleUsePicklesKey = this.handleUsePicklesKey.bind(this); - this.handleProviderChange = this.handleProviderChange.bind(this); + this.handleMouseMove = this.handleMouseMove.bind(this) + this.handleMouseUp = this.handleMouseUp.bind(this) + this.handleKeyPress = this.handleKeyPress.bind(this) + this.handleSubmit = this.handleSubmit.bind(this) + this.handleInput = this.handleInput.bind(this) + this.handleAnimationEnd = this.handleAnimationEnd.bind(this) + this.handleUsePicklesKey = this.handleUsePicklesKey.bind(this) + this.handleProviderChange = this.handleProviderChange.bind(this) + } + + reset() { + this.apiKey = "" + this.isLoading = false + this.errorMessage = "" + this.validatedApiKey = null + this.selectedProvider = "openai" + this.requestUpdate() + } + + async handleMouseDown(e) { + if (e.target.tagName === "INPUT" || e.target.tagName === "BUTTON" || e.target.tagName === "SELECT") { + return } - reset() { - this.apiKey = ''; - this.isLoading = false; - this.errorMessage = ''; - this.validatedApiKey = null; - this.selectedProvider = 'openai'; - this.requestUpdate(); + e.preventDefault() + + const { ipcRenderer } = window.require("electron") + const initialPosition = await ipcRenderer.invoke("get-header-position") + + this.dragState = { + initialMouseX: e.screenX, + initialMouseY: e.screenY, + initialWindowX: initialPosition.x, + initialWindowY: initialPosition.y, + moved: false, } - async handleMouseDown(e) { - if (e.target.tagName === 'INPUT' || e.target.tagName === 'BUTTON' || e.target.tagName === 'SELECT') { - return; + window.addEventListener("mousemove", this.handleMouseMove) + window.addEventListener("mouseup", this.handleMouseUp, { once: true }) + } + + handleMouseMove(e) { + if (!this.dragState) return + + const deltaX = Math.abs(e.screenX - this.dragState.initialMouseX) + const deltaY = Math.abs(e.screenY - this.dragState.initialMouseY) + + if (deltaX > 3 || deltaY > 3) { + this.dragState.moved = true + } + + const newWindowX = this.dragState.initialWindowX + (e.screenX - this.dragState.initialMouseX) + const newWindowY = this.dragState.initialWindowY + (e.screenY - this.dragState.initialMouseY) + + const { ipcRenderer } = window.require("electron") + ipcRenderer.invoke("move-header-to", newWindowX, newWindowY) + } + + handleMouseUp(e) { + if (!this.dragState) return + + const wasDragged = this.dragState.moved + + window.removeEventListener("mousemove", this.handleMouseMove) + this.dragState = null + + if (wasDragged) { + this.wasJustDragged = true + setTimeout(() => { + this.wasJustDragged = false + }, 200) + } + } + + handleInput(e) { + this.apiKey = e.target.value + this.errorMessage = "" + console.log("Input changed:", this.apiKey?.length || 0, "chars") + + this.requestUpdate() + this.updateComplete.then(() => { + const inputField = this.shadowRoot?.querySelector(".apikey-input") + if (inputField && this.isInputFocused) { + inputField.focus() + } + }) + } + + handleProviderChange(e) { + this.selectedProvider = e.target.value + this.errorMessage = "" + console.log("Provider changed to:", this.selectedProvider) + this.requestUpdate() + } + + handlePaste(e) { + e.preventDefault() + this.errorMessage = "" + const clipboardText = (e.clipboardData || window.clipboardData).getData("text") + console.log("Paste event detected:", clipboardText?.substring(0, 10) + "...") + + if (clipboardText) { + this.apiKey = clipboardText.trim() + + const inputElement = e.target + inputElement.value = this.apiKey + } + + this.requestUpdate() + this.updateComplete.then(() => { + const inputField = this.shadowRoot?.querySelector(".apikey-input") + if (inputField) { + inputField.focus() + inputField.setSelectionRange(inputField.value.length, inputField.value.length) + } + }) + } + + handleKeyPress(e) { + if (e.key === "Enter") { + e.preventDefault() + this.handleSubmit() + } + } + + async handleSubmit() { + if (this.wasJustDragged || this.isLoading || !this.apiKey.trim()) { + console.log("Submit blocked:", { + wasJustDragged: this.wasJustDragged, + isLoading: this.isLoading, + hasApiKey: !!this.apiKey.trim(), + }) + return + } + + console.log("Starting API key validation...") + this.isLoading = true + this.errorMessage = "" + this.requestUpdate() + + const apiKey = this.apiKey.trim() + const isValid = false + try { + const isValid = await this.validateApiKey(this.apiKey.trim(), this.selectedProvider) + + if (isValid) { + console.log("API key valid - starting slide out animation") + this.startSlideOutAnimation() + this.validatedApiKey = this.apiKey.trim() + this.validatedProvider = this.selectedProvider + } else { + this.errorMessage = "Invalid API key - please check and try again" + console.log("API key validation failed") + } + } catch (error) { + console.error("API key validation error:", error) + this.errorMessage = "Validation error - please try again" + } finally { + this.isLoading = false + this.requestUpdate() + } + } + + async validateApiKey(apiKey, provider = "openai") { + if (!apiKey || apiKey.length < 15) return false + + if (provider === "openai") { + if (!apiKey.match(/^[A-Za-z0-9_-]+$/)) return false + + try { + console.log("Validating OpenAI API key...") + + const response = await fetch("https://api.openai.com/v1/models", { + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${apiKey}`, + }, + }) + + if (response.ok) { + const data = await response.json() + + const hasGPTModels = data.data && data.data.some((m) => m.id.startsWith("gpt-")) + if (hasGPTModels) { + console.log("OpenAI API key validation successful") + return true + } else { + console.log("API key valid but no GPT models available") + return false + } + } else { + const errorData = await response.json().catch(() => ({})) + console.log("API key validation failed:", response.status, errorData.error?.message || "Unknown error") + return false + } + } catch (error) { + console.error("API key validation network error:", error) + return apiKey.length >= 20 // Fallback for network issues + } + } else if (provider === "gemini") { + // Gemini API keys typically start with 'AIza' + if (!apiKey.match(/^[A-Za-z0-9_-]+$/)) return false + + try { + console.log("Validating Gemini API key...") + + // Test the API key with a simple models list request + const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`) + + if (response.ok) { + const data = await response.json() + if (data.models && data.models.length > 0) { + console.log("Gemini API key validation successful") + return true + } } - e.preventDefault(); + console.log("Gemini API key validation failed") + return false + } catch (error) { + console.error("Gemini API key validation network error:", error) + return apiKey.length >= 20 // Fallback + } + } else if (provider === "anthropic") { + // Anthropic API keys typically start with 'sk-ant-' + if (!apiKey.startsWith("sk-ant-") || !apiKey.match(/^[A-Za-z0-9_-]+$/)) return false - const { ipcRenderer } = window.require('electron'); - const initialPosition = await ipcRenderer.invoke('get-header-position'); + try { + console.log("Validating Anthropic API key...") - this.dragState = { - initialMouseX: e.screenX, - initialMouseY: e.screenY, - initialWindowX: initialPosition.x, - initialWindowY: initialPosition.y, - moved: false, - }; + // Test the API key with a simple request + const response = await fetch("https://api.anthropic.com/v1/messages", { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-api-key": apiKey, + "anthropic-version": "2023-06-01", + }, + body: JSON.stringify({ + model: "claude-3-haiku-20240307", + max_tokens: 10, + messages: [{ role: "user", content: "Hi" }], + }), + }) - window.addEventListener('mousemove', this.handleMouseMove); - window.addEventListener('mouseup', this.handleMouseUp, { once: true }); - } - - handleMouseMove(e) { - if (!this.dragState) return; - - const deltaX = Math.abs(e.screenX - this.dragState.initialMouseX); - const deltaY = Math.abs(e.screenY - this.dragState.initialMouseY); - - if (deltaX > 3 || deltaY > 3) { - this.dragState.moved = true; + if (response.ok || response.status === 400) { + // 400 is also acceptable as it means the API key is valid but request format might be wrong + console.log("Anthropic API key validation successful") + return true } - const newWindowX = this.dragState.initialWindowX + (e.screenX - this.dragState.initialMouseX); - const newWindowY = this.dragState.initialWindowY + (e.screenY - this.dragState.initialMouseY); - - const { ipcRenderer } = window.require('electron'); - ipcRenderer.invoke('move-header-to', newWindowX, newWindowY); + console.log("Anthropic API key validation failed:", response.status) + return false + } catch (error) { + console.error("Anthropic API key validation network error:", error) + return apiKey.length >= 20 // Fallback + } } - handleMouseUp(e) { - if (!this.dragState) return; + return false + } - const wasDragged = this.dragState.moved; + startSlideOutAnimation() { + this.classList.add("sliding-out") + } - window.removeEventListener('mousemove', this.handleMouseMove); - this.dragState = null; + handleUsePicklesKey(e) { + e.preventDefault() + if (this.wasJustDragged) return - if (wasDragged) { - this.wasJustDragged = true; - setTimeout(() => { - this.wasJustDragged = false; - }, 200); - } + console.log("Requesting Firebase authentication from main process...") + if (window.require) { + window.require("electron").ipcRenderer.invoke("start-firebase-auth") } + } - handleInput(e) { - this.apiKey = e.target.value; - this.errorMessage = ''; - console.log('Input changed:', this.apiKey?.length || 0, 'chars'); - - this.requestUpdate(); - this.updateComplete.then(() => { - const inputField = this.shadowRoot?.querySelector('.apikey-input'); - if (inputField && this.isInputFocused) { - inputField.focus(); - } - }); + handleClose() { + console.log("Close button clicked") + if (window.require) { + window.require("electron").ipcRenderer.invoke("quit-application") } + } - handleProviderChange(e) { - this.selectedProvider = e.target.value; - this.errorMessage = ''; - console.log('Provider changed to:', this.selectedProvider); - this.requestUpdate(); - } + handleAnimationEnd(e) { + if (e.target !== this) return - handlePaste(e) { - e.preventDefault(); - this.errorMessage = ''; - const clipboardText = (e.clipboardData || window.clipboardData).getData('text'); - console.log('Paste event detected:', clipboardText?.substring(0, 10) + '...'); + if (this.classList.contains("sliding-out")) { + this.classList.remove("sliding-out") + this.classList.add("hidden") - if (clipboardText) { - this.apiKey = clipboardText.trim(); - - const inputElement = e.target; - inputElement.value = this.apiKey; - } - - this.requestUpdate(); - this.updateComplete.then(() => { - const inputField = this.shadowRoot?.querySelector('.apikey-input'); - if (inputField) { - inputField.focus(); - inputField.setSelectionRange(inputField.value.length, inputField.value.length); - } - }); - } - - handleKeyPress(e) { - if (e.key === 'Enter') { - e.preventDefault(); - this.handleSubmit(); - } - } - - async handleSubmit() { - if (this.wasJustDragged || this.isLoading || !this.apiKey.trim()) { - console.log('Submit blocked:', { - wasJustDragged: this.wasJustDragged, - isLoading: this.isLoading, - hasApiKey: !!this.apiKey.trim(), - }); - return; - } - - console.log('Starting API key validation...'); - this.isLoading = true; - this.errorMessage = ''; - this.requestUpdate(); - - const apiKey = this.apiKey.trim(); - let isValid = false; - try { - const isValid = await this.validateApiKey(this.apiKey.trim(), this.selectedProvider); - - if (isValid) { - console.log('API key valid - starting slide out animation'); - this.startSlideOutAnimation(); - this.validatedApiKey = this.apiKey.trim(); - this.validatedProvider = this.selectedProvider; - } else { - this.errorMessage = 'Invalid API key - please check and try again'; - console.log('API key validation failed'); - } - } catch (error) { - console.error('API key validation error:', error); - this.errorMessage = 'Validation error - please try again'; - } finally { - this.isLoading = false; - this.requestUpdate(); - } - } - - async validateApiKey(apiKey, provider = 'openai') { - if (!apiKey || apiKey.length < 15) return false; - - if (provider === 'openai') { - if (!apiKey.match(/^[A-Za-z0-9_-]+$/)) return false; - - try { - console.log('Validating OpenAI API key...'); - - const response = await fetch('https://api.openai.com/v1/models', { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${apiKey}`, - }, - }); - - if (response.ok) { - const data = await response.json(); - - const hasGPTModels = data.data && data.data.some(m => m.id.startsWith('gpt-')); - if (hasGPTModels) { - console.log('OpenAI API key validation successful'); - return true; - } else { - console.log('API key valid but no GPT models available'); - return false; - } - } else { - const errorData = await response.json().catch(() => ({})); - console.log('API key validation failed:', response.status, errorData.error?.message || 'Unknown error'); - return false; - } - } catch (error) { - console.error('API key validation network error:', error); - return apiKey.length >= 20; // Fallback for network issues - } - } else if (provider === 'gemini') { - // Gemini API keys typically start with 'AIza' - if (!apiKey.match(/^[A-Za-z0-9_-]+$/)) return false; - - try { - console.log('Validating Gemini API key...'); - - // Test the API key with a simple models list request - const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`); - - if (response.ok) { - const data = await response.json(); - if (data.models && data.models.length > 0) { - console.log('Gemini API key validation successful'); - return true; - } - } - - console.log('Gemini API key validation failed'); - return false; - } catch (error) { - console.error('Gemini API key validation network error:', error); - return apiKey.length >= 20; // Fallback - } - } - - return false; - } - - startSlideOutAnimation() { - this.classList.add('sliding-out'); - } - - handleUsePicklesKey(e) { - e.preventDefault(); - if (this.wasJustDragged) return; - - console.log('Requesting Firebase authentication from main process...'); + if (this.validatedApiKey) { if (window.require) { - window.require('electron').ipcRenderer.invoke('start-firebase-auth'); + window.require("electron").ipcRenderer.invoke("api-key-validated", { + apiKey: this.validatedApiKey, + provider: this.validatedProvider || "openai", + }) } + this.validatedApiKey = null + this.validatedProvider = null + } } + } - handleClose() { - console.log('Close button clicked'); - if (window.require) { - window.require('electron').ipcRenderer.invoke('quit-application'); - } - } + connectedCallback() { + super.connectedCallback() + this.addEventListener("animationend", this.handleAnimationEnd) + } - handleAnimationEnd(e) { - if (e.target !== this) return; + disconnectedCallback() { + super.disconnectedCallback() + this.removeEventListener("animationend", this.handleAnimationEnd) + } - if (this.classList.contains('sliding-out')) { - this.classList.remove('sliding-out'); - this.classList.add('hidden'); + render() { + const isButtonDisabled = this.isLoading || !this.apiKey || !this.apiKey.trim() + console.log("Rendering with provider:", this.selectedProvider) - if (this.validatedApiKey) { - if (window.require) { - window.require('electron').ipcRenderer.invoke('api-key-validated', { - apiKey: this.validatedApiKey, - provider: this.validatedProvider || 'openai' - }); - } - this.validatedApiKey = null; - this.validatedProvider = null; - } - } - } - - connectedCallback() { - super.connectedCallback(); - this.addEventListener('animationend', this.handleAnimationEnd); - - } - - disconnectedCallback() { - super.disconnectedCallback(); - this.removeEventListener('animationend', this.handleAnimationEnd); - - } - - render() { - const isButtonDisabled = this.isLoading || !this.apiKey || !this.apiKey.trim(); - console.log('Rendering with provider:', this.selectedProvider); - - return html` + return html`
or
@@ -615,8 +654,8 @@ export class ApiKeyHeader extends LitElement {
- `; - } + ` + } } -customElements.define('apikey-header', ApiKeyHeader); +customElements.define("apikey-header", ApiKeyHeader) diff --git a/src/common/ai/factory.js b/src/common/ai/factory.js index 05a6780..8d0d6b5 100644 --- a/src/common/ai/factory.js +++ b/src/common/ai/factory.js @@ -1,8 +1,9 @@ const providers = { - openai: require('./providers/openai'), - gemini: require('./providers/gemini'), + openai: require("./providers/openai"), + gemini: require("./providers/gemini"), + anthropic: require("./providers/anthropic"), // 추가 provider는 여기에 등록 -}; +} /** * Creates an STT session based on provider @@ -12,9 +13,9 @@ const providers = { */ function createSTT(provider, opts) { if (!providers[provider]?.createSTT) { - throw new Error(`STT not supported for provider: ${provider}`); + throw new Error(`STT not supported for provider: ${provider}`) } - return providers[provider].createSTT(opts); + return providers[provider].createSTT(opts) } /** @@ -25,9 +26,9 @@ function createSTT(provider, opts) { */ function createLLM(provider, opts) { if (!providers[provider]?.createLLM) { - throw new Error(`LLM not supported for provider: ${provider}`); + throw new Error(`LLM not supported for provider: ${provider}`) } - return providers[provider].createLLM(opts); + return providers[provider].createLLM(opts) } /** @@ -38,9 +39,9 @@ function createLLM(provider, opts) { */ function createStreamingLLM(provider, opts) { if (!providers[provider]?.createStreamingLLM) { - throw new Error(`Streaming LLM not supported for provider: ${provider}`); + throw new Error(`Streaming LLM not supported for provider: ${provider}`) } - return providers[provider].createStreamingLLM(opts); + return providers[provider].createStreamingLLM(opts) } /** @@ -48,20 +49,20 @@ function createStreamingLLM(provider, opts) { * @returns {object} Object with stt and llm arrays */ function getAvailableProviders() { - const sttProviders = []; - const llmProviders = []; - + const sttProviders = [] + const llmProviders = [] + for (const [name, provider] of Object.entries(providers)) { - if (provider.createSTT) sttProviders.push(name); - if (provider.createLLM) llmProviders.push(name); + if (provider.createSTT) sttProviders.push(name) + if (provider.createLLM) llmProviders.push(name) } - - return { stt: sttProviders, llm: llmProviders }; + + return { stt: sttProviders, llm: llmProviders } } module.exports = { createSTT, createLLM, createStreamingLLM, - getAvailableProviders -}; \ No newline at end of file + getAvailableProviders, +} diff --git a/src/common/ai/providers/anthropic.js b/src/common/ai/providers/anthropic.js new file mode 100644 index 0000000..415fa95 --- /dev/null +++ b/src/common/ai/providers/anthropic.js @@ -0,0 +1,280 @@ +const Anthropic = require("@anthropic-ai/sdk") + +/** + * Creates an Anthropic STT session + * Note: Anthropic doesn't have native real-time STT, so this is a placeholder + * You might want to use a different STT service or implement a workaround + * @param {object} opts - Configuration options + * @param {string} opts.apiKey - Anthropic API key + * @param {string} [opts.language='en'] - Language code + * @param {object} [opts.callbacks] - Event callbacks + * @returns {Promise} STT session placeholder + */ +async function createSTT({ apiKey, language = "en", callbacks = {}, ...config }) { + console.warn("[Anthropic] STT not natively supported. Consider using OpenAI or Gemini for STT.") + + // Return a mock STT session that doesn't actually do anything + // You might want to fallback to another provider for STT + return { + sendRealtimeInput: async (audioData) => { + console.warn("[Anthropic] STT sendRealtimeInput called but not implemented") + }, + close: async () => { + console.log("[Anthropic] STT session closed") + }, + } +} + +/** + * Creates an Anthropic LLM instance + * @param {object} opts - Configuration options + * @param {string} opts.apiKey - Anthropic API key + * @param {string} [opts.model='claude-3-5-sonnet-20241022'] - Model name + * @param {number} [opts.temperature=0.7] - Temperature + * @param {number} [opts.maxTokens=4096] - Max tokens + * @returns {object} LLM instance + */ +function createLLM({ apiKey, model = "claude-3-5-sonnet-20241022", temperature = 0.7, maxTokens = 4096, ...config }) { + const client = new Anthropic({ apiKey }) + + return { + generateContent: async (parts) => { + const messages = [] + let systemPrompt = "" + const userContent = [] + + for (const part of parts) { + if (typeof part === "string") { + if (systemPrompt === "" && part.includes("You are")) { + systemPrompt = part + } else { + userContent.push({ type: "text", text: part }) + } + } else if (part.inlineData) { + userContent.push({ + type: "image", + source: { + type: "base64", + media_type: part.inlineData.mimeType, + data: part.inlineData.data, + }, + }) + } + } + + if (userContent.length > 0) { + messages.push({ role: "user", content: userContent }) + } + + try { + const response = await client.messages.create({ + model: model, + max_tokens: maxTokens, + temperature: temperature, + system: systemPrompt || undefined, + messages: messages, + }) + + return { + response: { + text: () => response.content[0].text, + }, + raw: response, + } + } catch (error) { + console.error("Anthropic API error:", error) + throw error + } + }, + + // For compatibility with chat-style interfaces + chat: async (messages) => { + let systemPrompt = "" + const anthropicMessages = [] + + for (const msg of messages) { + if (msg.role === "system") { + systemPrompt = msg.content + } else { + // Handle multimodal content + let content + if (Array.isArray(msg.content)) { + content = [] + for (const part of msg.content) { + if (typeof part === "string") { + content.push({ type: "text", text: part }) + } else if (part.type === "text") { + content.push({ type: "text", text: part.text }) + } else if (part.type === "image_url" && part.image_url) { + // Convert base64 image to Anthropic format + const base64Data = part.image_url.url.split(",")[1] + content.push({ + type: "image", + source: { + type: "base64", + media_type: "image/png", + data: base64Data, + }, + }) + } + } + } else { + content = [{ type: "text", text: msg.content }] + } + + anthropicMessages.push({ + role: msg.role === "user" ? "user" : "assistant", + content: content, + }) + } + } + + const response = await client.messages.create({ + model: model, + max_tokens: maxTokens, + temperature: temperature, + system: systemPrompt || undefined, + messages: anthropicMessages, + }) + + return { + content: response.content[0].text, + raw: response, + } + }, + } +} + +/** + * Creates an Anthropic streaming LLM instance + * @param {object} opts - Configuration options + * @param {string} opts.apiKey - Anthropic API key + * @param {string} [opts.model='claude-3-5-sonnet-20241022'] - Model name + * @param {number} [opts.temperature=0.7] - Temperature + * @param {number} [opts.maxTokens=4096] - Max tokens + * @returns {object} Streaming LLM instance + */ +function createStreamingLLM({ + apiKey, + model = "claude-3-5-sonnet-20241022", + temperature = 0.7, + maxTokens = 4096, + ...config +}) { + const client = new Anthropic({ apiKey }) + + return { + streamChat: async (messages) => { + console.log("[Anthropic Provider] Starting streaming request") + + let systemPrompt = "" + const anthropicMessages = [] + + for (const msg of messages) { + if (msg.role === "system") { + systemPrompt = msg.content + } else { + // Handle multimodal content + let content + if (Array.isArray(msg.content)) { + content = [] + for (const part of msg.content) { + if (typeof part === "string") { + content.push({ type: "text", text: part }) + } else if (part.type === "text") { + content.push({ type: "text", text: part.text }) + } else if (part.type === "image_url" && part.image_url) { + // Convert base64 image to Anthropic format + const base64Data = part.image_url.url.split(",")[1] + content.push({ + type: "image", + source: { + type: "base64", + media_type: "image/png", + data: base64Data, + }, + }) + } + } + } else { + content = [{ type: "text", text: msg.content }] + } + + anthropicMessages.push({ + role: msg.role === "user" ? "user" : "assistant", + content: content, + }) + } + } + + // Create a ReadableStream to handle Anthropic's streaming + const stream = new ReadableStream({ + async start(controller) { + try { + console.log("[Anthropic Provider] Processing messages:", anthropicMessages.length, "messages") + + let chunkCount = 0 + let totalContent = "" + + // Stream the response + const stream = await client.messages.create({ + model: model, + max_tokens: maxTokens, + temperature: temperature, + system: systemPrompt || undefined, + messages: anthropicMessages, + stream: true, + }) + + for await (const chunk of stream) { + if (chunk.type === "content_block_delta" && chunk.delta.type === "text_delta") { + chunkCount++ + const chunkText = chunk.delta.text || "" + totalContent += chunkText + + // Format as SSE data + const data = JSON.stringify({ + choices: [ + { + delta: { + content: chunkText, + }, + }, + ], + }) + controller.enqueue(new TextEncoder().encode(`data: ${data}\n\n`)) + } + } + + console.log( + `[Anthropic Provider] Streamed ${chunkCount} chunks, total length: ${totalContent.length} chars`, + ) + + // Send the final done message + controller.enqueue(new TextEncoder().encode("data: [DONE]\n\n")) + controller.close() + console.log("[Anthropic Provider] Streaming completed successfully") + } catch (error) { + console.error("[Anthropic Provider] Streaming error:", error) + controller.error(error) + } + }, + }) + + // Create a Response object with the stream + return new Response(stream, { + headers: { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + Connection: "keep-alive", + }, + }) + }, + } +} + +module.exports = { + createSTT, + createLLM, + createStreamingLLM, +} diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 9d74334..4b540f6 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -1,7 +1,6 @@ const { BrowserWindow, globalShortcut, ipcMain, screen, app, shell, desktopCapturer } = require('electron'); const WindowLayoutManager = require('./windowLayoutManager'); const SmoothMovementManager = require('./smoothMovementManager'); -const liquidGlass = require('electron-liquid-glass'); const path = require('node:path'); const fs = require('node:fs'); const os = require('os'); @@ -15,6 +14,7 @@ const fetch = require('node-fetch'); /* ────────────────[ GLASS BYPASS ]─────────────── */ +let liquidGlass; const isLiquidGlassSupported = () => { if (process.platform !== 'darwin') { return false; @@ -23,7 +23,15 @@ const isLiquidGlassSupported = () => { // return majorVersion >= 25; // macOS 26+ (Darwin 25+) return majorVersion >= 26; // See you soon! }; -const shouldUseLiquidGlass = isLiquidGlassSupported(); +let shouldUseLiquidGlass = isLiquidGlassSupported(); +if (shouldUseLiquidGlass) { + try { + liquidGlass = require('electron-liquid-glass'); + } catch (e) { + console.warn('Could not load optional dependency "electron-liquid-glass". The feature will be disabled.'); + shouldUseLiquidGlass = false; + } +} /* ────────────────[ GLASS BYPASS ]─────────────── */ let isContentProtectionOn = true; @@ -83,7 +91,9 @@ function createFeatureWindows(header) { }); listen.setContentProtection(isContentProtectionOn); listen.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - listen.setWindowButtonVisibility(false); + if (process.platform === 'darwin') { + listen.setWindowButtonVisibility(false); + } const listenLoadOptions = { query: { view: 'listen' } }; if (!shouldUseLiquidGlass) { listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); @@ -112,7 +122,9 @@ function createFeatureWindows(header) { const ask = new BrowserWindow({ ...commonChildOptions, width:600 }); ask.setContentProtection(isContentProtectionOn); ask.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - ask.setWindowButtonVisibility(false); + if (process.platform === 'darwin') { + ask.setWindowButtonVisibility(false); + } const askLoadOptions = { query: { view: 'ask' } }; if (!shouldUseLiquidGlass) { ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); @@ -146,7 +158,9 @@ function createFeatureWindows(header) { const settings = new BrowserWindow({ ...commonChildOptions, width:240, maxHeight:400, parent:undefined }); settings.setContentProtection(isContentProtectionOn); settings.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - settings.setWindowButtonVisibility(false); + if (process.platform === 'darwin') { + settings.setWindowButtonVisibility(false); + } const settingsLoadOptions = { query: { view: 'settings' } }; if (!shouldUseLiquidGlass) { settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) @@ -236,12 +250,13 @@ function toggleAllWindowsVisibility(movementManager) { if (win.isVisible()) { lastVisibleWindows.add(name); if (name !== 'header') { - win.webContents.send('window-hide-animation'); - setTimeout(() => { - if (!win.isDestroyed()) { - win.hide(); - } - }, 200); + // win.webContents.send('window-hide-animation'); + // setTimeout(() => { + // if (!win.isDestroyed()) { + // win.hide(); + // } + // }, 200); + win.hide(); } } }); @@ -251,7 +266,7 @@ function toggleAllWindowsVisibility(movementManager) { movementManager.hideToEdge(nearestEdge, () => { header.hide(); console.log('[Visibility] Smart hide completed'); - }); + }, { instant: true }); } else { console.log('[Visibility] Smart showing from hidden position'); console.log('[Visibility] Restoring windows:', Array.from(lastVisibleWindows)); @@ -306,7 +321,9 @@ function createWindows() { webSecurity: false, }, }); - header.setWindowButtonVisibility(false); + if (process.platform === 'darwin') { + header.setWindowButtonVisibility(false); + } const headerLoadOptions = {}; if (!shouldUseLiquidGlass) { header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions); @@ -372,7 +389,7 @@ function createWindows() { // loadAndRegisterShortcuts(); // }); - ipcMain.handle('toggle-all-windows-visibility', toggleAllWindowsVisibility); + ipcMain.handle('toggle-all-windows-visibility', () => toggleAllWindowsVisibility(movementManager)); ipcMain.handle('toggle-feature', async (event, featureName) => { if (!windowPool.get(featureName) && currentHeaderState === 'main') { @@ -1482,4 +1499,4 @@ module.exports = { getStoredApiKey, getStoredProvider, captureScreenshot, -}; +}; \ No newline at end of file From 82796737efb34a8f6bf6c52e483aa915068e5ffc Mon Sep 17 00:00:00 2001 From: Surya Date: Mon, 7 Jul 2025 16:45:23 +0530 Subject: [PATCH 22/52] Feature : Anthropic API Support --- src/common/ai/providers/anthropic.js | 20 ++++++++++++++++---- src/features/ask/askService.js | 22 ++++++++++++++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/common/ai/providers/anthropic.js b/src/common/ai/providers/anthropic.js index 415fa95..f86a363 100644 --- a/src/common/ai/providers/anthropic.js +++ b/src/common/ai/providers/anthropic.js @@ -107,12 +107,17 @@ function createLLM({ apiKey, model = "claude-3-5-sonnet-20241022", temperature = content.push({ type: "text", text: part.text }) } else if (part.type === "image_url" && part.image_url) { // Convert base64 image to Anthropic format - const base64Data = part.image_url.url.split(",")[1] + const imageUrl = part.image_url.url + const [mimeInfo, base64Data] = imageUrl.split(",") + + // Extract the actual MIME type from the data URL + const mimeType = mimeInfo.match(/data:([^;]+)/)?.[1] || "image/jpeg" + content.push({ type: "image", source: { type: "base64", - media_type: "image/png", + media_type: mimeType, data: base64Data, }, }) @@ -185,12 +190,19 @@ function createStreamingLLM({ content.push({ type: "text", text: part.text }) } else if (part.type === "image_url" && part.image_url) { // Convert base64 image to Anthropic format - const base64Data = part.image_url.url.split(",")[1] + const imageUrl = part.image_url.url + const [mimeInfo, base64Data] = imageUrl.split(",") + + // Extract the actual MIME type from the data URL + const mimeType = mimeInfo.match(/data:([^;]+)/)?.[1] || "image/jpeg" + + console.log(`[Anthropic] Processing image with MIME type: ${mimeType}`) + content.push({ type: "image", source: { type: "base64", - media_type: "image/png", + media_type: mimeType, data: base64Data, }, }) diff --git a/src/features/ask/askService.js b/src/features/ask/askService.js index 03e4ed0..33428be 100644 --- a/src/features/ask/askService.js +++ b/src/features/ask/askService.js @@ -66,9 +66,27 @@ async function sendMessage(userPrompt) { console.log(`[AskService] 🚀 Sending request to ${provider} AI...`); + // FIX: Proper model selection for each provider + let model; + switch (provider) { + case 'openai': + model = 'gpt-4o'; // Use a valid OpenAI model + break; + case 'gemini': + model = 'gemini-2.0-flash-exp'; // Use a valid Gemini model + break; + case 'anthropic': + model = 'claude-3-5-sonnet-20241022'; // Use a valid Claude model + break; + default: + model = 'gpt-4o'; // Default fallback + } + + console.log(`[AskService] Using model: ${model} for provider: ${provider}`); + const streamingLLM = createStreamingLLM(provider, { apiKey: API_KEY, - model: provider === 'openai' ? 'gpt-4.1' : 'gemini-2.5-flash', + model: model, temperature: 0.7, maxTokens: 2048, usePortkey: provider === 'openai' && isLoggedIn, @@ -144,4 +162,4 @@ function initialize() { module.exports = { initialize, -}; \ No newline at end of file +}; \ No newline at end of file From 4dcf19f6a518e94a06e25bf7720b7faaab3c51d9 Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Mon, 7 Jul 2025 20:18:38 +0900 Subject: [PATCH 23/52] deeplink issue fixed --- electron-builder.yml | 27 +++++++ pickleglass_web/backend_node/ipcBridge.js | 18 ++++- pickleglass_web/backend_node/routes/user.js | 13 +++- .../repositories/user/sqlite.repository.js | 19 ++++- src/index.js | 70 ++++++++++--------- 5 files changed, 109 insertions(+), 38 deletions(-) diff --git a/electron-builder.yml b/electron-builder.yml index 8f7d820..153f3b5 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -13,6 +13,12 @@ publish: repo: glass releaseType: draft +# Protocols configuration for deep linking +protocols: + name: PickleGlass Protocol + schemes: + - pickleglass + # List of files to be included in the app package files: - src/**/* @@ -29,6 +35,27 @@ extraResources: asarUnpack: - "src/assets/SystemAudioDump" +# Windows configuration +win: + icon: src/assets/logo.ico + target: + - target: nsis + arch: x64 + - target: portable + arch: x64 + publisherName: Pickle Team + requestedExecutionLevel: asInvoker + +# NSIS installer configuration for Windows +nsis: + oneClick: false + perMachine: false + allowToChangeInstallationDirectory: true + deleteAppDataOnUninstall: true + createDesktopShortcut: always + createStartMenuShortcut: true + shortcutName: Glass + # macOS specific configuration mac: # The application category type diff --git a/pickleglass_web/backend_node/ipcBridge.js b/pickleglass_web/backend_node/ipcBridge.js index 46d1e04..805403c 100644 --- a/pickleglass_web/backend_node/ipcBridge.js +++ b/pickleglass_web/backend_node/ipcBridge.js @@ -2,9 +2,20 @@ const crypto = require('crypto'); function ipcRequest(req, channel, payload) { return new Promise((resolve, reject) => { + // 즉시 브리지 상태 확인 - 문제있으면 바로 실패 + if (!req.bridge || typeof req.bridge.emit !== 'function') { + reject(new Error('IPC bridge is not available')); + return; + } + const responseChannel = `${channel}-${crypto.randomUUID()}`; req.bridge.once(responseChannel, (response) => { + if (!response) { + reject(new Error(`No response received from ${channel}`)); + return; + } + if (response.success) { resolve(response.data); } else { @@ -12,7 +23,12 @@ function ipcRequest(req, channel, payload) { } }); - req.bridge.emit('web-data-request', channel, responseChannel, payload); + try { + req.bridge.emit('web-data-request', channel, responseChannel, payload); + } catch (error) { + req.bridge.removeAllListeners(responseChannel); + reject(new Error(`Failed to emit IPC request: ${error.message}`)); + } }); } diff --git a/pickleglass_web/backend_node/routes/user.js b/pickleglass_web/backend_node/routes/user.js index e0fe054..d31a9a8 100644 --- a/pickleglass_web/backend_node/routes/user.js +++ b/pickleglass_web/backend_node/routes/user.js @@ -25,11 +25,22 @@ router.get('/profile', async (req, res) => { router.post('/find-or-create', async (req, res) => { try { + console.log('[API] find-or-create request received:', req.body); + + if (!req.body || !req.body.uid) { + return res.status(400).json({ error: 'User data with uid is required' }); + } + const user = await ipcRequest(req, 'find-or-create-user', req.body); + console.log('[API] find-or-create response:', user); res.status(200).json(user); } catch (error) { console.error('Failed to find or create user via IPC:', error); - res.status(500).json({ error: 'Failed to find or create user' }); + console.error('Request body:', req.body); + res.status(500).json({ + error: 'Failed to find or create user', + details: error.message + }); } }); diff --git a/src/common/repositories/user/sqlite.repository.js b/src/common/repositories/user/sqlite.repository.js index 2bb0ad7..7185c81 100644 --- a/src/common/repositories/user/sqlite.repository.js +++ b/src/common/repositories/user/sqlite.repository.js @@ -2,8 +2,17 @@ const sqliteClient = require('../../services/sqliteClient'); function findOrCreate(user) { const db = sqliteClient.getDb(); + + if (!user || !user.uid) { + throw new Error('User object and uid are required'); + } + const { uid, displayName, email } = user; const now = Math.floor(Date.now() / 1000); + + // Validate inputs + const safeDisplayName = displayName || 'User'; + const safeEmail = email || 'no-email@example.com'; const query = ` INSERT INTO users (uid, display_name, email, created_at) @@ -14,11 +23,15 @@ function findOrCreate(user) { `; try { - db.prepare(query).run(uid, displayName, email, now); - return getById(uid); + console.log('[SQLite] Creating/updating user:', { uid, displayName: safeDisplayName, email: safeEmail }); + db.prepare(query).run(uid, safeDisplayName, safeEmail, now); + const result = getById(uid); + console.log('[SQLite] User operation successful:', result); + return result; } catch (err) { console.error('SQLite: Failed to find or create user:', err); - throw err; + console.error('SQLite: User data:', { uid, displayName: safeDisplayName, email: safeEmail }); + throw new Error(`Failed to create user in database: ${err.message}`); } } diff --git a/src/index.js b/src/index.js index e943a55..e0fcde4 100644 --- a/src/index.js +++ b/src/index.js @@ -61,28 +61,28 @@ function setupProtocolHandling() { let protocolUrl = null; - if (process.platform === 'win32') { - // Windows - const lastArg = commandLine.length > 0 ? commandLine[commandLine.length - 1] : null; - if (lastArg && - typeof lastArg === 'string' && - lastArg.startsWith('pickleglass://') && - !lastArg.includes('\\') && - !lastArg.includes('₩')) { - protocolUrl = lastArg; - } - } else { - // Linux or etc - const lastArg = commandLine.length > 0 ? commandLine[commandLine.length - 1] : null; - if (lastArg && - typeof lastArg === 'string' && - lastArg.startsWith('pickleglass://')) { - protocolUrl = lastArg; + // Search through all command line arguments for a valid protocol URL + for (const arg of commandLine) { + if (arg && typeof arg === 'string' && arg.startsWith('pickleglass://')) { + // Clean up the URL by removing problematic characters + const cleanUrl = arg.replace(/[\\₩]/g, ''); + + // Additional validation for Windows + if (process.platform === 'win32') { + // On Windows, ensure the URL doesn't contain file path indicators + if (!cleanUrl.includes(':') || cleanUrl.indexOf('://') === cleanUrl.lastIndexOf(':')) { + protocolUrl = cleanUrl; + break; + } + } else { + protocolUrl = cleanUrl; + break; + } } } if (protocolUrl) { - console.log('[Protocol] Valid URL found from second instance (last arg):', protocolUrl); + console.log('[Protocol] Valid URL found from second instance:', protocolUrl); handleCustomUrl(protocolUrl); } else { console.log('[Protocol] No valid protocol URL found in command line arguments'); @@ -135,16 +135,17 @@ function focusMainWindow() { } if (process.platform === 'win32') { - const lastArg = process.argv.length > 0 ? process.argv[process.argv.length - 1] : null; - - if (lastArg && - typeof lastArg === 'string' && - lastArg.startsWith('pickleglass://') && - !lastArg.includes('\\') && - !lastArg.includes('₩')) { - - console.log('[Protocol] Found protocol URL in initial arguments (last arg):', lastArg); - pendingDeepLinkUrl = lastArg; + for (const arg of process.argv) { + if (arg && typeof arg === 'string' && arg.startsWith('pickleglass://')) { + // Clean up the URL by removing problematic characters (korean characters issue...) + const cleanUrl = arg.replace(/[\\₩]/g, ''); + + if (!cleanUrl.includes(':') || cleanUrl.indexOf('://') === cleanUrl.lastIndexOf(':')) { + console.log('[Protocol] Found protocol URL in initial arguments:', cleanUrl); + pendingDeepLinkUrl = cleanUrl; + break; + } + } } console.log('[Protocol] Initial process.argv:', process.argv); @@ -376,16 +377,19 @@ async function handleCustomUrl(url) { try { console.log('[Custom URL] Processing URL:', url); - // val url + // Validate and clean URL if (!url || typeof url !== 'string' || !url.startsWith('pickleglass://')) { console.error('[Custom URL] Invalid URL format:', url); return; } - // val url - if (url.includes('\\') || url.includes('₩')) { - console.error('[Custom URL] URL contains invalid path characters:', url); - return; + // Clean up URL by removing problematic characters + const cleanUrl = url.replace(/[\\₩]/g, ''); + + // Additional validation + if (cleanUrl !== url) { + console.log('[Custom URL] Cleaned URL from:', url, 'to:', cleanUrl); + url = cleanUrl; } const urlObj = new URL(url); From 795ff440ea623140ae20713d10985d2102aa8c90 Mon Sep 17 00:00:00 2001 From: Surya <125463872+Surya-sourav@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:05:16 +0530 Subject: [PATCH 24/52] Delete src/electron/windowManager.js This was temporary fix for the Linux compatiblity issue with Electron-liquid-glass --- src/electron/windowManager.js | 1502 --------------------------------- 1 file changed, 1502 deletions(-) delete mode 100644 src/electron/windowManager.js diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js deleted file mode 100644 index 4b540f6..0000000 --- a/src/electron/windowManager.js +++ /dev/null @@ -1,1502 +0,0 @@ -const { BrowserWindow, globalShortcut, ipcMain, screen, app, shell, desktopCapturer } = require('electron'); -const WindowLayoutManager = require('./windowLayoutManager'); -const SmoothMovementManager = require('./smoothMovementManager'); -const path = require('node:path'); -const fs = require('node:fs'); -const os = require('os'); -const util = require('util'); -const execFile = util.promisify(require('child_process').execFile); -const sharp = require('sharp'); -const authService = require('../common/services/authService'); -const systemSettingsRepository = require('../common/repositories/systemSettings'); -const userRepository = require('../common/repositories/user'); -const fetch = require('node-fetch'); - - -/* ────────────────[ GLASS BYPASS ]─────────────── */ -let liquidGlass; -const isLiquidGlassSupported = () => { - if (process.platform !== 'darwin') { - return false; - } - const majorVersion = parseInt(os.release().split('.')[0], 10); - // return majorVersion >= 25; // macOS 26+ (Darwin 25+) - return majorVersion >= 26; // See you soon! -}; -let shouldUseLiquidGlass = isLiquidGlassSupported(); -if (shouldUseLiquidGlass) { - try { - liquidGlass = require('electron-liquid-glass'); - } catch (e) { - console.warn('Could not load optional dependency "electron-liquid-glass". The feature will be disabled.'); - shouldUseLiquidGlass = false; - } -} -/* ────────────────[ GLASS BYPASS ]─────────────── */ - -let isContentProtectionOn = true; -let currentDisplayId = null; - -let mouseEventsIgnored = false; -let lastVisibleWindows = new Set(['header']); -const HEADER_HEIGHT = 47; -const DEFAULT_WINDOW_WIDTH = 353; - -let currentHeaderState = 'apikey'; -const windowPool = new Map(); -let fixedYPosition = 0; -let lastScreenshot = null; - -let settingsHideTimer = null; - -let selectedCaptureSourceId = null; - -let layoutManager = null; -function updateLayout() { - if (layoutManager) { - layoutManager.updateLayout(); - } -} - -let movementManager = null; - -let storedProvider = 'openai'; - -const featureWindows = ['listen','ask','settings']; -function isAllowed(name) { - if (name === 'header') return true; - return featureWindows.includes(name) && currentHeaderState === 'main'; -} - -function createFeatureWindows(header) { - if (windowPool.has('listen')) return; - - const commonChildOptions = { - parent: header, - show: false, - frame: false, - transparent: true, - vibrancy: false, - hasShadow: false, - skipTaskbar: true, - hiddenInMissionControl: true, - resizable: false, - webPreferences: { nodeIntegration: true, contextIsolation: false }, - }; - - // listen - const listen = new BrowserWindow({ - ...commonChildOptions, width:400,minWidth:400,maxWidth:400, - maxHeight:700, - }); - listen.setContentProtection(isContentProtectionOn); - listen.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - if (process.platform === 'darwin') { - listen.setWindowButtonVisibility(false); - } - const listenLoadOptions = { query: { view: 'listen' } }; - if (!shouldUseLiquidGlass) { - listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); - } - else { - listenLoadOptions.query.glass = 'true'; - listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); - listen.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(listen.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); - if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); - // liquidGlass.unstable_setScrim(viewId, 1); - // liquidGlass.unstable_setSubdued(viewId, 1); - } - }); - } - - - windowPool.set('listen', listen); - - // ask - const ask = new BrowserWindow({ ...commonChildOptions, width:600 }); - ask.setContentProtection(isContentProtectionOn); - ask.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - if (process.platform === 'darwin') { - ask.setWindowButtonVisibility(false); - } - const askLoadOptions = { query: { view: 'ask' } }; - if (!shouldUseLiquidGlass) { - ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); - } - else { - askLoadOptions.query.glass = 'true'; - ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); - ask.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(ask.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); - if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); - // liquidGlass.unstable_setScrim(viewId, 1); - // liquidGlass.unstable_setSubdued(viewId, 1); - } - }); - } - - ask.on('blur',()=>ask.webContents.send('window-blur')); - - // Open DevTools in development - if (!app.isPackaged) { - ask.webContents.openDevTools({ mode: 'detach' }); - } - windowPool.set('ask', ask); - - // settings - const settings = new BrowserWindow({ ...commonChildOptions, width:240, maxHeight:400, parent:undefined }); - settings.setContentProtection(isContentProtectionOn); - settings.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - if (process.platform === 'darwin') { - settings.setWindowButtonVisibility(false); - } - const settingsLoadOptions = { query: { view: 'settings' } }; - if (!shouldUseLiquidGlass) { - settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) - .catch(console.error); - } - else { - settingsLoadOptions.query.glass = 'true'; - settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) - .catch(console.error); - settings.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(settings.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); - if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); - // liquidGlass.unstable_setScrim(viewId, 1); - // liquidGlass.unstable_setSubdued(viewId, 1); - } - }); - } - windowPool.set('settings', settings); -} - -function destroyFeatureWindows() { - if (settingsHideTimer) { - clearTimeout(settingsHideTimer); - settingsHideTimer = null; - } - featureWindows.forEach(name=>{ - const win = windowPool.get(name); - if (win && !win.isDestroyed()) win.destroy(); - windowPool.delete(name); - }); -} - - -function getCurrentDisplay(window) { - if (!window || window.isDestroyed()) return screen.getPrimaryDisplay(); - - const windowBounds = window.getBounds(); - const windowCenter = { - x: windowBounds.x + windowBounds.width / 2, - y: windowBounds.y + windowBounds.height / 2, - }; - - return screen.getDisplayNearestPoint(windowCenter); -} - -function getDisplayById(displayId) { - const displays = screen.getAllDisplays(); - return displays.find(d => d.id === displayId) || screen.getPrimaryDisplay(); -} - - - -function toggleAllWindowsVisibility(movementManager) { - const header = windowPool.get('header'); - if (!header) return; - - if (header.isVisible()) { - console.log('[Visibility] Smart hiding - calculating nearest edge'); - - const headerBounds = header.getBounds(); - const display = screen.getPrimaryDisplay(); - const { width: screenWidth, height: screenHeight } = display.workAreaSize; - - const centerX = headerBounds.x + headerBounds.width / 2; - const centerY = headerBounds.y + headerBounds.height / 2; - - const distances = { - top: centerY, - bottom: screenHeight - centerY, - left: centerX, - right: screenWidth - centerX, - }; - - const nearestEdge = Object.keys(distances).reduce((nearest, edge) => (distances[edge] < distances[nearest] ? edge : nearest)); - - console.log(`[Visibility] Nearest edge: ${nearestEdge} (distance: ${distances[nearestEdge].toFixed(1)}px)`); - - lastVisibleWindows.clear(); - lastVisibleWindows.add('header'); - - windowPool.forEach((win, name) => { - if (win.isVisible()) { - lastVisibleWindows.add(name); - if (name !== 'header') { - // win.webContents.send('window-hide-animation'); - // setTimeout(() => { - // if (!win.isDestroyed()) { - // win.hide(); - // } - // }, 200); - win.hide(); - } - } - }); - - console.log('[Visibility] Visible windows before hide:', Array.from(lastVisibleWindows)); - - movementManager.hideToEdge(nearestEdge, () => { - header.hide(); - console.log('[Visibility] Smart hide completed'); - }, { instant: true }); - } else { - console.log('[Visibility] Smart showing from hidden position'); - console.log('[Visibility] Restoring windows:', Array.from(lastVisibleWindows)); - - header.show(); - - movementManager.showFromEdge(() => { - lastVisibleWindows.forEach(name => { - if (name === 'header') return; - const win = windowPool.get(name); - if (win && !win.isDestroyed()) { - win.show(); - win.webContents.send('window-show-animation'); - } - }); - - setImmediate(updateLayout); - setTimeout(updateLayout, 120); - - console.log('[Visibility] Smart show completed'); - }); - } -} - - -function createWindows() { - const primaryDisplay = screen.getPrimaryDisplay(); - const { y: workAreaY, width: screenWidth } = primaryDisplay.workArea; - - const initialX = Math.round((screenWidth - DEFAULT_WINDOW_WIDTH) / 2); - const initialY = workAreaY + 21; - movementManager = new SmoothMovementManager(windowPool, getDisplayById, getCurrentDisplay, updateLayout); - - const header = new BrowserWindow({ - width: DEFAULT_WINDOW_WIDTH, - height: HEADER_HEIGHT, - x: initialX, - y: initialY, - frame: false, - transparent: true, - vibrancy: false, - alwaysOnTop: true, - skipTaskbar: true, - hiddenInMissionControl: true, - resizable: false, - focusable: true, - acceptFirstMouse: true, - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - backgroundThrottling: false, - webSecurity: false, - }, - }); - if (process.platform === 'darwin') { - header.setWindowButtonVisibility(false); - } - const headerLoadOptions = {}; - if (!shouldUseLiquidGlass) { - header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions); - } - else { - headerLoadOptions.query = { glass: 'true' }; - header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions); - header.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(header.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); - if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); - // liquidGlass.unstable_setScrim(viewId, 1); - // liquidGlass.unstable_setSubdued(viewId, 1); - } - }); - } - windowPool.set('header', header); - layoutManager = new WindowLayoutManager(windowPool); - - header.webContents.once('dom-ready', () => { - loadAndRegisterShortcuts(movementManager); - }); - - setupIpcHandlers(movementManager); - - if (currentHeaderState === 'main') { - createFeatureWindows(header); - } - - header.setContentProtection(isContentProtectionOn); - header.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); - // header.loadFile(path.join(__dirname, '../app/header.html')); - - // Open DevTools in development - if (!app.isPackaged) { - header.webContents.openDevTools({ mode: 'detach' }); - } - - header.on('focus', () => { - console.log('[WindowManager] Header gained focus'); - }); - - header.on('blur', () => { - console.log('[WindowManager] Header lost focus'); - }); - - header.webContents.on('before-input-event', (event, input) => { - if (input.type === 'mouseDown') { - const target = input.target; - if (target && (target.includes('input') || target.includes('apikey'))) { - header.focus(); - } - } - }); - - header.on('resize', updateLayout); - - // header.webContents.once('dom-ready', () => { - // loadAndRegisterShortcuts(); - // }); - - ipcMain.handle('toggle-all-windows-visibility', () => toggleAllWindowsVisibility(movementManager)); - - ipcMain.handle('toggle-feature', async (event, featureName) => { - if (!windowPool.get(featureName) && currentHeaderState === 'main') { - createFeatureWindows(windowPool.get('header')); - } - - const windowToToggle = windowPool.get(featureName); - - if (windowToToggle) { - if (featureName === 'listen') { - const listenService = global.listenService; - if (listenService && listenService.isSessionActive()) { - console.log('[WindowManager] Listen session is active, closing it via toggle.'); - await listenService.closeSession(); - return; - } - } - console.log(`[WindowManager] Toggling feature: ${featureName}`); - } - - if (featureName === 'ask') { - let askWindow = windowPool.get('ask'); - - if (!askWindow || askWindow.isDestroyed()) { - console.log('[WindowManager] Ask window not found, creating new one'); - return; - } - - if (askWindow.isVisible()) { - try { - const hasResponse = await askWindow.webContents.executeJavaScript(` - (() => { - try { - // PickleGlassApp의 Shadow DOM 내부로 접근 - const pickleApp = document.querySelector('pickle-glass-app'); - if (!pickleApp || !pickleApp.shadowRoot) { - console.log('PickleGlassApp not found'); - return false; - } - - // PickleGlassApp의 shadowRoot 내부에서 ask-view 찾기 - const askView = pickleApp.shadowRoot.querySelector('ask-view'); - if (!askView) { - console.log('AskView not found in PickleGlassApp shadow DOM'); - return false; - } - - console.log('AskView found, checking state...'); - console.log('currentResponse:', askView.currentResponse); - console.log('isLoading:', askView.isLoading); - console.log('isStreaming:', askView.isStreaming); - - const hasContent = !!(askView.currentResponse || askView.isLoading || askView.isStreaming); - - if (!hasContent && askView.shadowRoot) { - const responseContainer = askView.shadowRoot.querySelector('.response-container'); - if (responseContainer && !responseContainer.classList.contains('hidden')) { - const textContent = responseContainer.textContent.trim(); - const hasActualContent = textContent && - !textContent.includes('Ask a question to see the response here') && - textContent.length > 0; - console.log('Response container content check:', hasActualContent); - return hasActualContent; - } - } - - return hasContent; - } catch (error) { - console.error('Error checking AskView state:', error); - return false; - } - })() - `); - - console.log(`[WindowManager] Ask window visible, hasResponse: ${hasResponse}`); - - if (hasResponse) { - askWindow.webContents.send('toggle-text-input'); - console.log('[WindowManager] Sent toggle-text-input command'); - } else { - console.log('[WindowManager] No response found, closing window'); - askWindow.webContents.send('window-hide-animation'); - - setTimeout(() => { - if (!askWindow.isDestroyed()) { - askWindow.hide(); - updateLayout(); - } - }, 250); - } - } catch (error) { - console.error('[WindowManager] Error checking Ask window state:', error); - console.log('[WindowManager] Falling back to toggle text input'); - askWindow.webContents.send('toggle-text-input'); - } - } else { - console.log('[WindowManager] Showing hidden Ask window'); - askWindow.show(); - updateLayout(); - askWindow.webContents.send('window-show-animation'); - askWindow.webContents.send('window-did-show'); - } - } else { - const windowToToggle = windowPool.get(featureName); - - if (windowToToggle) { - if (windowToToggle.isDestroyed()) { - console.error(`Window ${featureName} is destroyed, cannot toggle`); - return; - } - - if (windowToToggle.isVisible()) { - if (featureName === 'settings') { - windowToToggle.webContents.send('settings-window-hide-animation'); - } else { - windowToToggle.webContents.send('window-hide-animation'); - } - - setTimeout(() => { - if (!windowToToggle.isDestroyed()) { - windowToToggle.hide(); - updateLayout(); - } - }, 250); - } else { - try { - windowToToggle.show(); - updateLayout(); - - if (featureName === 'listen') { - windowToToggle.webContents.send('start-listening-session'); - } - - windowToToggle.webContents.send('window-show-animation'); - } catch (e) { - console.error('Error showing window:', e); - } - } - } else { - console.error(`Window not found for feature: ${featureName}`); - console.error('Available windows:', Array.from(windowPool.keys())); - } - } - }); - - ipcMain.handle('send-question-to-ask', (event, question) => { - const askWindow = windowPool.get('ask'); - if (askWindow && !askWindow.isDestroyed()) { - console.log('📨 Main process: Sending question to AskView', question); - askWindow.webContents.send('receive-question-from-assistant', question); - return { success: true }; - } else { - console.error('❌ Cannot find AskView window'); - return { success: false, error: 'AskView window not found' }; - } - }); - - ipcMain.handle('adjust-window-height', (event, targetHeight) => { - const senderWindow = BrowserWindow.fromWebContents(event.sender); - if (senderWindow) { - const wasResizable = senderWindow.isResizable(); - if (!wasResizable) { - senderWindow.setResizable(true); - } - - const currentBounds = senderWindow.getBounds(); - const minHeight = senderWindow.getMinimumSize()[1]; - const maxHeight = senderWindow.getMaximumSize()[1]; - - let adjustedHeight; - if (maxHeight === 0) { - adjustedHeight = Math.max(minHeight, targetHeight); - } else { - adjustedHeight = Math.max(minHeight, Math.min(maxHeight, targetHeight)); - } - - senderWindow.setSize(currentBounds.width, adjustedHeight, false); - - if (!wasResizable) { - senderWindow.setResizable(false); - } - - updateLayout(); - } - }); - - ipcMain.on('session-did-close', () => { - const listenWindow = windowPool.get('listen'); - if (listenWindow && listenWindow.isVisible()) { - console.log('[WindowManager] Session closed, hiding listen window.'); - listenWindow.hide(); - } - }); - - // setupIpcHandlers(); - - return windowPool; -} - -function loadAndRegisterShortcuts(movementManager) { - const defaultKeybinds = getDefaultKeybinds(); - const header = windowPool.get('header'); - const sendToRenderer = (channel, ...args) => { - windowPool.forEach(win => { - try { - if (win && !win.isDestroyed()) { - win.webContents.send(channel, ...args); - } - } catch (e) {} - }); - }; - - - if (!header) { - return updateGlobalShortcuts(defaultKeybinds, undefined, sendToRenderer, movementManager); - } - - header.webContents - .executeJavaScript(`(() => localStorage.getItem('customKeybinds'))()`) - .then(saved => (saved ? JSON.parse(saved) : {})) - .then(savedKeybinds => { - const keybinds = { ...defaultKeybinds, ...savedKeybinds }; - updateGlobalShortcuts(keybinds, header, sendToRenderer, movementManager); - }) - .catch(() => updateGlobalShortcuts(defaultKeybinds, header, sendToRenderer, movementManager)); -} - - -function setupIpcHandlers(movementManager) { - screen.on('display-added', (event, newDisplay) => { - console.log('[Display] New display added:', newDisplay.id); - }); - - screen.on('display-removed', (event, oldDisplay) => { - console.log('[Display] Display removed:', oldDisplay.id); - const header = windowPool.get('header'); - if (header && getCurrentDisplay(header).id === oldDisplay.id) { - const primaryDisplay = screen.getPrimaryDisplay(); - movementManager.moveToDisplay(primaryDisplay.id); - } - }); - - screen.on('display-metrics-changed', (event, display, changedMetrics) => { - console.log('[Display] Display metrics changed:', display.id, changedMetrics); - updateLayout(); - }); - - // 1. 스트리밍 데이터 조각(chunk)을 받아서 ask 창으로 전달 - ipcMain.on('ask-response-chunk', (event, { token }) => { - const askWindow = windowPool.get('ask'); - if (askWindow && !askWindow.isDestroyed()) { - // renderer.js가 보낸 토큰을 AskView.js로 그대로 전달합니다. - askWindow.webContents.send('ask-response-chunk', { token }); - } - }); - - // 2. 스트리밍 종료 신호를 받아서 ask 창으로 전달 - ipcMain.on('ask-response-stream-end', () => { - const askWindow = windowPool.get('ask'); - if (askWindow && !askWindow.isDestroyed()) { - askWindow.webContents.send('ask-response-stream-end'); - } - }); - - ipcMain.on('show-window', (event, args) => { - const { name, bounds } = typeof args === 'object' && args !== null ? args : { name: args, bounds: null }; - const win = windowPool.get(name); - - if (win && !win.isDestroyed()) { - if (settingsHideTimer) { - clearTimeout(settingsHideTimer); - settingsHideTimer = null; - } - - if (name === 'settings') { - // Adjust position based on button bounds - const header = windowPool.get('header'); - const headerBounds = header?.getBounds() ?? { x: 0, y: 0 }; - const settingsBounds = win.getBounds(); - - const disp = getCurrentDisplay(header); - const { x: waX, y: waY, width: waW, height: waH } = disp.workArea; - - let x = Math.round(headerBounds.x + (bounds?.x ?? 0) + (bounds?.width ?? 0) / 2 - settingsBounds.width / 2); - let y = Math.round(headerBounds.y + (bounds?.y ?? 0) + (bounds?.height ?? 0) + 31); - - x = Math.max(waX + 10, Math.min(waX + waW - settingsBounds.width - 10, x)); - y = Math.max(waY + 10, Math.min(waY + waH - settingsBounds.height - 10, y)); - - win.setBounds({ x, y }); - win.__lockedByButton = true; - console.log(`[WindowManager] Positioning settings window at (${x}, ${y}) based on button bounds.`); - } - - win.show(); - win.moveTop(); - - if (name === 'settings') { - win.setAlwaysOnTop(true); - } - // updateLayout(); - } - }); - - ipcMain.on('hide-window', (event, name) => { - const window = windowPool.get(name); - if (window && !window.isDestroyed()) { - if (name === 'settings') { - if (settingsHideTimer) { - clearTimeout(settingsHideTimer); - } - settingsHideTimer = setTimeout(() => { - // window.setAlwaysOnTop(false); - // window.hide(); - if (window && !window.isDestroyed()) { - window.setAlwaysOnTop(false); - window.hide(); - } - settingsHideTimer = null; - }, 200); - } else { - window.hide(); - } - window.__lockedByButton = false; - } - }); - - ipcMain.on('cancel-hide-window', (event, name) => { - if (name === 'settings' && settingsHideTimer) { - clearTimeout(settingsHideTimer); - settingsHideTimer = null; - } - }); - - ipcMain.handle('hide-all', () => { - windowPool.forEach(win => { - if (win.isFocused()) return; - win.hide(); - }); - }); - - ipcMain.handle('quit-application', () => { - app.quit(); - }); - - ipcMain.handle('is-window-visible', (event, windowName) => { - const window = windowPool.get(windowName); - if (window && !window.isDestroyed()) { - return window.isVisible(); - } - return false; - }); - - - ipcMain.handle('toggle-content-protection', () => { - isContentProtectionOn = !isContentProtectionOn; - console.log(`[Protection] Content protection toggled to: ${isContentProtectionOn}`); - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - win.setContentProtection(isContentProtectionOn); - } - }); - return isContentProtectionOn; - }); - - ipcMain.handle('get-content-protection-status', () => { - return isContentProtectionOn; - }); - - ipcMain.on('header-state-changed', (event, state) => { - console.log(`[WindowManager] Header state changed to: ${state}`); - currentHeaderState = state; - - if (state === 'main') { - createFeatureWindows(windowPool.get('header')); - } else { // 'apikey' | 'permission' - destroyFeatureWindows(); - } - - for (const [name, win] of windowPool) { - if (!isAllowed(name) && !win.isDestroyed()) { - win.hide(); - } - if (isAllowed(name) && win.isVisible()) { - win.show(); - } - } - - const header = windowPool.get('header'); - if (header && !header.isDestroyed()) { - header.webContents - .executeJavaScript(`(() => localStorage.getItem('customKeybinds'))()`) - .then(saved => { - const defaultKeybinds = getDefaultKeybinds(); - const savedKeybinds = saved ? JSON.parse(saved) : {}; - const keybinds = { ...defaultKeybinds, ...savedKeybinds }; - - const sendToRenderer = (channel, ...args) => { - windowPool.forEach(win => { - try { - if (win && !win.isDestroyed()) { - win.webContents.send(channel, ...args); - } - } catch (e) {} - }); - }; - - updateGlobalShortcuts(keybinds, header, sendToRenderer, movementManager); - }) - .catch(console.error); - } - }); - - ipcMain.on('update-keybinds', (event, newKeybinds) => { - updateGlobalShortcuts(newKeybinds); - }); - - ipcMain.handle('open-login-page', () => { - const webUrl = process.env.pickleglass_WEB_URL || 'http://localhost:3000'; - const personalizeUrl = `${webUrl}/personalize?desktop=true`; - shell.openExternal(personalizeUrl); - console.log('Opening personalization page:', personalizeUrl); - }); - - setupApiKeyIPC(); - - ipcMain.handle('resize-window', () => {}); - - ipcMain.handle('resize-for-view', () => {}); - - ipcMain.handle('resize-header-window', (event, { width, height }) => { - const header = windowPool.get('header'); - if (header) { - const wasResizable = header.isResizable(); - if (!wasResizable) { - header.setResizable(true); - } - - const bounds = header.getBounds(); - const newX = bounds.x + Math.round((bounds.width - width) / 2); - - header.setBounds({ x: newX, y: bounds.y, width, height }); - - if (!wasResizable) { - header.setResizable(false); - } - return { success: true }; - } - return { success: false, error: 'Header window not found' }; - }); - - ipcMain.on('header-animation-complete', (event, state) => { - const header = windowPool.get('header'); - if (!header) return; - - if (state === 'hidden') { - header.hide(); - } else if (state === 'visible') { - lastVisibleWindows.forEach(name => { - if (name === 'header') return; - const win = windowPool.get(name); - if (win) win.show(); - }); - - setImmediate(updateLayout); - setTimeout(updateLayout, 120); - } - }); - - ipcMain.handle('get-header-position', () => { - const header = windowPool.get('header'); - if (header) { - const [x, y] = header.getPosition(); - return { x, y }; - } - return { x: 0, y: 0 }; - }); - - ipcMain.handle('move-header', (event, newX, newY) => { - const header = windowPool.get('header'); - if (header) { - const currentY = newY !== undefined ? newY : header.getBounds().y; - header.setPosition(newX, currentY, false); - - updateLayout(); - } - }); - - ipcMain.handle('move-header-to', (event, newX, newY) => { - const header = windowPool.get('header'); - if (header) { - const targetDisplay = screen.getDisplayNearestPoint({ x: newX, y: newY }); - const { x: workAreaX, y: workAreaY, width, height } = targetDisplay.workArea; - const headerBounds = header.getBounds(); - - const clampedX = Math.max(workAreaX, Math.min(workAreaX + width - headerBounds.width, newX)); - const clampedY = Math.max(workAreaY, Math.min(workAreaY + height - headerBounds.height, newY)); - - header.setPosition(clampedX, clampedY, false); - - updateLayout(); - } - }); - - ipcMain.handle('move-window-step', (event, direction) => { - if (movementManager) { - movementManager.moveStep(direction); - } - }); - - ipcMain.handle('force-close-window', (event, windowName) => { - const window = windowPool.get(windowName); - if (window && !window.isDestroyed()) { - console.log(`[WindowManager] Force closing window: ${windowName}`); - - window.webContents.send('window-hide-animation'); - - setTimeout(() => { - if (!window.isDestroyed()) { - window.hide(); - updateLayout(); - } - }, 250); - } - }); - - ipcMain.handle('start-screen-capture', async () => { - try { - isCapturing = true; - console.log('Starting screen capture in main process'); - return { success: true }; - } catch (error) { - console.error('Failed to start screen capture:', error); - return { success: false, error: error.message }; - } - }); - - ipcMain.handle('stop-screen-capture', async () => { - try { - isCapturing = false; - lastScreenshot = null; - console.log('Stopped screen capture in main process'); - return { success: true }; - } catch (error) { - console.error('Failed to stop screen capture:', error); - return { success: false, error: error.message }; - } - }); - - ipcMain.handle('capture-screenshot', async (event, options = {}) => { - return captureScreenshot(options); - }); - - ipcMain.handle('get-current-screenshot', async event => { - try { - if (lastScreenshot && Date.now() - lastScreenshot.timestamp < 1000) { - console.log('Returning cached screenshot'); - return { - success: true, - base64: lastScreenshot.base64, - width: lastScreenshot.width, - height: lastScreenshot.height, - }; - } - return { - success: false, - error: 'No screenshot available', - }; - } catch (error) { - console.error('Failed to get current screenshot:', error); - return { - success: false, - error: error.message, - }; - } - }); - - ipcMain.handle('firebase-logout', async () => { - console.log('[WindowManager] Received request to log out.'); - - await authService.signOut(); - await setApiKey(null); - - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-removed'); - } - }); - }); - - ipcMain.handle('check-system-permissions', async () => { - const { systemPreferences } = require('electron'); - const permissions = { - microphone: 'unknown', - screen: 'unknown', - needsSetup: true - }; - - try { - if (process.platform === 'darwin') { - // Check microphone permission on macOS - const micStatus = systemPreferences.getMediaAccessStatus('microphone'); - console.log('[Permissions] Microphone status:', micStatus); - permissions.microphone = micStatus; - - // Check screen recording permission using the system API - const screenStatus = systemPreferences.getMediaAccessStatus('screen'); - console.log('[Permissions] Screen status:', screenStatus); - permissions.screen = screenStatus; - - permissions.needsSetup = micStatus !== 'granted' || screenStatus !== 'granted'; - } else { - permissions.microphone = 'granted'; - permissions.screen = 'granted'; - permissions.needsSetup = false; - } - - console.log('[Permissions] System permissions status:', permissions); - return permissions; - } catch (error) { - console.error('[Permissions] Error checking permissions:', error); - return { - microphone: 'unknown', - screen: 'unknown', - needsSetup: true, - error: error.message - }; - } - }); - - ipcMain.handle('request-microphone-permission', async () => { - if (process.platform !== 'darwin') { - return { success: true }; - } - - const { systemPreferences } = require('electron'); - try { - const status = systemPreferences.getMediaAccessStatus('microphone'); - console.log('[Permissions] Microphone status:', status); - if (status === 'granted') { - return { success: true, status: 'granted' }; - } - - // Req mic permission - const granted = await systemPreferences.askForMediaAccess('microphone'); - return { - success: granted, - status: granted ? 'granted' : 'denied' - }; - } catch (error) { - console.error('[Permissions] Error requesting microphone permission:', error); - return { - success: false, - error: error.message - }; - } - }); - - ipcMain.handle('open-system-preferences', async (event, section) => { - if (process.platform !== 'darwin') { - return { success: false, error: 'Not supported on this platform' }; - } - - try { - if (section === 'screen-recording') { - // First trigger screen capture request to register the app in system preferences - try { - console.log('[Permissions] Triggering screen capture request to register app...'); - await desktopCapturer.getSources({ - types: ['screen'], - thumbnailSize: { width: 1, height: 1 } - }); - console.log('[Permissions] App registered for screen recording'); - } catch (captureError) { - console.log('[Permissions] Screen capture request triggered (expected to fail):', captureError.message); - } - - // Then open system preferences - // await shell.openExternal('x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture'); - } - // if (section === 'microphone') { - // await shell.openExternal('x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone'); - // } - return { success: true }; - } catch (error) { - console.error('[Permissions] Error opening system preferences:', error); - return { success: false, error: error.message }; - } - }); - - ipcMain.handle('mark-permissions-completed', async () => { - try { - // This is a system-level setting, not user-specific. - await systemSettingsRepository.markPermissionsAsCompleted(); - console.log('[Permissions] Marked permissions as completed'); - return { success: true }; - } catch (error) { - console.error('[Permissions] Error marking permissions as completed:', error); - return { success: false, error: error.message }; - } - }); - - ipcMain.handle('check-permissions-completed', async () => { - try { - const completed = await systemSettingsRepository.checkPermissionsCompleted(); - console.log('[Permissions] Permissions completed status:', completed); - return completed; - } catch (error) { - console.error('[Permissions] Error checking permissions completed status:', error); - return false; - } - }); - - ipcMain.handle('close-ask-window-if-empty', async () => { - const askWindow = windowPool.get('ask'); - if (askWindow && !askWindow.isFocused()) { - askWindow.hide(); - } - }); -} - - -async function setApiKey(apiKey, provider = 'openai') { - console.log('[WindowManager] Persisting API key and provider to DB'); - - try { - await userRepository.saveApiKey(apiKey, authService.getCurrentUserId(), provider); - console.log('[WindowManager] API key and provider saved to SQLite'); - - // Notify authService that the key status may have changed - await authService.updateApiKeyStatus(); - - } catch (err) { - console.error('[WindowManager] Failed to save API key to SQLite:', err); - } - - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - const js = apiKey ? ` - localStorage.setItem('openai_api_key', ${JSON.stringify(apiKey)}); - localStorage.setItem('ai_provider', ${JSON.stringify(provider)}); - ` : ` - localStorage.removeItem('openai_api_key'); - localStorage.removeItem('ai_provider'); - `; - win.webContents.executeJavaScript(js).catch(() => {}); - } - }); -} - -async function getStoredApiKey() { - const userId = authService.getCurrentUserId(); - if (!userId) return null; - const user = await userRepository.getById(userId); - return user?.api_key || null; -} - -async function getStoredProvider() { - const userId = authService.getCurrentUserId(); - if (!userId) return 'openai'; - const user = await userRepository.getById(userId); - return user?.provider || 'openai'; -} - -function setupApiKeyIPC() { - const { ipcMain } = require('electron'); - - // Both handlers now do the same thing: fetch the key from the source of truth. - ipcMain.handle('get-stored-api-key', getStoredApiKey); - - ipcMain.handle('api-key-validated', async (event, data) => { - console.log('[WindowManager] API key validation completed, saving...'); - - // Support both old format (string) and new format (object) - const apiKey = typeof data === 'string' ? data : data.apiKey; - const provider = typeof data === 'string' ? 'openai' : (data.provider || 'openai'); - - await setApiKey(apiKey, provider); - - windowPool.forEach((win, name) => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-validated', { apiKey, provider }); - } - }); - - return { success: true }; - }); - - ipcMain.handle('remove-api-key', async () => { - console.log('[WindowManager] API key removal requested'); - await setApiKey(null); - - windowPool.forEach((win, name) => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-removed'); - } - }); - - const settingsWindow = windowPool.get('settings'); - if (settingsWindow && settingsWindow.isVisible()) { - settingsWindow.hide(); - console.log('[WindowManager] Settings window hidden after clearing API key.'); - } - - return { success: true }; - }); - - ipcMain.handle('get-ai-provider', getStoredProvider); - - console.log('[WindowManager] API key related IPC handlers registered (SQLite-backed)'); -} - - -function getDefaultKeybinds() { - const isMac = process.platform === 'darwin'; - return { - moveUp: isMac ? 'Cmd+Up' : 'Ctrl+Up', - moveDown: isMac ? 'Cmd+Down' : 'Ctrl+Down', - moveLeft: isMac ? 'Cmd+Left' : 'Ctrl+Left', - moveRight: isMac ? 'Cmd+Right' : 'Ctrl+Right', - toggleVisibility: isMac ? 'Cmd+\\' : 'Ctrl+\\', - toggleClickThrough: isMac ? 'Cmd+M' : 'Ctrl+M', - nextStep: isMac ? 'Cmd+Enter' : 'Ctrl+Enter', - manualScreenshot: isMac ? 'Cmd+Shift+S' : 'Ctrl+Shift+S', - previousResponse: isMac ? 'Cmd+[' : 'Ctrl+[', - nextResponse: isMac ? 'Cmd+]' : 'Ctrl+]', - scrollUp: isMac ? 'Cmd+Shift+Up' : 'Ctrl+Shift+Up', - scrollDown: isMac ? 'Cmd+Shift+Down' : 'Ctrl+Shift+Down', - }; -} - -function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementManager) { - console.log('Updating global shortcuts with:', keybinds); - - // Unregister all existing shortcuts - globalShortcut.unregisterAll(); - - let toggleVisibilityDebounceTimer = null; - - const isMac = process.platform === 'darwin'; - const modifier = isMac ? 'Cmd' : 'Ctrl'; - - if (keybinds.toggleVisibility) { - try { - globalShortcut.register(keybinds.toggleVisibility, () => toggleAllWindowsVisibility(movementManager)); - console.log(`Registered toggleVisibility: ${keybinds.toggleVisibility}`); - } catch (error) { - console.error(`Failed to register toggleVisibility (${keybinds.toggleVisibility}):`, error); - } - } - - const displays = screen.getAllDisplays(); - if (displays.length > 1) { - displays.forEach((display, index) => { - const key = `${modifier}+Shift+${index + 1}`; - try { - globalShortcut.register(key, () => { - movementManager.moveToDisplay(display.id); - }); - console.log(`Registered display switch shortcut: ${key} -> Display ${index + 1}`); - } catch (error) { - console.error(`Failed to register display switch ${key}:`, error); - } - }); - } - - if (currentHeaderState === 'apikey') { - console.log('ApiKeyHeader is active, skipping conditional shortcuts'); - return; - } - - const directions = [ - { key: `${modifier}+Left`, direction: 'left' }, - { key: `${modifier}+Right`, direction: 'right' }, - { key: `${modifier}+Up`, direction: 'up' }, - { key: `${modifier}+Down`, direction: 'down' }, - ]; - - directions.forEach(({ key, direction }) => { - try { - globalShortcut.register(key, () => { - const header = windowPool.get('header'); - if (header && header.isVisible()) { - movementManager.moveStep(direction); - } - }); - console.log(`Registered global shortcut: ${key} -> ${direction}`); - } catch (error) { - console.error(`Failed to register ${key}:`, error); - } - }); - - const edgeDirections = [ - { key: `${modifier}+Shift+Left`, direction: 'left' }, - { key: `${modifier}+Shift+Right`, direction: 'right' }, - { key: `${modifier}+Shift+Up`, direction: 'up' }, - { key: `${modifier}+Shift+Down`, direction: 'down' }, - ]; - - edgeDirections.forEach(({ key, direction }) => { - try { - globalShortcut.register(key, () => { - const header = windowPool.get('header'); - if (header && header.isVisible()) { - movementManager.moveToEdge(direction); - } - }); - console.log(`Registered global shortcut: ${key} -> edge ${direction}`); - } catch (error) { - console.error(`Failed to register ${key}:`, error); - } - }); - - if (keybinds.toggleClickThrough) { - try { - globalShortcut.register(keybinds.toggleClickThrough, () => { - mouseEventsIgnored = !mouseEventsIgnored; - if (mouseEventsIgnored) { - mainWindow.setIgnoreMouseEvents(true, { forward: true }); - console.log('Mouse events ignored'); - } else { - mainWindow.setIgnoreMouseEvents(false); - console.log('Mouse events enabled'); - } - mainWindow.webContents.send('click-through-toggled', mouseEventsIgnored); - }); - console.log(`Registered toggleClickThrough: ${keybinds.toggleClickThrough}`); - } catch (error) { - console.error(`Failed to register toggleClickThrough (${keybinds.toggleClickThrough}):`, error); - } - } - - if (keybinds.nextStep) { - try { - globalShortcut.register(keybinds.nextStep, () => { - console.log('⌘/Ctrl+Enter Ask shortcut triggered'); - - const askWindow = windowPool.get('ask'); - if (!askWindow || askWindow.isDestroyed()) { - console.error('Ask window not found or destroyed'); - return; - } - - if (askWindow.isVisible()) { - askWindow.webContents.send('ask-global-send'); - } else { - try { - askWindow.show(); - - const header = windowPool.get('header'); - if (header) { - const currentHeaderPosition = header.getBounds(); - updateLayout(); - header.setPosition(currentHeaderPosition.x, currentHeaderPosition.y, false); - } - - askWindow.webContents.send('window-show-animation'); - } catch (e) { - console.error('Error showing Ask window:', e); - } - } - }); - console.log(`Registered Ask shortcut (nextStep): ${keybinds.nextStep}`); - } catch (error) { - console.error(`Failed to register Ask shortcut (${keybinds.nextStep}):`, error); - } - } - - if (keybinds.manualScreenshot) { - try { - globalShortcut.register(keybinds.manualScreenshot, () => { - console.log('Manual screenshot shortcut triggered'); - mainWindow.webContents.executeJavaScript(` - if (window.captureManualScreenshot) { - window.captureManualScreenshot(); - } else { - console.log('Manual screenshot function not available'); - } - `); - }); - console.log(`Registered manualScreenshot: ${keybinds.manualScreenshot}`); - } catch (error) { - console.error(`Failed to register manualScreenshot (${keybinds.manualScreenshot}):`, error); - } - } - - if (keybinds.previousResponse) { - try { - globalShortcut.register(keybinds.previousResponse, () => { - console.log('Previous response shortcut triggered'); - sendToRenderer('navigate-previous-response'); - }); - console.log(`Registered previousResponse: ${keybinds.previousResponse}`); - } catch (error) { - console.error(`Failed to register previousResponse (${keybinds.previousResponse}):`, error); - } - } - - if (keybinds.nextResponse) { - try { - globalShortcut.register(keybinds.nextResponse, () => { - console.log('Next response shortcut triggered'); - sendToRenderer('navigate-next-response'); - }); - console.log(`Registered nextResponse: ${keybinds.nextResponse}`); - } catch (error) { - console.error(`Failed to register nextResponse (${keybinds.nextResponse}):`, error); - } - } - - if (keybinds.scrollUp) { - try { - globalShortcut.register(keybinds.scrollUp, () => { - console.log('Scroll up shortcut triggered'); - sendToRenderer('scroll-response-up'); - }); - console.log(`Registered scrollUp: ${keybinds.scrollUp}`); - } catch (error) { - console.error(`Failed to register scrollUp (${keybinds.scrollUp}):`, error); - } - } - - if (keybinds.scrollDown) { - try { - globalShortcut.register(keybinds.scrollDown, () => { - console.log('Scroll down shortcut triggered'); - sendToRenderer('scroll-response-down'); - }); - console.log(`Registered scrollDown: ${keybinds.scrollDown}`); - } catch (error) { - console.error(`Failed to register scrollDown (${keybinds.scrollDown}):`, error); - } - } -} - - -async function captureScreenshot(options = {}) { - if (process.platform === 'darwin') { - try { - const tempPath = path.join(os.tmpdir(), `screenshot-${Date.now()}.jpg`); - - await execFile('screencapture', ['-x', '-t', 'jpg', tempPath]); - - const imageBuffer = await fs.promises.readFile(tempPath); - await fs.promises.unlink(tempPath); - - const resizedBuffer = await sharp(imageBuffer) - // .resize({ height: 1080 }) - .resize({ height: 384 }) - .jpeg({ quality: 80 }) - .toBuffer(); - - const base64 = resizedBuffer.toString('base64'); - const metadata = await sharp(resizedBuffer).metadata(); - - lastScreenshot = { - base64, - width: metadata.width, - height: metadata.height, - timestamp: Date.now(), - }; - - return { success: true, base64, width: metadata.width, height: metadata.height }; - } catch (error) { - console.error('Failed to capture and resize screenshot:', error); - return { success: false, error: error.message }; - } - } - - try { - const sources = await desktopCapturer.getSources({ - types: ['screen'], - thumbnailSize: { - width: 1920, - height: 1080, - }, - }); - - if (sources.length === 0) { - throw new Error('No screen sources available'); - } - const source = sources[0]; - const buffer = source.thumbnail.toJPEG(70); - const base64 = buffer.toString('base64'); - const size = source.thumbnail.getSize(); - - return { - success: true, - base64, - width: size.width, - height: size.height, - }; - } catch (error) { - console.error('Failed to capture screenshot using desktopCapturer:', error); - return { - success: false, - error: error.message, - }; - } -} - -module.exports = { - createWindows, - windowPool, - fixedYPosition, - setApiKey, - getStoredApiKey, - getStoredProvider, - captureScreenshot, -}; \ No newline at end of file From 3f9a2ba3eba415640c6b7526eb955155852c5a58 Mon Sep 17 00:00:00 2001 From: Surya <125463872+Surya-sourav@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:25:22 +0530 Subject: [PATCH 25/52] Add files via upload --- src/electron/windowManager.js | 1502 +++++++++++++++++++++++++++++++++ 1 file changed, 1502 insertions(+) create mode 100644 src/electron/windowManager.js diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js new file mode 100644 index 0000000..4b540f6 --- /dev/null +++ b/src/electron/windowManager.js @@ -0,0 +1,1502 @@ +const { BrowserWindow, globalShortcut, ipcMain, screen, app, shell, desktopCapturer } = require('electron'); +const WindowLayoutManager = require('./windowLayoutManager'); +const SmoothMovementManager = require('./smoothMovementManager'); +const path = require('node:path'); +const fs = require('node:fs'); +const os = require('os'); +const util = require('util'); +const execFile = util.promisify(require('child_process').execFile); +const sharp = require('sharp'); +const authService = require('../common/services/authService'); +const systemSettingsRepository = require('../common/repositories/systemSettings'); +const userRepository = require('../common/repositories/user'); +const fetch = require('node-fetch'); + + +/* ────────────────[ GLASS BYPASS ]─────────────── */ +let liquidGlass; +const isLiquidGlassSupported = () => { + if (process.platform !== 'darwin') { + return false; + } + const majorVersion = parseInt(os.release().split('.')[0], 10); + // return majorVersion >= 25; // macOS 26+ (Darwin 25+) + return majorVersion >= 26; // See you soon! +}; +let shouldUseLiquidGlass = isLiquidGlassSupported(); +if (shouldUseLiquidGlass) { + try { + liquidGlass = require('electron-liquid-glass'); + } catch (e) { + console.warn('Could not load optional dependency "electron-liquid-glass". The feature will be disabled.'); + shouldUseLiquidGlass = false; + } +} +/* ────────────────[ GLASS BYPASS ]─────────────── */ + +let isContentProtectionOn = true; +let currentDisplayId = null; + +let mouseEventsIgnored = false; +let lastVisibleWindows = new Set(['header']); +const HEADER_HEIGHT = 47; +const DEFAULT_WINDOW_WIDTH = 353; + +let currentHeaderState = 'apikey'; +const windowPool = new Map(); +let fixedYPosition = 0; +let lastScreenshot = null; + +let settingsHideTimer = null; + +let selectedCaptureSourceId = null; + +let layoutManager = null; +function updateLayout() { + if (layoutManager) { + layoutManager.updateLayout(); + } +} + +let movementManager = null; + +let storedProvider = 'openai'; + +const featureWindows = ['listen','ask','settings']; +function isAllowed(name) { + if (name === 'header') return true; + return featureWindows.includes(name) && currentHeaderState === 'main'; +} + +function createFeatureWindows(header) { + if (windowPool.has('listen')) return; + + const commonChildOptions = { + parent: header, + show: false, + frame: false, + transparent: true, + vibrancy: false, + hasShadow: false, + skipTaskbar: true, + hiddenInMissionControl: true, + resizable: false, + webPreferences: { nodeIntegration: true, contextIsolation: false }, + }; + + // listen + const listen = new BrowserWindow({ + ...commonChildOptions, width:400,minWidth:400,maxWidth:400, + maxHeight:700, + }); + listen.setContentProtection(isContentProtectionOn); + listen.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); + if (process.platform === 'darwin') { + listen.setWindowButtonVisibility(false); + } + const listenLoadOptions = { query: { view: 'listen' } }; + if (!shouldUseLiquidGlass) { + listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); + } + else { + listenLoadOptions.query.glass = 'true'; + listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); + listen.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(listen.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + + + windowPool.set('listen', listen); + + // ask + const ask = new BrowserWindow({ ...commonChildOptions, width:600 }); + ask.setContentProtection(isContentProtectionOn); + ask.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); + if (process.platform === 'darwin') { + ask.setWindowButtonVisibility(false); + } + const askLoadOptions = { query: { view: 'ask' } }; + if (!shouldUseLiquidGlass) { + ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); + } + else { + askLoadOptions.query.glass = 'true'; + ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); + ask.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(ask.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + + ask.on('blur',()=>ask.webContents.send('window-blur')); + + // Open DevTools in development + if (!app.isPackaged) { + ask.webContents.openDevTools({ mode: 'detach' }); + } + windowPool.set('ask', ask); + + // settings + const settings = new BrowserWindow({ ...commonChildOptions, width:240, maxHeight:400, parent:undefined }); + settings.setContentProtection(isContentProtectionOn); + settings.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); + if (process.platform === 'darwin') { + settings.setWindowButtonVisibility(false); + } + const settingsLoadOptions = { query: { view: 'settings' } }; + if (!shouldUseLiquidGlass) { + settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) + .catch(console.error); + } + else { + settingsLoadOptions.query.glass = 'true'; + settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) + .catch(console.error); + settings.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(settings.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + windowPool.set('settings', settings); +} + +function destroyFeatureWindows() { + if (settingsHideTimer) { + clearTimeout(settingsHideTimer); + settingsHideTimer = null; + } + featureWindows.forEach(name=>{ + const win = windowPool.get(name); + if (win && !win.isDestroyed()) win.destroy(); + windowPool.delete(name); + }); +} + + +function getCurrentDisplay(window) { + if (!window || window.isDestroyed()) return screen.getPrimaryDisplay(); + + const windowBounds = window.getBounds(); + const windowCenter = { + x: windowBounds.x + windowBounds.width / 2, + y: windowBounds.y + windowBounds.height / 2, + }; + + return screen.getDisplayNearestPoint(windowCenter); +} + +function getDisplayById(displayId) { + const displays = screen.getAllDisplays(); + return displays.find(d => d.id === displayId) || screen.getPrimaryDisplay(); +} + + + +function toggleAllWindowsVisibility(movementManager) { + const header = windowPool.get('header'); + if (!header) return; + + if (header.isVisible()) { + console.log('[Visibility] Smart hiding - calculating nearest edge'); + + const headerBounds = header.getBounds(); + const display = screen.getPrimaryDisplay(); + const { width: screenWidth, height: screenHeight } = display.workAreaSize; + + const centerX = headerBounds.x + headerBounds.width / 2; + const centerY = headerBounds.y + headerBounds.height / 2; + + const distances = { + top: centerY, + bottom: screenHeight - centerY, + left: centerX, + right: screenWidth - centerX, + }; + + const nearestEdge = Object.keys(distances).reduce((nearest, edge) => (distances[edge] < distances[nearest] ? edge : nearest)); + + console.log(`[Visibility] Nearest edge: ${nearestEdge} (distance: ${distances[nearestEdge].toFixed(1)}px)`); + + lastVisibleWindows.clear(); + lastVisibleWindows.add('header'); + + windowPool.forEach((win, name) => { + if (win.isVisible()) { + lastVisibleWindows.add(name); + if (name !== 'header') { + // win.webContents.send('window-hide-animation'); + // setTimeout(() => { + // if (!win.isDestroyed()) { + // win.hide(); + // } + // }, 200); + win.hide(); + } + } + }); + + console.log('[Visibility] Visible windows before hide:', Array.from(lastVisibleWindows)); + + movementManager.hideToEdge(nearestEdge, () => { + header.hide(); + console.log('[Visibility] Smart hide completed'); + }, { instant: true }); + } else { + console.log('[Visibility] Smart showing from hidden position'); + console.log('[Visibility] Restoring windows:', Array.from(lastVisibleWindows)); + + header.show(); + + movementManager.showFromEdge(() => { + lastVisibleWindows.forEach(name => { + if (name === 'header') return; + const win = windowPool.get(name); + if (win && !win.isDestroyed()) { + win.show(); + win.webContents.send('window-show-animation'); + } + }); + + setImmediate(updateLayout); + setTimeout(updateLayout, 120); + + console.log('[Visibility] Smart show completed'); + }); + } +} + + +function createWindows() { + const primaryDisplay = screen.getPrimaryDisplay(); + const { y: workAreaY, width: screenWidth } = primaryDisplay.workArea; + + const initialX = Math.round((screenWidth - DEFAULT_WINDOW_WIDTH) / 2); + const initialY = workAreaY + 21; + movementManager = new SmoothMovementManager(windowPool, getDisplayById, getCurrentDisplay, updateLayout); + + const header = new BrowserWindow({ + width: DEFAULT_WINDOW_WIDTH, + height: HEADER_HEIGHT, + x: initialX, + y: initialY, + frame: false, + transparent: true, + vibrancy: false, + alwaysOnTop: true, + skipTaskbar: true, + hiddenInMissionControl: true, + resizable: false, + focusable: true, + acceptFirstMouse: true, + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + backgroundThrottling: false, + webSecurity: false, + }, + }); + if (process.platform === 'darwin') { + header.setWindowButtonVisibility(false); + } + const headerLoadOptions = {}; + if (!shouldUseLiquidGlass) { + header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions); + } + else { + headerLoadOptions.query = { glass: 'true' }; + header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions); + header.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(header.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + windowPool.set('header', header); + layoutManager = new WindowLayoutManager(windowPool); + + header.webContents.once('dom-ready', () => { + loadAndRegisterShortcuts(movementManager); + }); + + setupIpcHandlers(movementManager); + + if (currentHeaderState === 'main') { + createFeatureWindows(header); + } + + header.setContentProtection(isContentProtectionOn); + header.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); + // header.loadFile(path.join(__dirname, '../app/header.html')); + + // Open DevTools in development + if (!app.isPackaged) { + header.webContents.openDevTools({ mode: 'detach' }); + } + + header.on('focus', () => { + console.log('[WindowManager] Header gained focus'); + }); + + header.on('blur', () => { + console.log('[WindowManager] Header lost focus'); + }); + + header.webContents.on('before-input-event', (event, input) => { + if (input.type === 'mouseDown') { + const target = input.target; + if (target && (target.includes('input') || target.includes('apikey'))) { + header.focus(); + } + } + }); + + header.on('resize', updateLayout); + + // header.webContents.once('dom-ready', () => { + // loadAndRegisterShortcuts(); + // }); + + ipcMain.handle('toggle-all-windows-visibility', () => toggleAllWindowsVisibility(movementManager)); + + ipcMain.handle('toggle-feature', async (event, featureName) => { + if (!windowPool.get(featureName) && currentHeaderState === 'main') { + createFeatureWindows(windowPool.get('header')); + } + + const windowToToggle = windowPool.get(featureName); + + if (windowToToggle) { + if (featureName === 'listen') { + const listenService = global.listenService; + if (listenService && listenService.isSessionActive()) { + console.log('[WindowManager] Listen session is active, closing it via toggle.'); + await listenService.closeSession(); + return; + } + } + console.log(`[WindowManager] Toggling feature: ${featureName}`); + } + + if (featureName === 'ask') { + let askWindow = windowPool.get('ask'); + + if (!askWindow || askWindow.isDestroyed()) { + console.log('[WindowManager] Ask window not found, creating new one'); + return; + } + + if (askWindow.isVisible()) { + try { + const hasResponse = await askWindow.webContents.executeJavaScript(` + (() => { + try { + // PickleGlassApp의 Shadow DOM 내부로 접근 + const pickleApp = document.querySelector('pickle-glass-app'); + if (!pickleApp || !pickleApp.shadowRoot) { + console.log('PickleGlassApp not found'); + return false; + } + + // PickleGlassApp의 shadowRoot 내부에서 ask-view 찾기 + const askView = pickleApp.shadowRoot.querySelector('ask-view'); + if (!askView) { + console.log('AskView not found in PickleGlassApp shadow DOM'); + return false; + } + + console.log('AskView found, checking state...'); + console.log('currentResponse:', askView.currentResponse); + console.log('isLoading:', askView.isLoading); + console.log('isStreaming:', askView.isStreaming); + + const hasContent = !!(askView.currentResponse || askView.isLoading || askView.isStreaming); + + if (!hasContent && askView.shadowRoot) { + const responseContainer = askView.shadowRoot.querySelector('.response-container'); + if (responseContainer && !responseContainer.classList.contains('hidden')) { + const textContent = responseContainer.textContent.trim(); + const hasActualContent = textContent && + !textContent.includes('Ask a question to see the response here') && + textContent.length > 0; + console.log('Response container content check:', hasActualContent); + return hasActualContent; + } + } + + return hasContent; + } catch (error) { + console.error('Error checking AskView state:', error); + return false; + } + })() + `); + + console.log(`[WindowManager] Ask window visible, hasResponse: ${hasResponse}`); + + if (hasResponse) { + askWindow.webContents.send('toggle-text-input'); + console.log('[WindowManager] Sent toggle-text-input command'); + } else { + console.log('[WindowManager] No response found, closing window'); + askWindow.webContents.send('window-hide-animation'); + + setTimeout(() => { + if (!askWindow.isDestroyed()) { + askWindow.hide(); + updateLayout(); + } + }, 250); + } + } catch (error) { + console.error('[WindowManager] Error checking Ask window state:', error); + console.log('[WindowManager] Falling back to toggle text input'); + askWindow.webContents.send('toggle-text-input'); + } + } else { + console.log('[WindowManager] Showing hidden Ask window'); + askWindow.show(); + updateLayout(); + askWindow.webContents.send('window-show-animation'); + askWindow.webContents.send('window-did-show'); + } + } else { + const windowToToggle = windowPool.get(featureName); + + if (windowToToggle) { + if (windowToToggle.isDestroyed()) { + console.error(`Window ${featureName} is destroyed, cannot toggle`); + return; + } + + if (windowToToggle.isVisible()) { + if (featureName === 'settings') { + windowToToggle.webContents.send('settings-window-hide-animation'); + } else { + windowToToggle.webContents.send('window-hide-animation'); + } + + setTimeout(() => { + if (!windowToToggle.isDestroyed()) { + windowToToggle.hide(); + updateLayout(); + } + }, 250); + } else { + try { + windowToToggle.show(); + updateLayout(); + + if (featureName === 'listen') { + windowToToggle.webContents.send('start-listening-session'); + } + + windowToToggle.webContents.send('window-show-animation'); + } catch (e) { + console.error('Error showing window:', e); + } + } + } else { + console.error(`Window not found for feature: ${featureName}`); + console.error('Available windows:', Array.from(windowPool.keys())); + } + } + }); + + ipcMain.handle('send-question-to-ask', (event, question) => { + const askWindow = windowPool.get('ask'); + if (askWindow && !askWindow.isDestroyed()) { + console.log('📨 Main process: Sending question to AskView', question); + askWindow.webContents.send('receive-question-from-assistant', question); + return { success: true }; + } else { + console.error('❌ Cannot find AskView window'); + return { success: false, error: 'AskView window not found' }; + } + }); + + ipcMain.handle('adjust-window-height', (event, targetHeight) => { + const senderWindow = BrowserWindow.fromWebContents(event.sender); + if (senderWindow) { + const wasResizable = senderWindow.isResizable(); + if (!wasResizable) { + senderWindow.setResizable(true); + } + + const currentBounds = senderWindow.getBounds(); + const minHeight = senderWindow.getMinimumSize()[1]; + const maxHeight = senderWindow.getMaximumSize()[1]; + + let adjustedHeight; + if (maxHeight === 0) { + adjustedHeight = Math.max(minHeight, targetHeight); + } else { + adjustedHeight = Math.max(minHeight, Math.min(maxHeight, targetHeight)); + } + + senderWindow.setSize(currentBounds.width, adjustedHeight, false); + + if (!wasResizable) { + senderWindow.setResizable(false); + } + + updateLayout(); + } + }); + + ipcMain.on('session-did-close', () => { + const listenWindow = windowPool.get('listen'); + if (listenWindow && listenWindow.isVisible()) { + console.log('[WindowManager] Session closed, hiding listen window.'); + listenWindow.hide(); + } + }); + + // setupIpcHandlers(); + + return windowPool; +} + +function loadAndRegisterShortcuts(movementManager) { + const defaultKeybinds = getDefaultKeybinds(); + const header = windowPool.get('header'); + const sendToRenderer = (channel, ...args) => { + windowPool.forEach(win => { + try { + if (win && !win.isDestroyed()) { + win.webContents.send(channel, ...args); + } + } catch (e) {} + }); + }; + + + if (!header) { + return updateGlobalShortcuts(defaultKeybinds, undefined, sendToRenderer, movementManager); + } + + header.webContents + .executeJavaScript(`(() => localStorage.getItem('customKeybinds'))()`) + .then(saved => (saved ? JSON.parse(saved) : {})) + .then(savedKeybinds => { + const keybinds = { ...defaultKeybinds, ...savedKeybinds }; + updateGlobalShortcuts(keybinds, header, sendToRenderer, movementManager); + }) + .catch(() => updateGlobalShortcuts(defaultKeybinds, header, sendToRenderer, movementManager)); +} + + +function setupIpcHandlers(movementManager) { + screen.on('display-added', (event, newDisplay) => { + console.log('[Display] New display added:', newDisplay.id); + }); + + screen.on('display-removed', (event, oldDisplay) => { + console.log('[Display] Display removed:', oldDisplay.id); + const header = windowPool.get('header'); + if (header && getCurrentDisplay(header).id === oldDisplay.id) { + const primaryDisplay = screen.getPrimaryDisplay(); + movementManager.moveToDisplay(primaryDisplay.id); + } + }); + + screen.on('display-metrics-changed', (event, display, changedMetrics) => { + console.log('[Display] Display metrics changed:', display.id, changedMetrics); + updateLayout(); + }); + + // 1. 스트리밍 데이터 조각(chunk)을 받아서 ask 창으로 전달 + ipcMain.on('ask-response-chunk', (event, { token }) => { + const askWindow = windowPool.get('ask'); + if (askWindow && !askWindow.isDestroyed()) { + // renderer.js가 보낸 토큰을 AskView.js로 그대로 전달합니다. + askWindow.webContents.send('ask-response-chunk', { token }); + } + }); + + // 2. 스트리밍 종료 신호를 받아서 ask 창으로 전달 + ipcMain.on('ask-response-stream-end', () => { + const askWindow = windowPool.get('ask'); + if (askWindow && !askWindow.isDestroyed()) { + askWindow.webContents.send('ask-response-stream-end'); + } + }); + + ipcMain.on('show-window', (event, args) => { + const { name, bounds } = typeof args === 'object' && args !== null ? args : { name: args, bounds: null }; + const win = windowPool.get(name); + + if (win && !win.isDestroyed()) { + if (settingsHideTimer) { + clearTimeout(settingsHideTimer); + settingsHideTimer = null; + } + + if (name === 'settings') { + // Adjust position based on button bounds + const header = windowPool.get('header'); + const headerBounds = header?.getBounds() ?? { x: 0, y: 0 }; + const settingsBounds = win.getBounds(); + + const disp = getCurrentDisplay(header); + const { x: waX, y: waY, width: waW, height: waH } = disp.workArea; + + let x = Math.round(headerBounds.x + (bounds?.x ?? 0) + (bounds?.width ?? 0) / 2 - settingsBounds.width / 2); + let y = Math.round(headerBounds.y + (bounds?.y ?? 0) + (bounds?.height ?? 0) + 31); + + x = Math.max(waX + 10, Math.min(waX + waW - settingsBounds.width - 10, x)); + y = Math.max(waY + 10, Math.min(waY + waH - settingsBounds.height - 10, y)); + + win.setBounds({ x, y }); + win.__lockedByButton = true; + console.log(`[WindowManager] Positioning settings window at (${x}, ${y}) based on button bounds.`); + } + + win.show(); + win.moveTop(); + + if (name === 'settings') { + win.setAlwaysOnTop(true); + } + // updateLayout(); + } + }); + + ipcMain.on('hide-window', (event, name) => { + const window = windowPool.get(name); + if (window && !window.isDestroyed()) { + if (name === 'settings') { + if (settingsHideTimer) { + clearTimeout(settingsHideTimer); + } + settingsHideTimer = setTimeout(() => { + // window.setAlwaysOnTop(false); + // window.hide(); + if (window && !window.isDestroyed()) { + window.setAlwaysOnTop(false); + window.hide(); + } + settingsHideTimer = null; + }, 200); + } else { + window.hide(); + } + window.__lockedByButton = false; + } + }); + + ipcMain.on('cancel-hide-window', (event, name) => { + if (name === 'settings' && settingsHideTimer) { + clearTimeout(settingsHideTimer); + settingsHideTimer = null; + } + }); + + ipcMain.handle('hide-all', () => { + windowPool.forEach(win => { + if (win.isFocused()) return; + win.hide(); + }); + }); + + ipcMain.handle('quit-application', () => { + app.quit(); + }); + + ipcMain.handle('is-window-visible', (event, windowName) => { + const window = windowPool.get(windowName); + if (window && !window.isDestroyed()) { + return window.isVisible(); + } + return false; + }); + + + ipcMain.handle('toggle-content-protection', () => { + isContentProtectionOn = !isContentProtectionOn; + console.log(`[Protection] Content protection toggled to: ${isContentProtectionOn}`); + windowPool.forEach(win => { + if (win && !win.isDestroyed()) { + win.setContentProtection(isContentProtectionOn); + } + }); + return isContentProtectionOn; + }); + + ipcMain.handle('get-content-protection-status', () => { + return isContentProtectionOn; + }); + + ipcMain.on('header-state-changed', (event, state) => { + console.log(`[WindowManager] Header state changed to: ${state}`); + currentHeaderState = state; + + if (state === 'main') { + createFeatureWindows(windowPool.get('header')); + } else { // 'apikey' | 'permission' + destroyFeatureWindows(); + } + + for (const [name, win] of windowPool) { + if (!isAllowed(name) && !win.isDestroyed()) { + win.hide(); + } + if (isAllowed(name) && win.isVisible()) { + win.show(); + } + } + + const header = windowPool.get('header'); + if (header && !header.isDestroyed()) { + header.webContents + .executeJavaScript(`(() => localStorage.getItem('customKeybinds'))()`) + .then(saved => { + const defaultKeybinds = getDefaultKeybinds(); + const savedKeybinds = saved ? JSON.parse(saved) : {}; + const keybinds = { ...defaultKeybinds, ...savedKeybinds }; + + const sendToRenderer = (channel, ...args) => { + windowPool.forEach(win => { + try { + if (win && !win.isDestroyed()) { + win.webContents.send(channel, ...args); + } + } catch (e) {} + }); + }; + + updateGlobalShortcuts(keybinds, header, sendToRenderer, movementManager); + }) + .catch(console.error); + } + }); + + ipcMain.on('update-keybinds', (event, newKeybinds) => { + updateGlobalShortcuts(newKeybinds); + }); + + ipcMain.handle('open-login-page', () => { + const webUrl = process.env.pickleglass_WEB_URL || 'http://localhost:3000'; + const personalizeUrl = `${webUrl}/personalize?desktop=true`; + shell.openExternal(personalizeUrl); + console.log('Opening personalization page:', personalizeUrl); + }); + + setupApiKeyIPC(); + + ipcMain.handle('resize-window', () => {}); + + ipcMain.handle('resize-for-view', () => {}); + + ipcMain.handle('resize-header-window', (event, { width, height }) => { + const header = windowPool.get('header'); + if (header) { + const wasResizable = header.isResizable(); + if (!wasResizable) { + header.setResizable(true); + } + + const bounds = header.getBounds(); + const newX = bounds.x + Math.round((bounds.width - width) / 2); + + header.setBounds({ x: newX, y: bounds.y, width, height }); + + if (!wasResizable) { + header.setResizable(false); + } + return { success: true }; + } + return { success: false, error: 'Header window not found' }; + }); + + ipcMain.on('header-animation-complete', (event, state) => { + const header = windowPool.get('header'); + if (!header) return; + + if (state === 'hidden') { + header.hide(); + } else if (state === 'visible') { + lastVisibleWindows.forEach(name => { + if (name === 'header') return; + const win = windowPool.get(name); + if (win) win.show(); + }); + + setImmediate(updateLayout); + setTimeout(updateLayout, 120); + } + }); + + ipcMain.handle('get-header-position', () => { + const header = windowPool.get('header'); + if (header) { + const [x, y] = header.getPosition(); + return { x, y }; + } + return { x: 0, y: 0 }; + }); + + ipcMain.handle('move-header', (event, newX, newY) => { + const header = windowPool.get('header'); + if (header) { + const currentY = newY !== undefined ? newY : header.getBounds().y; + header.setPosition(newX, currentY, false); + + updateLayout(); + } + }); + + ipcMain.handle('move-header-to', (event, newX, newY) => { + const header = windowPool.get('header'); + if (header) { + const targetDisplay = screen.getDisplayNearestPoint({ x: newX, y: newY }); + const { x: workAreaX, y: workAreaY, width, height } = targetDisplay.workArea; + const headerBounds = header.getBounds(); + + const clampedX = Math.max(workAreaX, Math.min(workAreaX + width - headerBounds.width, newX)); + const clampedY = Math.max(workAreaY, Math.min(workAreaY + height - headerBounds.height, newY)); + + header.setPosition(clampedX, clampedY, false); + + updateLayout(); + } + }); + + ipcMain.handle('move-window-step', (event, direction) => { + if (movementManager) { + movementManager.moveStep(direction); + } + }); + + ipcMain.handle('force-close-window', (event, windowName) => { + const window = windowPool.get(windowName); + if (window && !window.isDestroyed()) { + console.log(`[WindowManager] Force closing window: ${windowName}`); + + window.webContents.send('window-hide-animation'); + + setTimeout(() => { + if (!window.isDestroyed()) { + window.hide(); + updateLayout(); + } + }, 250); + } + }); + + ipcMain.handle('start-screen-capture', async () => { + try { + isCapturing = true; + console.log('Starting screen capture in main process'); + return { success: true }; + } catch (error) { + console.error('Failed to start screen capture:', error); + return { success: false, error: error.message }; + } + }); + + ipcMain.handle('stop-screen-capture', async () => { + try { + isCapturing = false; + lastScreenshot = null; + console.log('Stopped screen capture in main process'); + return { success: true }; + } catch (error) { + console.error('Failed to stop screen capture:', error); + return { success: false, error: error.message }; + } + }); + + ipcMain.handle('capture-screenshot', async (event, options = {}) => { + return captureScreenshot(options); + }); + + ipcMain.handle('get-current-screenshot', async event => { + try { + if (lastScreenshot && Date.now() - lastScreenshot.timestamp < 1000) { + console.log('Returning cached screenshot'); + return { + success: true, + base64: lastScreenshot.base64, + width: lastScreenshot.width, + height: lastScreenshot.height, + }; + } + return { + success: false, + error: 'No screenshot available', + }; + } catch (error) { + console.error('Failed to get current screenshot:', error); + return { + success: false, + error: error.message, + }; + } + }); + + ipcMain.handle('firebase-logout', async () => { + console.log('[WindowManager] Received request to log out.'); + + await authService.signOut(); + await setApiKey(null); + + windowPool.forEach(win => { + if (win && !win.isDestroyed()) { + win.webContents.send('api-key-removed'); + } + }); + }); + + ipcMain.handle('check-system-permissions', async () => { + const { systemPreferences } = require('electron'); + const permissions = { + microphone: 'unknown', + screen: 'unknown', + needsSetup: true + }; + + try { + if (process.platform === 'darwin') { + // Check microphone permission on macOS + const micStatus = systemPreferences.getMediaAccessStatus('microphone'); + console.log('[Permissions] Microphone status:', micStatus); + permissions.microphone = micStatus; + + // Check screen recording permission using the system API + const screenStatus = systemPreferences.getMediaAccessStatus('screen'); + console.log('[Permissions] Screen status:', screenStatus); + permissions.screen = screenStatus; + + permissions.needsSetup = micStatus !== 'granted' || screenStatus !== 'granted'; + } else { + permissions.microphone = 'granted'; + permissions.screen = 'granted'; + permissions.needsSetup = false; + } + + console.log('[Permissions] System permissions status:', permissions); + return permissions; + } catch (error) { + console.error('[Permissions] Error checking permissions:', error); + return { + microphone: 'unknown', + screen: 'unknown', + needsSetup: true, + error: error.message + }; + } + }); + + ipcMain.handle('request-microphone-permission', async () => { + if (process.platform !== 'darwin') { + return { success: true }; + } + + const { systemPreferences } = require('electron'); + try { + const status = systemPreferences.getMediaAccessStatus('microphone'); + console.log('[Permissions] Microphone status:', status); + if (status === 'granted') { + return { success: true, status: 'granted' }; + } + + // Req mic permission + const granted = await systemPreferences.askForMediaAccess('microphone'); + return { + success: granted, + status: granted ? 'granted' : 'denied' + }; + } catch (error) { + console.error('[Permissions] Error requesting microphone permission:', error); + return { + success: false, + error: error.message + }; + } + }); + + ipcMain.handle('open-system-preferences', async (event, section) => { + if (process.platform !== 'darwin') { + return { success: false, error: 'Not supported on this platform' }; + } + + try { + if (section === 'screen-recording') { + // First trigger screen capture request to register the app in system preferences + try { + console.log('[Permissions] Triggering screen capture request to register app...'); + await desktopCapturer.getSources({ + types: ['screen'], + thumbnailSize: { width: 1, height: 1 } + }); + console.log('[Permissions] App registered for screen recording'); + } catch (captureError) { + console.log('[Permissions] Screen capture request triggered (expected to fail):', captureError.message); + } + + // Then open system preferences + // await shell.openExternal('x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture'); + } + // if (section === 'microphone') { + // await shell.openExternal('x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone'); + // } + return { success: true }; + } catch (error) { + console.error('[Permissions] Error opening system preferences:', error); + return { success: false, error: error.message }; + } + }); + + ipcMain.handle('mark-permissions-completed', async () => { + try { + // This is a system-level setting, not user-specific. + await systemSettingsRepository.markPermissionsAsCompleted(); + console.log('[Permissions] Marked permissions as completed'); + return { success: true }; + } catch (error) { + console.error('[Permissions] Error marking permissions as completed:', error); + return { success: false, error: error.message }; + } + }); + + ipcMain.handle('check-permissions-completed', async () => { + try { + const completed = await systemSettingsRepository.checkPermissionsCompleted(); + console.log('[Permissions] Permissions completed status:', completed); + return completed; + } catch (error) { + console.error('[Permissions] Error checking permissions completed status:', error); + return false; + } + }); + + ipcMain.handle('close-ask-window-if-empty', async () => { + const askWindow = windowPool.get('ask'); + if (askWindow && !askWindow.isFocused()) { + askWindow.hide(); + } + }); +} + + +async function setApiKey(apiKey, provider = 'openai') { + console.log('[WindowManager] Persisting API key and provider to DB'); + + try { + await userRepository.saveApiKey(apiKey, authService.getCurrentUserId(), provider); + console.log('[WindowManager] API key and provider saved to SQLite'); + + // Notify authService that the key status may have changed + await authService.updateApiKeyStatus(); + + } catch (err) { + console.error('[WindowManager] Failed to save API key to SQLite:', err); + } + + windowPool.forEach(win => { + if (win && !win.isDestroyed()) { + const js = apiKey ? ` + localStorage.setItem('openai_api_key', ${JSON.stringify(apiKey)}); + localStorage.setItem('ai_provider', ${JSON.stringify(provider)}); + ` : ` + localStorage.removeItem('openai_api_key'); + localStorage.removeItem('ai_provider'); + `; + win.webContents.executeJavaScript(js).catch(() => {}); + } + }); +} + +async function getStoredApiKey() { + const userId = authService.getCurrentUserId(); + if (!userId) return null; + const user = await userRepository.getById(userId); + return user?.api_key || null; +} + +async function getStoredProvider() { + const userId = authService.getCurrentUserId(); + if (!userId) return 'openai'; + const user = await userRepository.getById(userId); + return user?.provider || 'openai'; +} + +function setupApiKeyIPC() { + const { ipcMain } = require('electron'); + + // Both handlers now do the same thing: fetch the key from the source of truth. + ipcMain.handle('get-stored-api-key', getStoredApiKey); + + ipcMain.handle('api-key-validated', async (event, data) => { + console.log('[WindowManager] API key validation completed, saving...'); + + // Support both old format (string) and new format (object) + const apiKey = typeof data === 'string' ? data : data.apiKey; + const provider = typeof data === 'string' ? 'openai' : (data.provider || 'openai'); + + await setApiKey(apiKey, provider); + + windowPool.forEach((win, name) => { + if (win && !win.isDestroyed()) { + win.webContents.send('api-key-validated', { apiKey, provider }); + } + }); + + return { success: true }; + }); + + ipcMain.handle('remove-api-key', async () => { + console.log('[WindowManager] API key removal requested'); + await setApiKey(null); + + windowPool.forEach((win, name) => { + if (win && !win.isDestroyed()) { + win.webContents.send('api-key-removed'); + } + }); + + const settingsWindow = windowPool.get('settings'); + if (settingsWindow && settingsWindow.isVisible()) { + settingsWindow.hide(); + console.log('[WindowManager] Settings window hidden after clearing API key.'); + } + + return { success: true }; + }); + + ipcMain.handle('get-ai-provider', getStoredProvider); + + console.log('[WindowManager] API key related IPC handlers registered (SQLite-backed)'); +} + + +function getDefaultKeybinds() { + const isMac = process.platform === 'darwin'; + return { + moveUp: isMac ? 'Cmd+Up' : 'Ctrl+Up', + moveDown: isMac ? 'Cmd+Down' : 'Ctrl+Down', + moveLeft: isMac ? 'Cmd+Left' : 'Ctrl+Left', + moveRight: isMac ? 'Cmd+Right' : 'Ctrl+Right', + toggleVisibility: isMac ? 'Cmd+\\' : 'Ctrl+\\', + toggleClickThrough: isMac ? 'Cmd+M' : 'Ctrl+M', + nextStep: isMac ? 'Cmd+Enter' : 'Ctrl+Enter', + manualScreenshot: isMac ? 'Cmd+Shift+S' : 'Ctrl+Shift+S', + previousResponse: isMac ? 'Cmd+[' : 'Ctrl+[', + nextResponse: isMac ? 'Cmd+]' : 'Ctrl+]', + scrollUp: isMac ? 'Cmd+Shift+Up' : 'Ctrl+Shift+Up', + scrollDown: isMac ? 'Cmd+Shift+Down' : 'Ctrl+Shift+Down', + }; +} + +function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementManager) { + console.log('Updating global shortcuts with:', keybinds); + + // Unregister all existing shortcuts + globalShortcut.unregisterAll(); + + let toggleVisibilityDebounceTimer = null; + + const isMac = process.platform === 'darwin'; + const modifier = isMac ? 'Cmd' : 'Ctrl'; + + if (keybinds.toggleVisibility) { + try { + globalShortcut.register(keybinds.toggleVisibility, () => toggleAllWindowsVisibility(movementManager)); + console.log(`Registered toggleVisibility: ${keybinds.toggleVisibility}`); + } catch (error) { + console.error(`Failed to register toggleVisibility (${keybinds.toggleVisibility}):`, error); + } + } + + const displays = screen.getAllDisplays(); + if (displays.length > 1) { + displays.forEach((display, index) => { + const key = `${modifier}+Shift+${index + 1}`; + try { + globalShortcut.register(key, () => { + movementManager.moveToDisplay(display.id); + }); + console.log(`Registered display switch shortcut: ${key} -> Display ${index + 1}`); + } catch (error) { + console.error(`Failed to register display switch ${key}:`, error); + } + }); + } + + if (currentHeaderState === 'apikey') { + console.log('ApiKeyHeader is active, skipping conditional shortcuts'); + return; + } + + const directions = [ + { key: `${modifier}+Left`, direction: 'left' }, + { key: `${modifier}+Right`, direction: 'right' }, + { key: `${modifier}+Up`, direction: 'up' }, + { key: `${modifier}+Down`, direction: 'down' }, + ]; + + directions.forEach(({ key, direction }) => { + try { + globalShortcut.register(key, () => { + const header = windowPool.get('header'); + if (header && header.isVisible()) { + movementManager.moveStep(direction); + } + }); + console.log(`Registered global shortcut: ${key} -> ${direction}`); + } catch (error) { + console.error(`Failed to register ${key}:`, error); + } + }); + + const edgeDirections = [ + { key: `${modifier}+Shift+Left`, direction: 'left' }, + { key: `${modifier}+Shift+Right`, direction: 'right' }, + { key: `${modifier}+Shift+Up`, direction: 'up' }, + { key: `${modifier}+Shift+Down`, direction: 'down' }, + ]; + + edgeDirections.forEach(({ key, direction }) => { + try { + globalShortcut.register(key, () => { + const header = windowPool.get('header'); + if (header && header.isVisible()) { + movementManager.moveToEdge(direction); + } + }); + console.log(`Registered global shortcut: ${key} -> edge ${direction}`); + } catch (error) { + console.error(`Failed to register ${key}:`, error); + } + }); + + if (keybinds.toggleClickThrough) { + try { + globalShortcut.register(keybinds.toggleClickThrough, () => { + mouseEventsIgnored = !mouseEventsIgnored; + if (mouseEventsIgnored) { + mainWindow.setIgnoreMouseEvents(true, { forward: true }); + console.log('Mouse events ignored'); + } else { + mainWindow.setIgnoreMouseEvents(false); + console.log('Mouse events enabled'); + } + mainWindow.webContents.send('click-through-toggled', mouseEventsIgnored); + }); + console.log(`Registered toggleClickThrough: ${keybinds.toggleClickThrough}`); + } catch (error) { + console.error(`Failed to register toggleClickThrough (${keybinds.toggleClickThrough}):`, error); + } + } + + if (keybinds.nextStep) { + try { + globalShortcut.register(keybinds.nextStep, () => { + console.log('⌘/Ctrl+Enter Ask shortcut triggered'); + + const askWindow = windowPool.get('ask'); + if (!askWindow || askWindow.isDestroyed()) { + console.error('Ask window not found or destroyed'); + return; + } + + if (askWindow.isVisible()) { + askWindow.webContents.send('ask-global-send'); + } else { + try { + askWindow.show(); + + const header = windowPool.get('header'); + if (header) { + const currentHeaderPosition = header.getBounds(); + updateLayout(); + header.setPosition(currentHeaderPosition.x, currentHeaderPosition.y, false); + } + + askWindow.webContents.send('window-show-animation'); + } catch (e) { + console.error('Error showing Ask window:', e); + } + } + }); + console.log(`Registered Ask shortcut (nextStep): ${keybinds.nextStep}`); + } catch (error) { + console.error(`Failed to register Ask shortcut (${keybinds.nextStep}):`, error); + } + } + + if (keybinds.manualScreenshot) { + try { + globalShortcut.register(keybinds.manualScreenshot, () => { + console.log('Manual screenshot shortcut triggered'); + mainWindow.webContents.executeJavaScript(` + if (window.captureManualScreenshot) { + window.captureManualScreenshot(); + } else { + console.log('Manual screenshot function not available'); + } + `); + }); + console.log(`Registered manualScreenshot: ${keybinds.manualScreenshot}`); + } catch (error) { + console.error(`Failed to register manualScreenshot (${keybinds.manualScreenshot}):`, error); + } + } + + if (keybinds.previousResponse) { + try { + globalShortcut.register(keybinds.previousResponse, () => { + console.log('Previous response shortcut triggered'); + sendToRenderer('navigate-previous-response'); + }); + console.log(`Registered previousResponse: ${keybinds.previousResponse}`); + } catch (error) { + console.error(`Failed to register previousResponse (${keybinds.previousResponse}):`, error); + } + } + + if (keybinds.nextResponse) { + try { + globalShortcut.register(keybinds.nextResponse, () => { + console.log('Next response shortcut triggered'); + sendToRenderer('navigate-next-response'); + }); + console.log(`Registered nextResponse: ${keybinds.nextResponse}`); + } catch (error) { + console.error(`Failed to register nextResponse (${keybinds.nextResponse}):`, error); + } + } + + if (keybinds.scrollUp) { + try { + globalShortcut.register(keybinds.scrollUp, () => { + console.log('Scroll up shortcut triggered'); + sendToRenderer('scroll-response-up'); + }); + console.log(`Registered scrollUp: ${keybinds.scrollUp}`); + } catch (error) { + console.error(`Failed to register scrollUp (${keybinds.scrollUp}):`, error); + } + } + + if (keybinds.scrollDown) { + try { + globalShortcut.register(keybinds.scrollDown, () => { + console.log('Scroll down shortcut triggered'); + sendToRenderer('scroll-response-down'); + }); + console.log(`Registered scrollDown: ${keybinds.scrollDown}`); + } catch (error) { + console.error(`Failed to register scrollDown (${keybinds.scrollDown}):`, error); + } + } +} + + +async function captureScreenshot(options = {}) { + if (process.platform === 'darwin') { + try { + const tempPath = path.join(os.tmpdir(), `screenshot-${Date.now()}.jpg`); + + await execFile('screencapture', ['-x', '-t', 'jpg', tempPath]); + + const imageBuffer = await fs.promises.readFile(tempPath); + await fs.promises.unlink(tempPath); + + const resizedBuffer = await sharp(imageBuffer) + // .resize({ height: 1080 }) + .resize({ height: 384 }) + .jpeg({ quality: 80 }) + .toBuffer(); + + const base64 = resizedBuffer.toString('base64'); + const metadata = await sharp(resizedBuffer).metadata(); + + lastScreenshot = { + base64, + width: metadata.width, + height: metadata.height, + timestamp: Date.now(), + }; + + return { success: true, base64, width: metadata.width, height: metadata.height }; + } catch (error) { + console.error('Failed to capture and resize screenshot:', error); + return { success: false, error: error.message }; + } + } + + try { + const sources = await desktopCapturer.getSources({ + types: ['screen'], + thumbnailSize: { + width: 1920, + height: 1080, + }, + }); + + if (sources.length === 0) { + throw new Error('No screen sources available'); + } + const source = sources[0]; + const buffer = source.thumbnail.toJPEG(70); + const base64 = buffer.toString('base64'); + const size = source.thumbnail.getSize(); + + return { + success: true, + base64, + width: size.width, + height: size.height, + }; + } catch (error) { + console.error('Failed to capture screenshot using desktopCapturer:', error); + return { + success: false, + error: error.message, + }; + } +} + +module.exports = { + createWindows, + windowPool, + fixedYPosition, + setApiKey, + getStoredApiKey, + getStoredProvider, + captureScreenshot, +}; \ No newline at end of file From d2951f9fef99a1a3e411dd6b2a2adbd23e5e903f Mon Sep 17 00:00:00 2001 From: CarlosCommits <41172581+CarlosCommits@users.noreply.github.com> Date: Mon, 7 Jul 2025 08:22:08 -0400 Subject: [PATCH 26/52] Resolves an intermittent issue where the text input in the "Ask" window would not auto-focus on Windows (#41) --- src/features/ask/AskView.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/features/ask/AskView.js b/src/features/ask/AskView.js index 9565194..ca2a294 100644 --- a/src/features/ask/AskView.js +++ b/src/features/ask/AskView.js @@ -857,12 +857,7 @@ export class AskView extends LitElement { ipcRenderer.on('window-blur', this.handleWindowBlur); ipcRenderer.on('window-did-show', () => { if (!this.currentResponse && !this.isLoading && !this.isStreaming) { - setTimeout(() => { - const textInput = this.shadowRoot?.getElementById('textInput'); - if (textInput) { - textInput.focus(); - } - }, 100); + this.focusTextInput(); } }); @@ -1291,6 +1286,19 @@ export class AskView extends LitElement { if (changedProperties.has('showTextInput') || changedProperties.has('isLoading')) { this.adjustWindowHeightThrottled(); } + + if (changedProperties.has('showTeextInput') && this.showTextInput) { + this.focusTextInput(); + } + } + + focusTextInput(){ + requestAnimationFrame(() => { + const textInput = this.shadowRoot?.getElementById('textInput'); + if (textInput){ + textInput.focus(); + } + }); } firstUpdated() { From 2f7fa36f452bfda7663bc4c7cc2d471103f4e3dc Mon Sep 17 00:00:00 2001 From: samtiz Date: Mon, 7 Jul 2025 21:23:52 +0900 Subject: [PATCH 27/52] fix typo & build err --- electron-builder.yml | 1 - src/features/ask/AskView.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/electron-builder.yml b/electron-builder.yml index 153f3b5..35e6ed5 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -43,7 +43,6 @@ win: arch: x64 - target: portable arch: x64 - publisherName: Pickle Team requestedExecutionLevel: asInvoker # NSIS installer configuration for Windows diff --git a/src/features/ask/AskView.js b/src/features/ask/AskView.js index ca2a294..33cb43c 100644 --- a/src/features/ask/AskView.js +++ b/src/features/ask/AskView.js @@ -1287,7 +1287,7 @@ export class AskView extends LitElement { this.adjustWindowHeightThrottled(); } - if (changedProperties.has('showTeextInput') && this.showTextInput) { + if (changedProperties.has('showTextInput') && this.showTextInput) { this.focusTextInput(); } } From 96062e9b8d357967dd2e7d24e92723d6ee8ae4a3 Mon Sep 17 00:00:00 2001 From: samtiz Date: Mon, 7 Jul 2025 23:19:53 +0900 Subject: [PATCH 28/52] release v0.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0d27b52..b399345 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pickle-glass", "productName": "Glass", - "version": "0.2.0", + "version": "0.2.1", "description": "Cl*ely for Free", "main": "src/index.js", "scripts": { From 00db563fd3e5dd13bbfc506ad95c4c628eb83139 Mon Sep 17 00:00:00 2001 From: samtiz Date: Tue, 8 Jul 2025 01:36:15 +0900 Subject: [PATCH 29/52] fix db init issue + add CI workflow --- .github/workflows/build.yml | 34 ++++++++++++++++++++++++++++ src/index.js | 44 +++++++++++++++++++++---------------- 2 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..b8ae04a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,34 @@ +name: Build & Verify + +on: + push: + branches: [ "main" ] # Runs on every push to main branch + +jobs: + build: + # Currently runs on macOS only, can add windows-latest later + runs-on: macos-latest + + steps: + - name: 🚚 Checkout code + uses: actions/checkout@v4 + + - name: ⚙️ Setup Node.js environment + uses: actions/setup-node@v4 + with: + node-version: '20.x' # Node.js version compatible with project + cache: 'npm' # npm dependency caching for speed improvement + + - name: 📦 Install root dependencies + run: npm install + + - name: 🌐 Install and build web (Renderer) part + # Move to pickleglass_web directory and run commands + working-directory: ./pickleglass_web + run: | + npm install + npm run build + + - name: 🖥️ Build Electron app + # Run Electron build script from root directory + run: npm run build \ No newline at end of file diff --git a/src/index.js b/src/index.js index e0fcde4..52c057f 100644 --- a/src/index.js +++ b/src/index.js @@ -165,27 +165,33 @@ app.whenReady().then(async () => { // Initialize core services initializeFirebase(); - databaseInitializer.initialize() - .then(() => { - console.log('>>> [index.js] Database initialized successfully'); - - // Clean up zombie sessions from previous runs first - sessionRepository.endAllActiveSessions(); + try { + await databaseInitializer.initialize(); + console.log('>>> [index.js] Database initialized successfully'); + + // Clean up zombie sessions from previous runs first + sessionRepository.endAllActiveSessions(); - authService.initialize(); - listenService.setupIpcHandlers(); - askService.initialize(); - settingsService.initialize(); - setupGeneralIpcHandlers(); - }) - .catch(err => { - console.error('>>> [index.js] Database initialization failed - some features may not work', err); - }); + authService.initialize(); + listenService.setupIpcHandlers(); + askService.initialize(); + settingsService.initialize(); + setupGeneralIpcHandlers(); - WEB_PORT = await startWebStack(); - console.log('Web front-end listening on', WEB_PORT); - - createWindows(); + // Start web server and create windows ONLY after all initializations are successful + WEB_PORT = await startWebStack(); + console.log('Web front-end listening on', WEB_PORT); + + createWindows(); + + } catch (err) { + console.error('>>> [index.js] Database initialization failed - some features may not work', err); + // Optionally, show an error dialog to the user + dialog.showErrorBox( + 'Application Error', + 'A critical error occurred during startup. Some features might be disabled. Please restart the application.' + ); + } initAutoUpdater(); From 6a0d8d35c46dc22bd0d9306accaefe0bf71057d8 Mon Sep 17 00:00:00 2001 From: samtiz Date: Tue, 8 Jul 2025 01:40:01 +0900 Subject: [PATCH 30/52] feat: Track package-lock.json for CI --- .gitignore | 1 - package-lock.json | 12077 ++++++++++++++++++++++++++++ pickleglass_web/package-lock.json | 6976 ++++++++++++++++ 3 files changed, 19053 insertions(+), 1 deletion(-) create mode 100644 package-lock.json create mode 100644 pickleglass_web/package-lock.json diff --git a/.gitignore b/.gitignore index 09f6325..776dab2 100644 --- a/.gitignore +++ b/.gitignore @@ -102,7 +102,6 @@ pickleglass_web/venv/ node_modules/ npm-debug.log yarn-error.log -package-lock.json # Database data/*.db diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..edabde8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,12077 @@ +{ + "name": "pickle-glass", + "version": "0.2.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "pickle-glass", + "version": "0.2.1", + "hasInstallScript": true, + "license": "GPL-3.0", + "dependencies": { + "@google/genai": "^1.8.0", + "@google/generative-ai": "^0.24.1", + "axios": "^1.10.0", + "better-sqlite3": "^9.4.3", + "cors": "^2.8.5", + "dotenv": "^17.0.0", + "electron-squirrel-startup": "^1.0.1", + "electron-store": "^8.2.0", + "electron-updater": "^6.6.2", + "express": "^4.18.2", + "firebase": "^11.10.0", + "firebase-admin": "^13.4.0", + "jsonwebtoken": "^9.0.2", + "node-fetch": "^2.7.0", + "openai": "^4.70.0", + "react-hot-toast": "^2.5.2", + "sharp": "^0.34.2", + "validator": "^13.11.0", + "wait-on": "^8.0.3", + "ws": "^8.18.0" + }, + "devDependencies": { + "@electron-forge/cli": "^7.8.1", + "@electron-forge/maker-deb": "^7.8.1", + "@electron-forge/maker-dmg": "^7.8.1", + "@electron-forge/maker-rpm": "^7.8.1", + "@electron-forge/maker-squirrel": "^7.8.1", + "@electron-forge/maker-zip": "^7.8.1", + "@electron-forge/plugin-auto-unpack-natives": "^7.8.1", + "@electron-forge/plugin-fuses": "^7.8.1", + "@electron/fuses": "^1.8.0", + "@electron/notarize": "^2.5.0", + "electron": "^30.5.1", + "electron-builder": "^26.0.12", + "electron-reloader": "^1.2.3", + "esbuild": "^0.25.5" + }, + "optionalDependencies": { + "electron-liquid-glass": "^1.0.1" + } + }, + "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-forge/cli": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-7.8.1.tgz", + "integrity": "sha512-QI3EShutfq9Y+2TWWrPjm4JZM3eSAKzoQvRZdVhAfVpUbyJ8K23VqJShg3kGKlPf9BXHAGvE+8LyH5s2yDr1qA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-cli?utm_medium=referral&utm_source=npm_fund" + } + ], + "license": "MIT", + "dependencies": { + "@electron-forge/core": "7.8.1", + "@electron-forge/core-utils": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "@electron/get": "^3.0.0", + "chalk": "^4.0.0", + "commander": "^11.1.0", + "debug": "^4.3.1", + "fs-extra": "^10.0.0", + "listr2": "^7.0.2", + "log-symbols": "^4.0.0", + "semver": "^7.2.1" + }, + "bin": { + "electron-forge": "dist/electron-forge.js", + "electron-forge-vscode-nix": "script/vscode.sh", + "electron-forge-vscode-win": "script/vscode.cmd" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/core": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-7.8.1.tgz", + "integrity": "sha512-jkh0QPW5p0zmruu1E8+2XNufc4UMxy13WLJcm7hn9jbaXKLkMbKuEvhrN1tH/9uGp1mhr/t8sC4N67gP+gS87w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-core?utm_medium=referral&utm_source=npm_fund" + } + ], + "license": "MIT", + "dependencies": { + "@electron-forge/core-utils": "7.8.1", + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/plugin-base": "7.8.1", + "@electron-forge/publisher-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "@electron-forge/template-base": "7.8.1", + "@electron-forge/template-vite": "7.8.1", + "@electron-forge/template-vite-typescript": "7.8.1", + "@electron-forge/template-webpack": "7.8.1", + "@electron-forge/template-webpack-typescript": "7.8.1", + "@electron-forge/tracer": "7.8.1", + "@electron/get": "^3.0.0", + "@electron/packager": "^18.3.5", + "@electron/rebuild": "^3.7.0", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.3.1", + "fast-glob": "^3.2.7", + "filenamify": "^4.1.0", + "find-up": "^5.0.0", + "fs-extra": "^10.0.0", + "global-dirs": "^3.0.0", + "got": "^11.8.5", + "interpret": "^3.1.1", + "jiti": "^2.4.2", + "listr2": "^7.0.2", + "lodash": "^4.17.20", + "log-symbols": "^4.0.0", + "node-fetch": "^2.6.7", + "rechoir": "^0.8.0", + "semver": "^7.2.1", + "source-map-support": "^0.5.13", + "sudo-prompt": "^9.1.1", + "username": "^5.1.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/core-utils": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/core-utils/-/core-utils-7.8.1.tgz", + "integrity": "sha512-mRoPLDNZgmjyOURE/K0D3Op53XGFmFRgfIvFC7c9S/BqsRpovVblrqI4XxPRdNmH9dvhd8On9gGz+XIYAKD3aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "@electron/rebuild": "^3.7.0", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.3.1", + "find-up": "^5.0.0", + "fs-extra": "^10.0.0", + "log-symbols": "^4.0.0", + "semver": "^7.2.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/maker-base": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-7.8.1.tgz", + "integrity": "sha512-GUZqschGuEBzSzE0bMeDip65IDds48DZXzldlRwQ+85SYVA6RMU2AwDDqx3YiYsvP2OuxKruuqIJZtOF5ps4FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "fs-extra": "^10.0.0", + "which": "^2.0.2" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/maker-deb": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-deb/-/maker-deb-7.8.1.tgz", + "integrity": "sha512-tjjeesQtCP5Xht1X7gl4+K9bwoETPmQfBkOVAY/FZIxPj40uQh/hOUtLX2tYENNGNVZ1ryDYRs8TuPi+I41Vfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + }, + "optionalDependencies": { + "electron-installer-debian": "^3.2.0" + } + }, + "node_modules/@electron-forge/maker-dmg": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-dmg/-/maker-dmg-7.8.1.tgz", + "integrity": "sha512-l449QvY2Teu+J9rHnjkTHEm/wOJ1LRfmrQ2QkGtFoTRcqvFWdUAEN8nK2/08w3j2h6tvOY3QSUjRzXrhJZRNRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + }, + "optionalDependencies": { + "electron-installer-dmg": "^5.0.1" + } + }, + "node_modules/@electron-forge/maker-rpm": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-rpm/-/maker-rpm-7.8.1.tgz", + "integrity": "sha512-TF6wylft3BHkw9zdHcxmjEPBZYgTIc0jE31skFnMEQ/aExbNRiNaCZvsXy+7ptTWZxhxUKRc9KHhLFRMCmOK8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + }, + "optionalDependencies": { + "electron-installer-redhat": "^3.2.0" + } + }, + "node_modules/@electron-forge/maker-squirrel": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-squirrel/-/maker-squirrel-7.8.1.tgz", + "integrity": "sha512-qT1PMvT7ALF0ONOkxlA0oc0PiFuKCAKgoMPoxYo9gGOqFvnAb+TBcnLxflQ4ashE/ZkrHpykr4LcDJxqythQTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + }, + "optionalDependencies": { + "electron-winstaller": "^5.3.0" + } + }, + "node_modules/@electron-forge/maker-zip": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-zip/-/maker-zip-7.8.1.tgz", + "integrity": "sha512-unIxEoV1lnK4BLVqCy3L2y897fTyg8nKY1WT4rrpv0MUKnQG4qmigDfST5zZNNHHaulEn/ElAic2GEiP7d6bhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "cross-zip": "^4.0.0", + "fs-extra": "^10.0.0", + "got": "^11.8.5" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/plugin-auto-unpack-natives": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/plugin-auto-unpack-natives/-/plugin-auto-unpack-natives-7.8.1.tgz", + "integrity": "sha512-4URAgWX9qqqKe6Bfad0VmpFRrwINYMODfKGd2nFQrfHxmBtdpXnsWlLwVGE/wGssIQaTMI5bWQ6F2RNeXTgnhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/plugin-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/plugin-base": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/plugin-base/-/plugin-base-7.8.1.tgz", + "integrity": "sha512-iCZC2d7CbsZ9l6j5d+KPIiyQx0U1QBfWAbKnnQhWCSizjcrZ7A9V4sMFZeTO6+PVm48b/r9GFPm+slpgZtYQLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/plugin-fuses": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/plugin-fuses/-/plugin-fuses-7.8.1.tgz", + "integrity": "sha512-dYTwvbV1HcDOIQ0wTybpdtPq6YoBYXIWBTb7DJuvFu/c/thj1eoEdnbwr8mT9hEivjlu5p4ls46n16P5EtZ0oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/plugin-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + }, + "peerDependencies": { + "@electron/fuses": ">=1.0.0" + } + }, + "node_modules/@electron-forge/publisher-base": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/publisher-base/-/publisher-base-7.8.1.tgz", + "integrity": "sha512-z2C+C4pcFxyCXIFwXGDcxhU8qtVUPZa3sPL6tH5RuMxJi77768chLw2quDWk2/dfupcSELXcOMYCs7aLysCzeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/shared-types": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/shared-types/-/shared-types-7.8.1.tgz", + "integrity": "sha512-guLyGjIISKQQRWHX+ugmcjIOjn2q/BEzCo3ioJXFowxiFwmZw/oCZ2KlPig/t6dMqgUrHTH5W/F0WKu0EY4M+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/tracer": "7.8.1", + "@electron/packager": "^18.3.5", + "@electron/rebuild": "^3.7.0", + "listr2": "^7.0.2" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-base": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/template-base/-/template-base-7.8.1.tgz", + "integrity": "sha512-k8jEUr0zWFWb16ZGho+Es2OFeKkcbTgbC6mcH4eNyF/sumh/4XZMcwRtX1i7EiZAYiL9sVxyI6KVwGu254g+0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/core-utils": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.3.1", + "fs-extra": "^10.0.0", + "username": "^5.1.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-vite": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/template-vite/-/template-vite-7.8.1.tgz", + "integrity": "sha512-qzSlJaBYYqQAbBdLk4DqAE3HCNz4yXbpkb+VC74ddL4JGwPdPU57DjCthr6YetKJ2FsOVy9ipovA8HX5UbXpAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "@electron-forge/template-base": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-vite-typescript": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/template-vite-typescript/-/template-vite-typescript-7.8.1.tgz", + "integrity": "sha512-CccQhwUjZcc6svzuOi3BtbDal591DzyX2J5GPa6mwVutDP8EMtqJL1VyOHdcWO/7XjI6GNAD0fiXySOJiUAECA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "@electron-forge/template-base": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-webpack": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-7.8.1.tgz", + "integrity": "sha512-DA77o9kTCHrq+W211pyNP49DyAt0d1mzMp2gisyNz7a+iKvlv2DsMAeRieLoCQ44akb/z8ZsL0YLteSjKLy4AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "@electron-forge/template-base": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-webpack-typescript": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-7.8.1.tgz", + "integrity": "sha512-h922E+6zWwym1RT6WKD79BLTc4H8YxEMJ7wPWkBX59kw/exsTB/KFdiJq6r82ON5jSJ+Q8sDGqSmDWdyCfo+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "@electron-forge/template-base": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/tracer": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/tracer/-/tracer-7.8.1.tgz", + "integrity": "sha512-r2i7aHVp2fylGQSPDw3aTcdNfVX9cpL1iL2MKHrCRNwgrfR+nryGYg434T745GGm1rNQIv5Egdkh5G9xf00oWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chrome-trace-event": "^1.0.3" + }, + "engines": { + "node": ">= 14.17.5" + } + }, + "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/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/@electron/fuses": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@electron/fuses/-/fuses-1.8.0.tgz", + "integrity": "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.1", + "fs-extra": "^9.0.1", + "minimist": "^1.2.5" + }, + "bin": { + "electron-fuses": "dist/bin.js" + } + }, + "node_modules/@electron/fuses/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/get": { + "version": "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/@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/@electron/get/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@electron/get/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@electron/node-gyp": { + "version": "10.2.0-electron.1", + "resolved": "git+ssh://git@github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "integrity": "sha512-CrYo6TntjpoMO1SHjl5Pa/JoUsECNqNdB7Kx49WLQpWzPw53eEITJ2Hs9fh/ryUYDn4pxZz11StaBYBrLFJdqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^8.1.0", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.2.1", + "nopt": "^6.0.0", + "proc-log": "^2.0.1", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@electron/node-gyp/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@electron/node-gyp/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@electron/node-gyp/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/notarize": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz", + "integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/notarize/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/osx-sign": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.3.tgz", + "integrity": "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@electron/packager": { + "version": "18.3.6", + "resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.3.6.tgz", + "integrity": "sha512-1eXHB5t+SQKvUiDpWGpvr90ZSSbXj+isrh3YbjCTjKT4bE4SQrKSBfukEAaBvp67+GXHFtCHjQgN9qSTFIge+Q==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@electron/asar": "^3.2.13", + "@electron/get": "^3.0.0", + "@electron/notarize": "^2.1.0", + "@electron/osx-sign": "^1.0.5", + "@electron/universal": "^2.0.1", + "@electron/windows-sign": "^1.0.0", + "debug": "^4.0.1", + "extract-zip": "^2.0.0", + "filenamify": "^4.1.0", + "fs-extra": "^11.1.0", + "galactus": "^1.0.0", + "get-package-info": "^1.0.0", + "junk": "^3.1.0", + "parse-author": "^2.0.0", + "plist": "^3.0.0", + "resedit": "^2.0.0", + "resolve": "^1.1.6", + "semver": "^7.1.3", + "yargs-parser": "^21.1.1" + }, + "bin": { + "electron-packager": "bin/electron-packager.js" + }, + "engines": { + "node": ">= 16.13.0" + }, + "funding": { + "url": "https://github.com/electron/packager?sponsor=1" + } + }, + "node_modules/@electron/packager/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/rebuild": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.2.tgz", + "integrity": "sha512-19/KbIR/DAxbsCkiaGMXIdPnMCJLkcf8AvGnduJtWBs/CBwiAjY1apCqOLVxrXg+rtXFCngbXhBanWjxLUt1Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@electron/universal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.3.tgz", + "integrity": "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@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/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@electron/windows-sign": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz", + "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==", + "dev": true, + "license": "BSD-2-Clause", + "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.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fastify/busboy": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz", + "integrity": "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==", + "license": "MIT" + }, + "node_modules/@firebase/ai": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-1.4.1.tgz", + "integrity": "sha512-bcusQfA/tHjUjBTnMx6jdoPMpDl3r8K15Z+snHz9wq0Foox0F/V+kNLXucEOHoTL2hTc9l+onZCyBJs2QoIC3g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/analytics": { + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.17.tgz", + "integrity": "sha512-n5vfBbvzduMou/2cqsnKrIes4auaBjdhg8QNA2ZQZ59QgtO2QiwBaXQZQE4O4sgB0Ds1tvLgUUkY+pwzu6/xEg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.23.tgz", + "integrity": "sha512-3AdO10RN18G5AzREPoFgYhW6vWXr3u+OYQv6pl3CX6Fky8QRk0AHurZlY3Q1xkXO0TDxIsdhO3y65HF7PBOJDw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/analytics": "0.10.17", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.2.tgz", + "integrity": "sha512-jwtMmJa1BXXDCiDx1vC6SFN/+HfYG53UkfJa6qeN5ogvOunzbFDO3wISZy5n9xgYFUrEP6M7e8EG++riHNTv9w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.10.1.tgz", + "integrity": "sha512-MgNdlms9Qb0oSny87pwpjKush9qUwCJhfmTJHDfrcKo4neLGiSeVE4qJkzP7EQTIUFKp84pbTxobSAXkiuQVYQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.26.tgz", + "integrity": "sha512-PkX+XJMLDea6nmnopzFKlr+s2LMQGqdyT2DHdbx1v1dPSqOol2YzgpgymmhC67vitXVpNvS3m/AiWQWWhhRRPQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check": "0.10.1", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-compat": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.4.2.tgz", + "integrity": "sha512-LssbyKHlwLeiV8GBATyOyjmHcMpX/tFjzRUCS1jnwGAew1VsBB4fJowyS5Ud5LdFbYpJeS+IQoC+RQxpK7eH3Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app": "0.13.2", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth": { + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", + "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.5.28", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.28.tgz", + "integrity": "sha512-HpMSo/cc6Y8IX7bkRIaPPqT//Jt83iWy5rmDWeThXQCAImstkdNo3giFLORJwrZw2ptiGkOij64EH1ztNJzc7Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth": "1.10.8", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-types": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.18.tgz", + "integrity": "sha512-n28kPCkE2dL2U28fSxZJjzPPVpKsQminJ6NrzcKXAI0E/lYC8YhfwpyllScqVEvAI3J2QgJZWYgrX+1qGI+SQQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/data-connect": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.10.tgz", + "integrity": "sha512-VMVk7zxIkgwlVQIWHOKFahmleIjiVFwFOjmakXPd/LDgaB/5vzwsB5DWIYo+3KhGxWpidQlR8geCIn39YflJIQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/database": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.20.tgz", + "integrity": "sha512-H9Rpj1pQ1yc9+4HQOotFGLxqAXwOzCHsRSRjcQFNOr8lhUt6LeYjf0NSRL04sc4X0dWe8DsCvYKxMYvFG/iOJw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.11.tgz", + "integrity": "sha512-itEsHARSsYS95+udF/TtIzNeQ0Uhx4uIna0sk4E0wQJBUnLc/G1X6D7oRljoOuwwCezRLGvWBRyNrugv/esOEw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/database": "1.0.20", + "@firebase/database-types": "1.0.15", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.15.tgz", + "integrity": "sha512-XWHJ0VUJ0k2E9HDMlKxlgy/ZuTa9EvHCGLjaKSUvrQnwhgZuRU5N3yX6SZ+ftf2hTzZmfRkv+b3QRvGg40bKNw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.12.1" + } + }, + "node_modules/@firebase/firestore": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.8.0.tgz", + "integrity": "sha512-QSRk+Q1/CaabKyqn3C32KSFiOdZpSqI9rpLK5BHPcooElumOBooPFa6YkDdiT+/KhJtel36LdAacha9BptMj2A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "@firebase/webchannel-wrapper": "1.0.3", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.3.53", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.53.tgz", + "integrity": "sha512-qI3yZL8ljwAYWrTousWYbemay2YZa+udLWugjdjju2KODWtLG94DfO4NALJgPLv8CVGcDHNFXoyQexdRA0Cz8Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/firestore": "4.8.0", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.12.9", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.9.tgz", + "integrity": "sha512-FG95w6vjbUXN84Ehezc2SDjGmGq225UYbHrb/ptkRT7OTuCiQRErOQuyt1jI1tvcDekdNog+anIObihNFz79Lg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.26.tgz", + "integrity": "sha512-A798/6ff5LcG2LTWqaGazbFYnjBW8zc65YfID/en83ALmkhu2b0G8ykvQnLtakbV9ajrMYPn7Yc/XcYsZIUsjA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/functions": "0.12.9", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/installations": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.18.tgz", + "integrity": "sha512-NQ86uGAcvO8nBRwVltRL9QQ4Reidc/3whdAasgeWCPIcrhOKDuNpAALa6eCVryLnK14ua2DqekCOX5uC9XbU/A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.18.tgz", + "integrity": "sha512-aLFohRpJO5kKBL/XYL4tN+GdwEB/Q6Vo9eZOM/6Kic7asSUgmSfGPpGUZO1OAaSRGwF4Lqnvi1f/f9VZnKzChw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.12.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.22.tgz", + "integrity": "sha512-GJcrPLc+Hu7nk+XQ70Okt3M1u1eRr2ZvpMbzbc54oTPJZySHcX9ccZGVFcsZbSZ6o1uqumm8Oc7OFkD3Rn1/og==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.22.tgz", + "integrity": "sha512-5ZHtRnj6YO6f/QPa/KU6gryjmX4Kg33Kn4gRpNU6M1K47Gm8kcQwPkX7erRUYEH1mIWptfvjvXMHWoZaWjkU7A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/messaging": "0.12.22", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/performance": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.7.tgz", + "integrity": "sha512-JTlTQNZKAd4+Q5sodpw6CN+6NmwbY72av3Lb6wUKTsL7rb3cuBIhQSrslWbVz0SwK3x0ZNcqX24qtRbwKiv+6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.20", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.20.tgz", + "integrity": "sha512-XkFK5NmOKCBuqOKWeRgBUFZZGz9SzdTZp4OqeUg+5nyjapTiZ4XoiiUL8z7mB2q+63rPmBl7msv682J3rcDXIQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/performance": "0.7.7", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/remote-config": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.5.tgz", + "integrity": "sha512-fU0c8HY0vrVHwC+zQ/fpXSqHyDMuuuglV94VF6Yonhz8Fg2J+KOowPGANM0SZkLvVOYpTeWp3ZmM+F6NjwWLnw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.18.tgz", + "integrity": "sha512-YiETpldhDy7zUrnS8e+3l7cNs0sL7+tVAxvVYU0lu7O+qLHbmdtAxmgY+wJqWdW2c9nDvBFec7QiF58pEUu0qQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/remote-config": "0.6.5", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/storage": { + "version": "0.13.14", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.14.tgz", + "integrity": "sha512-xTq5ixxORzx+bfqCpsh+o3fxOsGoDjC1nO0Mq2+KsOcny3l7beyBhP/y1u5T6mgsFQwI1j6oAkbT5cWdDBx87g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.24.tgz", + "integrity": "sha512-XHn2tLniiP7BFKJaPZ0P8YQXKiVJX+bMyE2j2YWjYfaddqiJnROJYqSomwW6L3Y+gZAga35ONXUJQju6MB6SOQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/storage": "0.13.14", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.1.tgz", + "integrity": "sha512-zGlBn/9Dnya5ta9bX/fgEoNC3Cp8s6h+uYPYaDieZsFOAdHP/ExzQ/eaDgxD3GOROdPkLKpvKY0iIzr9adle0w==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", + "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==", + "license": "Apache-2.0" + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@google-cloud/firestore": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.2.tgz", + "integrity": "sha512-BQCSbjWJndCZ6bj8BSGhi4EM1TDFs9HgZXXsJ7d2kEPo+x64fB3OnQE8ffmn3vWADqeAmYBPaMPF/k6PHETXKA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@opentelemetry/api": "^1.3.0", + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^4.3.3", + "protobufjs": "^7.2.6" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", + "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.16.0.tgz", + "integrity": "sha512-7/5LRgykyOfQENcm6hDKP8SX/u9XxE5YOiWOkgkwcoO+cG8xT/cyOvp9wwN3IxfdYgpHs8CE7Nq2PKX2lNaEXw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "<4.1.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "duplexify": "^4.1.3", + "fast-xml-parser": "^4.4.1", + "gaxios": "^6.0.2", + "google-auth-library": "^9.6.3", + "html-entities": "^2.5.2", + "mime": "^3.0.0", + "p-limit": "^3.0.1", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@google-cloud/storage/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@google/genai": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.8.0.tgz", + "integrity": "sha512-n3KiMFesQCy2R9iSdBIuJ0JWYQ1HZBJJkmt4PPZMGZKvlgHhBAGw1kUMyX+vsAIzprN3lK45DI755lm70wPOOg==", + "license": "Apache-2.0", + "dependencies": { + "google-auth-library": "^9.14.2", + "ws": "^8.18.0", + "zod": "^3.22.4", + "zod-to-json-schema": "^3.22.4" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.11.0" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@google/generative-ai": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz", + "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz", + "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz", + "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", + "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", + "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", + "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", + "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", + "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", + "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", + "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", + "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", + "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.2.tgz", + "integrity": "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.2.tgz", + "integrity": "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.2.tgz", + "integrity": "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.2.tgz", + "integrity": "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.2.tgz", + "integrity": "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.2.tgz", + "integrity": "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.2.tgz", + "integrity": "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.4.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.2.tgz", + "integrity": "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.2.tgz", + "integrity": "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.2.tgz", + "integrity": "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "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/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "license": "BSD-3-Clause" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/appdmg": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@types/appdmg/-/appdmg-0.5.5.tgz", + "integrity": "sha512-G+n6DgZTZFOteITE30LnWj+HRVIGr7wMlAiLWOO02uJFWVEitaPU9JVXm9wJokkgshBawb2O1OykdcsmkkZfgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.10", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", + "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", + "license": "MIT", + "dependencies": { + "@types/ms": "*", + "@types/node": "*" + } + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.4.tgz", + "integrity": "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.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/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/request/node_modules/form-data": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.3.tgz", + "integrity": "sha512-XHIrMD0NpDrNM/Ckf7XJiBbLl57KEhT3+i3yY+eWm+cqYZJQTZrKo8Y8AWKnuV5GT4scfuUGt9LzNoIx3dU1nQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.35", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/verror": { + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", + "integrity": "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "dev": true, + "license": "MIT", + "engines": { + "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": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "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": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "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-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/app-builder-bin": { + "version": "5.0.0-alpha.12", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz", + "integrity": "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/app-builder-lib": { + "version": "26.0.12", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.0.12.tgz", + "integrity": "sha512-+/CEPH1fVKf6HowBUs6LcAIoRcjeqgvAeoSE+cl7Y7LndyQ9ViGPYibNk7wmhMHzNgHIuIbw4nWADPO+4mjgWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@develar/schema-utils": "~2.6.5", + "@electron/asar": "3.2.18", + "@electron/fuses": "^1.8.0", + "@electron/notarize": "2.5.0", + "@electron/osx-sign": "1.3.1", + "@electron/rebuild": "3.7.0", + "@electron/universal": "2.0.1", + "@malept/flatpak-bundler": "^0.4.0", + "@types/fs-extra": "9.0.13", + "async-exit-hook": "^2.0.1", + "builder-util": "26.0.11", + "builder-util-runtime": "9.3.1", + "chromium-pickle-js": "^0.2.0", + "config-file-ts": "0.2.8-rc1", + "debug": "^4.3.4", + "dotenv": "^16.4.5", + "dotenv-expand": "^11.0.6", + "ejs": "^3.1.8", + "electron-publish": "26.0.11", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", + "is-ci": "^3.0.0", + "isbinaryfile": "^5.0.0", + "js-yaml": "^4.1.0", + "json5": "^2.2.3", + "lazy-val": "^1.0.5", + "minimatch": "^10.0.0", + "plist": "3.1.0", + "resedit": "^1.7.0", + "semver": "^7.3.8", + "tar": "^6.1.12", + "temp-file": "^3.4.0", + "tiny-async-pool": "1.3.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "dmg-builder": "26.0.12", + "electron-builder-squirrel-windows": "26.0.12" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/asar": { + "version": "3.2.18", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.18.tgz", + "integrity": "sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/asar/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/osx-sign": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.1.tgz", + "integrity": "sha512-BAfviURMHpmb1Yb50YbCxnOY0wfwaLXH5KJ4+80zS0gUkzDX3ec23naTlEqKsN+PwYn+a1cCzM7BJ4Wcd3sGzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "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/app-builder-lib/node_modules/@electron/osx-sign/node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/rebuild": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.0.tgz", + "integrity": "sha512-VW++CNSlZwMYP7MyXEbrKjpzEwhB5kDNbzGtiPEjwYysqyTCF+YbNJ210Dj3AjWsGSV4iEEwNkmJN9yGZmVvmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/universal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz", + "integrity": "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/asar": "^3.2.7", + "@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/app-builder-lib/node_modules/@electron/universal/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/app-builder-lib/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/app-builder-lib/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/app-builder-lib/node_modules/isbinaryfile": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.4.tgz", + "integrity": "sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/app-builder-lib/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/app-builder-lib/node_modules/pe-library": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz", + "integrity": "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/app-builder-lib/node_modules/resedit": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/resedit/-/resedit-1.7.2.tgz", + "integrity": "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pe-library": "^0.4.1" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/appdmg": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/appdmg/-/appdmg-0.6.6.tgz", + "integrity": "sha512-GRmFKlCG+PWbcYF4LUNonTYmy0GjguDy6Jh9WP8mpd0T6j80XIJyXBiWlD0U+MLNhqV9Nhx49Gl9GpVToulpLg==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "async": "^1.4.2", + "ds-store": "^0.1.5", + "execa": "^1.0.0", + "fs-temp": "^1.0.0", + "fs-xattr": "^0.3.0", + "image-size": "^0.7.4", + "is-my-json-valid": "^2.20.0", + "minimist": "^1.1.3", + "parse-color": "^1.0.0", + "path-exists": "^4.0.0", + "repeat-string": "^1.5.4" + }, + "bin": { + "appdmg": "bin/appdmg.js" + }, + "engines": { + "node": ">=8.5" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "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": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "license": "MIT", + "optional": true, + "dependencies": { + "retry": "0.13.1" + } + }, + "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": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", + "license": "MIT", + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/author-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", + "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/axios": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base32-encode": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/base32-encode/-/base32-encode-1.2.0.tgz", + "integrity": "sha512-cHFU8XeRyx0GgmoWi5qHMCVRiqU6J3MHWxVgun7jggCBUpVzm1Ir7M9dYr2whjSNc3tFeXfQ/oZjQu/4u55h9A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "to-data-view": "^1.1.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/better-sqlite3": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.6.0.tgz", + "integrity": "sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + } + }, + "node_modules/bignumber.js": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.0.tgz", + "integrity": "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/bplist-creator": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", + "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "stream-buffers": "~2.2.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/builder-util": { + "version": "26.0.11", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.0.11.tgz", + "integrity": "sha512-xNjXfsldUEe153h1DraD0XvDOpqGR0L5eKFkdReB7eFW5HqysDZFfly4rckda6y9dF39N3pkPlOblcfHKGw+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/debug": "^4.1.6", + "7zip-bin": "~5.2.0", + "app-builder-bin": "5.0.0-alpha.12", + "builder-util-runtime": "9.3.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", + "is-ci": "^3.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.3.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.3.1.tgz", + "integrity": "sha512-2/egrNDDnRaxVwK3A+cJq6UOlqOdedGA7JPqCeJjN2Zjk1/QB/6QUi3b714ScIGS7HafFXTyzJEOr5b44I3kvQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "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": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", + "license": "MIT", + "dependencies": { + "ajv": "^8.6.3", + "ajv-formats": "^2.1.1", + "atomically": "^1.7.0", + "debounce-fn": "^4.0.0", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", + "json-schema-typed": "^7.0.3", + "onetime": "^5.1.2", + "pkg-up": "^3.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conf/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "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/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/config-file-ts": { + "version": "0.2.8-rc1", + "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.8-rc1.tgz", + "integrity": "sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^10.3.12", + "typescript": "^5.4.3" + } + }, + "node_modules/config-file-ts/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/config-file-ts/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/config-file-ts/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/config-file-ts/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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" + }, + "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-zip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-4.0.1.tgz", + "integrity": "sha512-n63i0lZ0rvQ6FXiGQ+/JFCKAUyPFhLQYJIqKaa+tSJtfKeULF/IDNDAbdnSIxgS4NTuw2b0+lj8LzfITuq+ZxQ==", + "dev": true, + "funding": [ + { + "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", + "engines": { + "node": ">=12.10" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/date-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", + "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "time-zone": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/debounce-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/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-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/dir-compare": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz", + "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5", + "p-limit": "^3.1.0 " + } + }, + "node_modules/dmg-builder": { + "version": "26.0.12", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.0.12.tgz", + "integrity": "sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "26.0.12", + "builder-util": "26.0.11", + "builder-util-runtime": "9.3.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-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/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotenv": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.0.1.tgz", + "integrity": "sha512-GLjkduuAL7IMJg/ZnOPm9AnWKJ82mSE2tzXLaJ/6hD6DhwGfZaXG77oB8qbReyiczNxnbxQKyh0OE5mXq0bAHA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "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/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/ds-store": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ds-store/-/ds-store-0.1.6.tgz", + "integrity": "sha512-kY21M6Lz+76OS3bnCzjdsJSF7LBpLYGCVfavW8TgQD2XkcqIZ86W0y9qUDZu6fp7SIZzqosMDW2zi7zVFfv4hw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bplist-creator": "~0.0.3", + "macos-alias": "~0.2.5", + "tn1150": "^0.1.0" + } + }, + "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/duplexify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-30.5.1.tgz", + "integrity": "sha512-AhL7+mZ8Lg14iaNfoYTkXQ2qee8mmsQyllKdqxlpv/zrKgfxz6jNVtcRRbQtLxtF8yzcImWdfTQROpYiPumdbw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, + "node_modules/electron-builder": { + "version": "26.0.12", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.0.12.tgz", + "integrity": "sha512-cD1kz5g2sgPTMFHjLxfMjUK5JABq3//J4jPswi93tOPFz6btzXYtK5NrDt717NRbukCUDOrrvmYVOWERlqoiXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "26.0.12", + "builder-util": "26.0.11", + "builder-util-runtime": "9.3.1", + "chalk": "^4.1.2", + "dmg-builder": "26.0.12", + "fs-extra": "^10.1.0", + "is-ci": "^3.0.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.0.12", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.0.12.tgz", + "integrity": "sha512-kpwXM7c/ayRUbYVErQbsZ0nQZX4aLHQrPEG9C4h9vuJCXylwFH8a7Jgi2VpKIObzCXO7LKHiCw4KdioFLFOgqA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "app-builder-lib": "26.0.12", + "builder-util": "26.0.11", + "electron-winstaller": "5.4.0" + } + }, + "node_modules/electron-installer-common": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/electron-installer-common/-/electron-installer-common-0.10.4.tgz", + "integrity": "sha512-8gMNPXfAqUE5CfXg8RL0vXpLE9HAaPkgLXVoHE3BMUzogMWenf4LmwQ27BdCUrEhkjrKl+igs2IHJibclR3z3Q==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@electron/asar": "^3.2.5", + "@malept/cross-spawn-promise": "^1.0.0", + "debug": "^4.1.1", + "fs-extra": "^9.0.0", + "glob": "^7.1.4", + "lodash": "^4.17.15", + "parse-author": "^2.0.0", + "semver": "^7.1.1", + "tmp-promise": "^3.0.2" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "url": "https://github.com/electron-userland/electron-installer-common?sponsor=1" + }, + "optionalDependencies": { + "@types/fs-extra": "^9.0.1" + } + }, + "node_modules/electron-installer-common/node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "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", + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/electron-installer-common/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "optional": true, + "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-installer-debian": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/electron-installer-debian/-/electron-installer-debian-3.2.0.tgz", + "integrity": "sha512-58ZrlJ1HQY80VucsEIG9tQ//HrTlG6sfofA3nRGr6TmkX661uJyu4cMPPh6kXW+aHdq/7+q25KyQhDrXvRL7jw==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin", + "linux" + ], + "dependencies": { + "@malept/cross-spawn-promise": "^1.0.0", + "debug": "^4.1.1", + "electron-installer-common": "^0.10.2", + "fs-extra": "^9.0.0", + "get-folder-size": "^2.0.1", + "lodash": "^4.17.4", + "word-wrap": "^1.2.3", + "yargs": "^16.0.2" + }, + "bin": { + "electron-installer-debian": "src/cli.js" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-installer-debian/node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "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", + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/electron-installer-debian/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-installer-debian/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/electron-installer-debian/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "optional": true, + "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-installer-debian/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-installer-debian/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "optional": true, + "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/electron-installer-debian/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-installer-debian/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-installer-dmg": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/electron-installer-dmg/-/electron-installer-dmg-5.0.1.tgz", + "integrity": "sha512-qOa1aAQdX57C+vzhDk3549dd/PRlNL4F8y736MTD1a43qptD+PvHY97Bo9gSf+OZ8iUWE7BrYSpk/FgLUe40EA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@types/appdmg": "^0.5.5", + "debug": "^4.3.2", + "minimist": "^1.2.7" + }, + "bin": { + "electron-installer-dmg": "dist/electron-installer-dmg-bin.js" + }, + "engines": { + "node": ">= 16" + }, + "optionalDependencies": { + "appdmg": "^0.6.4" + } + }, + "node_modules/electron-installer-redhat": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/electron-installer-redhat/-/electron-installer-redhat-3.4.0.tgz", + "integrity": "sha512-gEISr3U32Sgtj+fjxUAlSDo3wyGGq6OBx7rF5UdpIgbnpUvMN4W5uYb0ThpnAZ42VEJh/3aODQXHbFS4f5J3Iw==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin", + "linux" + ], + "dependencies": { + "@malept/cross-spawn-promise": "^1.0.0", + "debug": "^4.1.1", + "electron-installer-common": "^0.10.2", + "fs-extra": "^9.0.0", + "lodash": "^4.17.15", + "word-wrap": "^1.2.3", + "yargs": "^16.0.2" + }, + "bin": { + "electron-installer-redhat": "src/cli.js" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-installer-redhat/node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "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", + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/electron-installer-redhat/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-installer-redhat/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/electron-installer-redhat/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "optional": true, + "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-installer-redhat/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-installer-redhat/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "optional": true, + "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/electron-installer-redhat/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-installer-redhat/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-is-dev": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz", + "integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-liquid-glass": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/electron-liquid-glass/-/electron-liquid-glass-1.0.1.tgz", + "integrity": "sha512-XznNF0uDOmwvIQFGfgZM6PiQbrpXJiG4GYN6VnLzUrZwcOsQUGy51cJ5mPZCfwH+ST/ahorhLzwFEr+hsKRHXw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "node-addon-api": "^8.4.0" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "node-gyp-build": "^4" + } + }, + "node_modules/electron-publish": { + "version": "26.0.11", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.0.11.tgz", + "integrity": "sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^9.0.11", + "builder-util": "26.0.11", + "builder-util-runtime": "9.3.1", + "chalk": "^4.1.2", + "form-data": "^4.0.0", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "mime": "^2.5.2" + } + }, + "node_modules/electron-reloader": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/electron-reloader/-/electron-reloader-1.2.3.tgz", + "integrity": "sha512-aDnACAzNg0QvQhzw7LYOx/nVS10mEtbuG6M0QQvNQcLnJEwFs6is+EGRCnM+KQlQ4KcTbdwnt07nd7ZjHpY4iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "chokidar": "^3.5.0", + "date-time": "^3.1.0", + "electron-is-dev": "^1.2.0", + "find-up": "^5.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-squirrel-startup": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/electron-squirrel-startup/-/electron-squirrel-startup-1.0.1.tgz", + "integrity": "sha512-sTfFIHGku+7PsHLJ7v0dRcZNkALrV+YEozINTW8X1nM//e5O3L+rfYuvSW00lmGHnYmUjARZulD8F2V8ISI9RA==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^2.2.0" + } + }, + "node_modules/electron-squirrel-startup/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/electron-squirrel-startup/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/electron-store": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.2.0.tgz", + "integrity": "sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw==", + "license": "MIT", + "dependencies": { + "conf": "^10.2.0", + "type-fest": "^2.17.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-updater": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.6.2.tgz", + "integrity": "sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw==", + "license": "MIT", + "dependencies": { + "builder-util-runtime": "9.3.1", + "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.6.3", + "tiny-typed-emitter": "^2.1.0" + } + }, + "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", + "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", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/electron-winstaller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-winstaller/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/electron/node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "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/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/electron/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/electron/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/encode-utf8": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "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/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/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "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-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/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", + "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/farmhash-modern": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", + "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-xml-parser": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "strnum": "^1.1.1" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/firebase": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.10.0.tgz", + "integrity": "sha512-nKBXoDzF0DrXTBQJlZa+sbC5By99ysYU1D6PkMRYknm0nCW7rJly47q492Ht7Ndz5MeYSBuboKuhS1e6mFC03w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/ai": "1.4.1", + "@firebase/analytics": "0.10.17", + "@firebase/analytics-compat": "0.2.23", + "@firebase/app": "0.13.2", + "@firebase/app-check": "0.10.1", + "@firebase/app-check-compat": "0.3.26", + "@firebase/app-compat": "0.4.2", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.10.8", + "@firebase/auth-compat": "0.5.28", + "@firebase/data-connect": "0.3.10", + "@firebase/database": "1.0.20", + "@firebase/database-compat": "2.0.11", + "@firebase/firestore": "4.8.0", + "@firebase/firestore-compat": "0.3.53", + "@firebase/functions": "0.12.9", + "@firebase/functions-compat": "0.3.26", + "@firebase/installations": "0.6.18", + "@firebase/installations-compat": "0.2.18", + "@firebase/messaging": "0.12.22", + "@firebase/messaging-compat": "0.2.22", + "@firebase/performance": "0.7.7", + "@firebase/performance-compat": "0.2.20", + "@firebase/remote-config": "0.6.5", + "@firebase/remote-config-compat": "0.2.18", + "@firebase/storage": "0.13.14", + "@firebase/storage-compat": "0.3.24", + "@firebase/util": "1.12.1" + } + }, + "node_modules/firebase-admin": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.4.0.tgz", + "integrity": "sha512-Y8DcyKK+4pl4B93ooiy1G8qvdyRMkcNFfBSh+8rbVcw4cW8dgG0VXCCTp5NUwub8sn9vSPsOwpb9tE2OuFmcfQ==", + "license": "Apache-2.0", + "dependencies": { + "@fastify/busboy": "^3.0.0", + "@firebase/database-compat": "^2.0.0", + "@firebase/database-types": "^1.0.6", + "@types/node": "^22.8.7", + "farmhash-modern": "^1.1.0", + "google-auth-library": "^9.14.2", + "jsonwebtoken": "^9.0.0", + "jwks-rsa": "^3.1.0", + "node-forge": "^1.3.1", + "uuid": "^11.0.2" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^7.11.0", + "@google-cloud/storage": "^7.14.0" + } + }, + "node_modules/firebase-admin/node_modules/@types/node": { + "version": "22.16.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.0.tgz", + "integrity": "sha512-B2egV9wALML1JCpv3VQoQ+yesQKAmNMBIAY7OteVrikcOcAkWm+dGL6qpeCktPjAv6N1JLnhbNiqS35UpFyBsQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/flora-colossus": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-2.0.0.tgz", + "integrity": "sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/fmix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", + "integrity": "sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "imul": "^1.0.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "license": "MIT" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "license": "MIT", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-temp": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-1.2.1.tgz", + "integrity": "sha512-okTwLB7/Qsq82G6iN5zZJFsOfZtx2/pqrA7Hk/9fvy+c+eJS9CvgGXT2uNxwnI14BDY9L/jQPkaBgSvlKfSW9w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "random-path": "^0.1.0" + } + }, + "node_modules/fs-xattr": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/fs-xattr/-/fs-xattr-0.3.1.tgz", + "integrity": "sha512-UVqkrEW0GfDabw4C3HOrFlxKfx0eeigfRne69FxSBdHIP8Qt5Sq6Pu3RM9KmMlkygtC4pPKkj5CiPO5USnj2GA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "!win32" + ], + "engines": { + "node": ">=8.6.0" + } + }, + "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/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "license": "MIT", + "optional": true + }, + "node_modules/galactus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/galactus/-/galactus-1.0.0.tgz", + "integrity": "sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "flora-colossus": "^2.0.0", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/gar": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/gar/-/gar-1.0.4.tgz", + "integrity": "sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gaxios/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-property": "^1.0.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==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-folder-size": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-2.0.1.tgz", + "integrity": "sha512-+CEb+GDCM7tkOS2wdMKTn9vU7DgnKUTuDlehkNJKNSovdCOVxs14OfKCk4cvSaR3za4gj+OBdl9opPN9xrJ0zA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "gar": "^1.0.4", + "tiny-each-async": "2.0.3" + }, + "bin": { + "get-folder-size": "bin/get-folder-size" + } + }, + "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-package-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", + "integrity": "sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.1.1", + "debug": "^2.2.0", + "lodash.get": "^4.0.0", + "read-pkg-up": "^2.0.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/get-package-info/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/get-package-info/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "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": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "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-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/goober": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", + "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", + "license": "MIT", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, + "node_modules/google-auth-library": { + "version": "9.15.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", + "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.6.1.tgz", + "integrity": "sha512-V6eky/xz2mcKfAd1Ioxyd6nmA61gao3n01C+YeuIwu3vzM9EDR6wcVzMSIbLMDXWeoi9SHYctXuKYC5uJUT3eQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "^1.10.9", + "@grpc/proto-loader": "^0.7.13", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.3.0", + "node-fetch": "^2.7.0", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.2", + "protobufjs": "^7.3.2", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax/node_modules/@grpc/grpc-js": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.4.tgz", + "integrity": "sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/google-gax/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "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.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/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/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "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-corefoundation/node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/image-size": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz", + "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/imul": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", + "integrity": "sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true, + "license": "ISC" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-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-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-my-ip-valid": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz", + "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/is-my-json-valid": { + "version": "2.20.6", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", + "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^5.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==", + "license": "BSD-2-Clause" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", + "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", + "license": "MIT", + "dependencies": { + "@types/express": "^4.17.20", + "@types/jsonwebtoken": "^9.0.4", + "debug": "^4.3.4", + "jose": "^4.15.4", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lazy-val": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", + "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", + "license": "MIT" + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "node_modules/listr2": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz", + "integrity": "sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^5.0.1", + "rfdc": "^1.3.0", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "license": "MIT" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", + "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^5.0.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^5.0.0", + "strip-ansi": "^7.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", + "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", + "license": "MIT", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "6.0.0" + } + }, + "node_modules/macos-alias": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/macos-alias/-/macos-alias-0.2.12.tgz", + "integrity": "sha512-yiLHa7cfJcGRFq4FrR4tMlpNHb4Vy4mWnpajlSSIFM5k4Lv8/7BbbDLzCAVogWNl0LlLhizRp1drXv0hK9h0Yw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "nan": "^2.4.0" + } + }, + "node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "license": "MIT", + "optional": true, + "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/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mem/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "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-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/murmur-32": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/murmur-32/-/murmur-32-0.2.0.tgz", + "integrity": "sha512-ZkcWZudylwF+ir3Ld1n7gL6bI2mQAzXvSobPwVtu8aYi2sbXeipeSkdcanRLzIofLcM5F53lGaKm2dk7orBi7Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "encode-utf8": "^1.0.3", + "fmix": "^0.1.0", + "imul": "^1.0.0" + } + }, + "node_modules/nan": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", + "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-abi": { + "version": "3.75.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", + "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz", + "integrity": "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^18 || ^20 || >= 21" + } + }, + "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-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/openai": { + "version": "4.104.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz", + "integrity": "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.23.8" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/openai/node_modules/@types/node": { + "version": "18.19.115", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.115.tgz", + "integrity": "sha512-kNrFiTgG4a9JAn1LMQeLOv3MvXIPokzXziohMrMsvpYgLpdEt/mMiVYc4sGKtDfyxM5gIDF4VgrPRyCw4fHOYg==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/openai/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "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/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-author": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", + "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "author-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-color": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", + "integrity": "sha512-fuDHYgFHJGbpGMgw9skY/bj3HL/Jrn4l/5rSspy00DoT4RyLnDcRvPxdZ+r6OFwIsgAuhDh4I09tAId4mI12bw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "~0.5.0" + } + }, + "node_modules/parse-color/node_modules/color-convert": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", + "integrity": "sha512-RwBeO/B/vZR3dfKL1ye/vx8MHZ40ugzpyfeVG5GsiuGnrlMWe2o8wxBbLCpw9CsxV+wHuzYlCiWnybrIA0ling==", + "dev": true, + "optional": true + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "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/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pe-library": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-1.0.1.tgz", + "integrity": "sha512-nh39Mo1eGWmZS7y+mK/dQIqg7S1lp38DpRxkyoHf0ZcUs/HDc+yyTjuOtTvSMZHmfSLuSQaX945u05Y2Q6UWZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14", + "npm": ">=7" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/postject": { + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", + "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", + "dev": true, + "license": "MIT", + "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", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proc-log": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", + "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/proto3-json-serializer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", + "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/protobufjs": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", + "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "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/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "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/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/random-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/random-path/-/random-path-0.1.2.tgz", + "integrity": "sha512-4jY0yoEaQ5v9StCl5kZbNIQlg1QheIDBrdkDn53EynpPb9FgO6//p3X/tgMnrC45XN6QZCzU1Xz/+pSSsJBpRw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "base32-encode": "^0.1.0 || ^1.0.0", + "murmur-32": "^0.1.0 || ^0.2.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/react-hot-toast": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.2.tgz", + "integrity": "sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.3", + "goober": "^2.1.16" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "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/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-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": "2.0.3", + "resolved": "https://registry.npmjs.org/resedit/-/resedit-2.0.3.tgz", + "integrity": "sha512-oTeemxwoMuxxTYxXUwjkrOPfngTQehlv0/HoYFNkB4uzsP1Un1A9nI8JQKGOFkxpqkC7qkMs0lUsGrvUlbLNUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pe-library": "^1.0.1" + }, + "engines": { + "node": ">=14", + "npm": ">=7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/request": "^2.48.8", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "dev": true, + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT", + "peer": true + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", + "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.4", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.2", + "@img/sharp-darwin-x64": "0.34.2", + "@img/sharp-libvips-darwin-arm64": "1.1.0", + "@img/sharp-libvips-darwin-x64": "1.1.0", + "@img/sharp-libvips-linux-arm": "1.1.0", + "@img/sharp-libvips-linux-arm64": "1.1.0", + "@img/sharp-libvips-linux-ppc64": "1.1.0", + "@img/sharp-libvips-linux-s390x": "1.1.0", + "@img/sharp-libvips-linux-x64": "1.1.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", + "@img/sharp-libvips-linuxmusl-x64": "1.1.0", + "@img/sharp-linux-arm": "0.34.2", + "@img/sharp-linux-arm64": "0.34.2", + "@img/sharp-linux-s390x": "0.34.2", + "@img/sharp-linux-x64": "0.34.2", + "@img/sharp-linuxmusl-arm64": "0.34.2", + "@img/sharp-linuxmusl-x64": "0.34.2", + "@img/sharp-wasm32": "0.34.2", + "@img/sharp-win32-arm64": "0.34.2", + "@img/sharp-win32-ia32": "0.34.2", + "@img/sharp-win32-x64": "0.34.2" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "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/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "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", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", + "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.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-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/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "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/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", + "dev": true, + "license": "Unlicense", + "optional": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "license": "MIT", + "optional": true, + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT", + "optional": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "license": "MIT", + "optional": true + }, + "node_modules/sudo-prompt": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", + "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT" + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "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/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", + "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/teeny-request": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.9", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/teeny-request/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/teeny-request/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/teeny-request/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/teeny-request/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "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/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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-each-async": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tiny-each-async/-/tiny-each-async-2.0.3.tgz", + "integrity": "sha512-5ROII7nElnAirvFn8g7H7MtpfV1daMcyfTGQwsn/x2VtyV+VPiO5CjReCJtWLvoKTDEDmZocf3cNPraiMnBXLA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/tiny-typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", + "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==", + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "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/tn1150": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tn1150/-/tn1150-0.1.0.tgz", + "integrity": "sha512-DbplOfQFkqG5IHcDyyrs/lkvSr3mPUVsFf/RbDppOshs22yTPnSJWEe6FkYd1txAwU/zcnR905ar2fi4kwF29w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "unorm": "^1.4.1" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/to-data-view": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", + "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.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/unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", + "dev": true, + "license": "MIT or GPL-2.0", + "optional": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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/username": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz", + "integrity": "sha512-PCKbdWw85JsYMvmCv5GH3kXmM66rCd9m1hBEDutPNv94b/pqCMT4NtcKyeWYvLFiE8b+ha1Jdl8XAaUdPn5QTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^1.0.0", + "mem": "^4.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validator": { + "version": "13.15.15", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz", + "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.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/wait-on": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.3.tgz", + "integrity": "sha512-nQFqAFzZDeRxsu7S3C7LbuxslHhk+gnJZHyethuGKAn2IVleIbTB9I3vJSQiSR+DifUqmdzfPMoMPJfLqMF2vw==", + "license": "MIT", + "dependencies": { + "axios": "^1.8.2", + "joi": "^17.13.3", + "lodash": "^4.17.21", + "minimist": "^1.2.8", + "rxjs": "^7.8.2" + }, + "bin": { + "wait-on": "bin/wait-on" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "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/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "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/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "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/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.75", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.75.tgz", + "integrity": "sha512-OhpzAmVzabPOL6C3A3gpAifqr9MqihV/Msx3gor2b2kviCgcb+HM9SEOpMWwwNp9MRunWnhtAKUoo0AHhjyPPg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.24.6", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", + "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } + } + } +} diff --git a/pickleglass_web/package-lock.json b/pickleglass_web/package-lock.json new file mode 100644 index 0000000..c7d23a8 --- /dev/null +++ b/pickleglass_web/package-lock.json @@ -0,0 +1,6976 @@ +{ + "name": "pickleglass-frontend", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "pickleglass-frontend", + "version": "0.1.0", + "dependencies": { + "@headlessui/react": "^1.7.17", + "autoprefixer": "^10.4.16", + "axios": "^1.6.0", + "firebase": "^11.10.0", + "lucide-react": "^0.294.0", + "next": "^14.2.30", + "postcss": "^8.4.32", + "react": "^18", + "react-dom": "^18", + "react-hot-toast": "^2.5.2", + "tailwindcss": "^3.3.0" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "eslint": "^8", + "eslint-config-next": "14.0.4", + "typescript": "^5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emnapi/core": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz", + "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz", + "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "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/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@firebase/ai": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-1.4.1.tgz", + "integrity": "sha512-bcusQfA/tHjUjBTnMx6jdoPMpDl3r8K15Z+snHz9wq0Foox0F/V+kNLXucEOHoTL2hTc9l+onZCyBJs2QoIC3g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/analytics": { + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.17.tgz", + "integrity": "sha512-n5vfBbvzduMou/2cqsnKrIes4auaBjdhg8QNA2ZQZ59QgtO2QiwBaXQZQE4O4sgB0Ds1tvLgUUkY+pwzu6/xEg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.23.tgz", + "integrity": "sha512-3AdO10RN18G5AzREPoFgYhW6vWXr3u+OYQv6pl3CX6Fky8QRk0AHurZlY3Q1xkXO0TDxIsdhO3y65HF7PBOJDw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/analytics": "0.10.17", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.2.tgz", + "integrity": "sha512-jwtMmJa1BXXDCiDx1vC6SFN/+HfYG53UkfJa6qeN5ogvOunzbFDO3wISZy5n9xgYFUrEP6M7e8EG++riHNTv9w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.10.1.tgz", + "integrity": "sha512-MgNdlms9Qb0oSny87pwpjKush9qUwCJhfmTJHDfrcKo4neLGiSeVE4qJkzP7EQTIUFKp84pbTxobSAXkiuQVYQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.26.tgz", + "integrity": "sha512-PkX+XJMLDea6nmnopzFKlr+s2LMQGqdyT2DHdbx1v1dPSqOol2YzgpgymmhC67vitXVpNvS3m/AiWQWWhhRRPQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check": "0.10.1", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-compat": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.4.2.tgz", + "integrity": "sha512-LssbyKHlwLeiV8GBATyOyjmHcMpX/tFjzRUCS1jnwGAew1VsBB4fJowyS5Ud5LdFbYpJeS+IQoC+RQxpK7eH3Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app": "0.13.2", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-compat": { + "version": "0.5.28", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.28.tgz", + "integrity": "sha512-HpMSo/cc6Y8IX7bkRIaPPqT//Jt83iWy5rmDWeThXQCAImstkdNo3giFLORJwrZw2ptiGkOij64EH1ztNJzc7Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth": "1.10.8", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/auth": { + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", + "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-types": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.18.tgz", + "integrity": "sha512-n28kPCkE2dL2U28fSxZJjzPPVpKsQminJ6NrzcKXAI0E/lYC8YhfwpyllScqVEvAI3J2QgJZWYgrX+1qGI+SQQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/data-connect": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.10.tgz", + "integrity": "sha512-VMVk7zxIkgwlVQIWHOKFahmleIjiVFwFOjmakXPd/LDgaB/5vzwsB5DWIYo+3KhGxWpidQlR8geCIn39YflJIQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/database": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.20.tgz", + "integrity": "sha512-H9Rpj1pQ1yc9+4HQOotFGLxqAXwOzCHsRSRjcQFNOr8lhUt6LeYjf0NSRL04sc4X0dWe8DsCvYKxMYvFG/iOJw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.11.tgz", + "integrity": "sha512-itEsHARSsYS95+udF/TtIzNeQ0Uhx4uIna0sk4E0wQJBUnLc/G1X6D7oRljoOuwwCezRLGvWBRyNrugv/esOEw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/database": "1.0.20", + "@firebase/database-types": "1.0.15", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.15.tgz", + "integrity": "sha512-XWHJ0VUJ0k2E9HDMlKxlgy/ZuTa9EvHCGLjaKSUvrQnwhgZuRU5N3yX6SZ+ftf2hTzZmfRkv+b3QRvGg40bKNw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.12.1" + } + }, + "node_modules/@firebase/firestore": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.8.0.tgz", + "integrity": "sha512-QSRk+Q1/CaabKyqn3C32KSFiOdZpSqI9rpLK5BHPcooElumOBooPFa6YkDdiT+/KhJtel36LdAacha9BptMj2A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "@firebase/webchannel-wrapper": "1.0.3", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.3.53", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.53.tgz", + "integrity": "sha512-qI3yZL8ljwAYWrTousWYbemay2YZa+udLWugjdjju2KODWtLG94DfO4NALJgPLv8CVGcDHNFXoyQexdRA0Cz8Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/firestore": "4.8.0", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.12.9", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.9.tgz", + "integrity": "sha512-FG95w6vjbUXN84Ehezc2SDjGmGq225UYbHrb/ptkRT7OTuCiQRErOQuyt1jI1tvcDekdNog+anIObihNFz79Lg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.26.tgz", + "integrity": "sha512-A798/6ff5LcG2LTWqaGazbFYnjBW8zc65YfID/en83ALmkhu2b0G8ykvQnLtakbV9ajrMYPn7Yc/XcYsZIUsjA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/functions": "0.12.9", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/installations": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.18.tgz", + "integrity": "sha512-NQ86uGAcvO8nBRwVltRL9QQ4Reidc/3whdAasgeWCPIcrhOKDuNpAALa6eCVryLnK14ua2DqekCOX5uC9XbU/A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.18.tgz", + "integrity": "sha512-aLFohRpJO5kKBL/XYL4tN+GdwEB/Q6Vo9eZOM/6Kic7asSUgmSfGPpGUZO1OAaSRGwF4Lqnvi1f/f9VZnKzChw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.12.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.22.tgz", + "integrity": "sha512-GJcrPLc+Hu7nk+XQ70Okt3M1u1eRr2ZvpMbzbc54oTPJZySHcX9ccZGVFcsZbSZ6o1uqumm8Oc7OFkD3Rn1/og==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.22.tgz", + "integrity": "sha512-5ZHtRnj6YO6f/QPa/KU6gryjmX4Kg33Kn4gRpNU6M1K47Gm8kcQwPkX7erRUYEH1mIWptfvjvXMHWoZaWjkU7A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/messaging": "0.12.22", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/performance": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.7.tgz", + "integrity": "sha512-JTlTQNZKAd4+Q5sodpw6CN+6NmwbY72av3Lb6wUKTsL7rb3cuBIhQSrslWbVz0SwK3x0ZNcqX24qtRbwKiv+6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.20", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.20.tgz", + "integrity": "sha512-XkFK5NmOKCBuqOKWeRgBUFZZGz9SzdTZp4OqeUg+5nyjapTiZ4XoiiUL8z7mB2q+63rPmBl7msv682J3rcDXIQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/performance": "0.7.7", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/remote-config": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.5.tgz", + "integrity": "sha512-fU0c8HY0vrVHwC+zQ/fpXSqHyDMuuuglV94VF6Yonhz8Fg2J+KOowPGANM0SZkLvVOYpTeWp3ZmM+F6NjwWLnw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.18.tgz", + "integrity": "sha512-YiETpldhDy7zUrnS8e+3l7cNs0sL7+tVAxvVYU0lu7O+qLHbmdtAxmgY+wJqWdW2c9nDvBFec7QiF58pEUu0qQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/remote-config": "0.6.5", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/storage": { + "version": "0.13.14", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.14.tgz", + "integrity": "sha512-xTq5ixxORzx+bfqCpsh+o3fxOsGoDjC1nO0Mq2+KsOcny3l7beyBhP/y1u5T6mgsFQwI1j6oAkbT5cWdDBx87g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.24.tgz", + "integrity": "sha512-XHn2tLniiP7BFKJaPZ0P8YQXKiVJX+bMyE2j2YWjYfaddqiJnROJYqSomwW6L3Y+gZAga35ONXUJQju6MB6SOQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/storage": "0.13.14", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.1.tgz", + "integrity": "sha512-zGlBn/9Dnya5ta9bX/fgEoNC3Cp8s6h+uYPYaDieZsFOAdHP/ExzQ/eaDgxD3GOROdPkLKpvKY0iIzr9adle0w==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", + "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==", + "license": "Apache-2.0" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@headlessui/react": { + "version": "1.7.19", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz", + "integrity": "sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==", + "license": "MIT", + "dependencies": { + "@tanstack/react-virtual": "^3.0.0-beta.60", + "client-only": "^0.0.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "react-dom": "^16 || ^17 || ^18" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.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/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz", + "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@next/env": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.30.tgz", + "integrity": "sha512-KBiBKrDY6kxTQWGzKjQB7QirL3PiiOkV7KW98leHFjtVRKtft76Ra5qSA/SL75xT44dp6hOcqiiJ6iievLOYug==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.0.4.tgz", + "integrity": "sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "7.1.7" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.30.tgz", + "integrity": "sha512-EAqfOTb3bTGh9+ewpO/jC59uACadRHM6TSA9DdxJB/6gxOpyV+zrbqeXiFTDy9uV6bmipFDkfpAskeaDcO+7/g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.30.tgz", + "integrity": "sha512-TyO7Wz1IKE2kGv8dwQ0bmPL3s44EKVencOqwIY69myoS3rdpO1NPg5xPM5ymKu7nfX4oYJrpMxv8G9iqLsnL4A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.30.tgz", + "integrity": "sha512-I5lg1fgPJ7I5dk6mr3qCH1hJYKJu1FsfKSiTKoYwcuUf53HWTrEkwmMI0t5ojFKeA6Vu+SfT2zVy5NS0QLXV4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.30.tgz", + "integrity": "sha512-8GkNA+sLclQyxgzCDs2/2GSwBc92QLMrmYAmoP2xehe5MUKBLB2cgo34Yu242L1siSkwQkiV4YLdCnjwc/Micw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.30.tgz", + "integrity": "sha512-8Ly7okjssLuBoe8qaRCcjGtcMsv79hwzn/63wNeIkzJVFVX06h5S737XNr7DZwlsbTBDOyI6qbL2BJB5n6TV/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.30.tgz", + "integrity": "sha512-dBmV1lLNeX4mR7uI7KNVHsGQU+OgTG5RGFPi3tBJpsKPvOPtg9poyav/BYWrB3GPQL4dW5YGGgalwZ79WukbKQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.30.tgz", + "integrity": "sha512-6MMHi2Qc1Gkq+4YLXAgbYslE1f9zMGBikKMdmQRHXjkGPot1JY3n5/Qrbg40Uvbi8//wYnydPnyvNhI1DMUW1g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.30.tgz", + "integrity": "sha512-pVZMnFok5qEX4RT59mK2hEVtJX+XFfak+/rjHpyFh7juiT52r177bfFKhnlafm0UOSldhXjj32b+LZIOdswGTg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.30.tgz", + "integrity": "sha512-4KCo8hMZXMjpTzs3HOqOGYYwAXymXIy7PEPAXNEcEOyKqkjiDlECumrWziy+JEF0Oi4ILHGxzgQ3YiMGG2t/Lg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.12.0.tgz", + "integrity": "sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.13.12", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.12.tgz", + "integrity": "sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.13.12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.13.12", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.12.tgz", + "integrity": "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.4.tgz", + "integrity": "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.23", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz", + "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.0.tgz", + "integrity": "sha512-LRw5BW29sYj9NsQC6QoqeLVQhEa+BwVINYyMlcve+6stwdBsSt5UB7zw4UZB4+4PNqIVilHoMaPWCb/KhABHQw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.0.tgz", + "integrity": "sha512-zYX8D2zcWCAHqghA8tPjbp7LwjVXbIZP++mpU/Mrf5jUVlk3BWIxkeB8yYzZi5GpFSlqMcRZQxQqbMI0c2lASQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.0.tgz", + "integrity": "sha512-YsYOT049hevAY/lTYD77GhRs885EXPeAfExG5KenqMJ417nYLS2N/kpRpYbABhFZBVQn+2uRPasTe4ypmYoo3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.0.tgz", + "integrity": "sha512-PSjvk3OZf1aZImdGY5xj9ClFG3bC4gnSSYWrt+id0UAv+GwwVldhpMFjAga8SpMo2T1GjV9UKwM+QCsQCQmtdA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.0.tgz", + "integrity": "sha512-KC/iFaEN/wsTVYnHClyHh5RSYA9PpuGfqkFua45r4sweXpC0KHZ+BYY7ikfcGPt5w1lMpR1gneFzuqWLQxsRKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.0.tgz", + "integrity": "sha512-CDh/0v8uot43cB4yKtDL9CVY8pbPnMV0dHyQCE4lFz6PW/+9tS0i9eqP5a91PAqEBVMqH1ycu+k8rP6wQU846w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.0.tgz", + "integrity": "sha512-+TE7epATDSnvwr3L/hNHX3wQ8KQYB+jSDTdywycg3qDqvavRP8/HX9qdq/rMcnaRDn4EOtallb3vL/5wCWGCkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.0.tgz", + "integrity": "sha512-VBAYGg3VahofpQ+L4k/ZO8TSICIbUKKTaMYOWHWfuYBFqPbSkArZZLezw3xd27fQkxX4BaLGb/RKnW0dH9Y/UA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.0.tgz", + "integrity": "sha512-9IgGFUUb02J1hqdRAHXpZHIeUHRrbnGo6vrRbz0fREH7g+rzQy53/IBSyadZ/LG5iqMxukriNPu4hEMUn+uWEg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.0.tgz", + "integrity": "sha512-LR4iQ/LPjMfivpL2bQ9kmm3UnTas3U+umcCnq/CV7HAkukVdHxrDD1wwx74MIWbbgzQTLPYY7Ur2MnnvkYJCBQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.0.tgz", + "integrity": "sha512-HCupFQwMrRhrOg7YHrobbB5ADg0Q8RNiuefqMHVsdhEy9lLyXm/CxsCXeLJdrg27NAPsCaMDtdlm8Z2X8x91Tg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.0.tgz", + "integrity": "sha512-Ckxy76A5xgjWa4FNrzcKul5qFMWgP5JSQ5YKd0XakmWOddPLSkQT+uAvUpQNnFGNbgKzv90DyQlxPDYPQ4nd6A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.0.tgz", + "integrity": "sha512-HfO0PUCCRte2pMJmVyxPI+eqT7KuV3Fnvn2RPvMe5mOzb2BJKf4/Vth8sSt9cerQboMaTVpbxyYjjLBWIuI5BQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.0.tgz", + "integrity": "sha512-9PZdjP7tLOEjpXHS6+B/RNqtfVUyDEmaViPOuSqcbomLdkJnalt5RKQ1tr2m16+qAufV0aDkfhXtoO7DQos/jg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.0.tgz", + "integrity": "sha512-qkE99ieiSKMnFJY/EfyGKVtNra52/k+lVF/PbO4EL5nU6AdvG4XhtJ+WHojAJP7ID9BNIra/yd75EHndewNRfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.0.tgz", + "integrity": "sha512-MjXek8UL9tIX34gymvQLecz2hMaQzOlaqYJJBomwm1gsvK2F7hF+YqJJ2tRyBDTv9EZJGMt4KlKkSD/gZWCOiw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.0.tgz", + "integrity": "sha512-9LT6zIGO7CHybiQSh7DnQGwFMZvVr0kUjah6qQfkH2ghucxPV6e71sUXJdSM4Ba0MaGE6DC/NwWf7mJmc3DAng==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.0.tgz", + "integrity": "sha512-HYchBYOZ7WN266VjoGm20xFv5EonG/ODURRgwl9EZT7Bq1nLEs6VKJddzfFdXEAho0wfFlt8L/xIiE29Pmy1RA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.0.tgz", + "integrity": "sha512-+oLKLHw3I1UQo4MeHfoLYF+e6YBa8p5vYUw3Rgt7IDzCs+57vIZqQlIo62NDpYM0VG6BjWOwnzBczMvbtH8hag==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "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/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "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/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "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-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "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/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "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/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/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/axe-core": { + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", + "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axios": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "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/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/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/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/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/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/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/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "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/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "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/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "license": "Apache-2.0" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.179", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.179.tgz", + "integrity": "sha512-UWKi/EbBopgfFsc5k61wFpV7WrnnSlSzW/e2XcBmS6qKYTivZlLtoll5/rdqRTxGglGHkmkW0j0pFNJG10EUIQ==", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "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.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "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-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "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.4", + "safe-array-concat": "^1.1.3" + }, + "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/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.0.4.tgz", + "integrity": "sha512-9/xbOHEQOmQtqvQ1UsTQZpnA7SlDMBtuKJ//S4JnoyK3oGLhILKXdBgu/UO7lQo/2xOykQULS1qQ6p2+EpHgAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "14.0.4", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/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/eslint-plugin-import/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/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "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": "5.0.0-canary-7118f5dd7-20230705", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz", + "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/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/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/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/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "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/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/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/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/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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/firebase": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.10.0.tgz", + "integrity": "sha512-nKBXoDzF0DrXTBQJlZa+sbC5By99ysYU1D6PkMRYknm0nCW7rJly47q492Ht7Ndz5MeYSBuboKuhS1e6mFC03w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/ai": "1.4.1", + "@firebase/analytics": "0.10.17", + "@firebase/analytics-compat": "0.2.23", + "@firebase/app": "0.13.2", + "@firebase/app-check": "0.10.1", + "@firebase/app-check-compat": "0.3.26", + "@firebase/app-compat": "0.4.2", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.10.8", + "@firebase/auth-compat": "0.5.28", + "@firebase/data-connect": "0.3.10", + "@firebase/database": "1.0.20", + "@firebase/database-compat": "2.0.11", + "@firebase/firestore": "4.8.0", + "@firebase/firestore-compat": "0.3.53", + "@firebase/functions": "0.12.9", + "@firebase/functions-compat": "0.3.26", + "@firebase/installations": "0.6.18", + "@firebase/installations-compat": "0.2.18", + "@firebase/messaging": "0.12.22", + "@firebase/messaging-compat": "0.2.22", + "@firebase/performance": "0.7.7", + "@firebase/performance-compat": "0.2.20", + "@firebase/remote-config": "0.6.5", + "@firebase/remote-config-compat": "0.2.18", + "@firebase/storage": "0.13.14", + "@firebase/storage-compat": "0.3.24", + "@firebase/util": "1.12.1" + } + }, + "node_modules/firebase/node_modules/@firebase/auth": { + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", + "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "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/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "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": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/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==", + "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/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-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-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/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "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==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "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==", + "dev": 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/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/goober": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", + "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", + "license": "MIT", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": 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.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "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/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-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-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-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-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-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-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-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": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-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-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/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-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/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "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/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "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-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/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "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/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/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.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/lodash.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/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/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==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/lucide-react": { + "version": "0.294.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.294.0.tgz", + "integrity": "sha512-V7o0/VECSGbLHn3/1O67FUgBwWB+hmzshrgDVRJQhMh8uj5D3HBuIvhuAmQTtlupILSplwIZg5FTc4tTKMA2SA==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/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/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-postinstall": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.0.tgz", + "integrity": "sha512-M7NqKyhODKV1gRLdkwE7pDsZP2/SC2a2vHkOYh9MCpKMbWVfyVfUw5MaH83Fv6XMjxr5jryUp3IDDL9rlxsTeA==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "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/next": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.30.tgz", + "integrity": "sha512-+COdu6HQrHHFQ1S/8BBsCag61jZacmvbuL2avHvQFbWa2Ox7bE+d8FyNgxRLjXQ5wtPyQwEmk85js/AuaG2Sbg==", + "license": "MIT", + "dependencies": { + "@next/env": "14.2.30", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.30", + "@next/swc-darwin-x64": "14.2.30", + "@next/swc-linux-arm64-gnu": "14.2.30", + "@next/swc-linux-arm64-musl": "14.2.30", + "@next/swc-linux-x64-gnu": "14.2.30", + "@next/swc-linux-x64-musl": "14.2.30", + "@next/swc-win32-arm64-msvc": "14.2.30", + "@next/swc-win32-ia32-msvc": "14.2.30", + "@next/swc-win32-x64-msvc": "14.2.30" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "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.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "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==", + "dev": 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.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "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-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/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/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/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/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.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/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/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/protobufjs": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", + "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/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/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-hot-toast": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.2.tgz", + "integrity": "sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.3", + "goober": "^2.1.16" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "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/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/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/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-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/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/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.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stable-hash": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "dev": true, + "license": "MIT" + }, + "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/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/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": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "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.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "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-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/unrs-resolver": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.0.tgz", + "integrity": "sha512-uw3hCGO/RdAEAb4zgJ3C/v6KIAFFOtBoxR86b2Ejc5TnH7HrhTWJR2o0A9ullC3eWMegKQCw/arQ/JivywQzkg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.0", + "@unrs/resolver-binding-android-arm64": "1.11.0", + "@unrs/resolver-binding-darwin-arm64": "1.11.0", + "@unrs/resolver-binding-darwin-x64": "1.11.0", + "@unrs/resolver-binding-freebsd-x64": "1.11.0", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.0", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.0", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.0", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.0", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.0", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-x64-musl": "1.11.0", + "@unrs/resolver-binding-wasm32-wasi": "1.11.0", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.0", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.0", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/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/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/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.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "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==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/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" + } + } + } +} From 8db58dcb1e4b71d0cc3f9fca424e1f31c50238ff Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Jul 2025 18:38:22 +0100 Subject: [PATCH 31/52] windows --- electron-builder.yml | 2 + package.json | 8 +- src/features/listen/listenService.js | 14 +++ src/features/listen/renderer/listenCapture.js | 116 +++++++++++++----- src/features/listen/stt/sttService.js | 15 +++ .../summary/repositories/sqlite.repository.js | 46 +++---- src/index.js | 13 +- 7 files changed, 158 insertions(+), 56 deletions(-) diff --git a/electron-builder.yml b/electron-builder.yml index 35e6ed5..79b81fb 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -44,6 +44,8 @@ win: - target: portable arch: x64 requestedExecutionLevel: asInvoker + # Disable code signing to avoid symbolic link issues on Windows + signAndEditExecutable: false # NSIS installer configuration for Windows nsis: diff --git a/package.json b/package.json index b399345..581acde 100644 --- a/package.json +++ b/package.json @@ -9,12 +9,14 @@ "start": "npm run build:renderer && electron-forge start", "package": "npm run build:renderer && electron-forge package", "make": "npm run build:renderer && electron-forge make", - "build": "npm run build:renderer && electron-builder --config electron-builder.yml --publish never", - "build:win": "npm run build:renderer && electron-builder --win --x64 --publish never", - "publish": "npm run build:renderer && electron-builder --config electron-builder.yml --publish always", + "build": "npm run build:all && electron-builder --config electron-builder.yml --publish never", + "build:win": "npm run build:all && electron-builder --win --x64 --publish never", + "publish": "npm run build:all && electron-builder --config electron-builder.yml --publish always", "lint": "eslint --ext .ts,.tsx,.js .", "postinstall": "electron-builder install-app-deps", "build:renderer": "node build.js", + "build:web": "cd pickleglass_web && npm run build && cd ..", + "build:all": "npm run build:renderer && npm run build:web", "watch:renderer": "node build.js --watch" }, "keywords": [ diff --git a/src/features/listen/listenService.js b/src/features/listen/listenService.js index a0dcde8..3b89aa2 100644 --- a/src/features/listen/listenService.js +++ b/src/features/listen/listenService.js @@ -219,6 +219,20 @@ class ListenService { } }); + ipcMain.handle('send-system-audio-content', async (event, { data, mimeType }) => { + try { + await this.sttService.sendSystemAudioContent(data, mimeType); + + // Send system audio data back to renderer for AEC reference (like macOS does) + this.sendToRenderer('system-audio-data', { data }); + + return { success: true }; + } catch (error) { + console.error('Error sending system audio:', error); + return { success: false, error: error.message }; + } + }); + ipcMain.handle('start-macos-audio', async () => { if (process.platform !== 'darwin') { return { success: false, error: 'macOS audio capture only available on macOS' }; diff --git a/src/features/listen/renderer/listenCapture.js b/src/features/listen/renderer/listenCapture.js index a4eef43..1c27f75 100644 --- a/src/features/listen/renderer/listenCapture.js +++ b/src/features/listen/renderer/listenCapture.js @@ -15,6 +15,8 @@ let micMediaStream = null; let screenshotInterval = null; let audioContext = null; let audioProcessor = null; +let systemAudioContext = null; +let systemAudioProcessor = null; let currentImageQuality = 'medium'; let lastScreenshotBase64 = null; @@ -345,6 +347,7 @@ function setupMicProcessing(micStream) { micProcessor.connect(micAudioContext.destination); audioProcessor = micProcessor; + return { context: micAudioContext, processor: micProcessor }; } function setupLinuxMicProcessing(micStream) { @@ -380,34 +383,40 @@ function setupLinuxMicProcessing(micStream) { audioProcessor = micProcessor; } -function setupWindowsLoopbackProcessing() { - // Setup audio processing for Windows loopback audio only - audioContext = new AudioContext({ sampleRate: SAMPLE_RATE }); - const source = audioContext.createMediaStreamSource(mediaStream); - audioProcessor = audioContext.createScriptProcessor(BUFFER_SIZE, 1, 1); +function setupSystemAudioProcessing(systemStream) { + const systemAudioContext = new AudioContext({ sampleRate: SAMPLE_RATE }); + const systemSource = systemAudioContext.createMediaStreamSource(systemStream); + const systemProcessor = systemAudioContext.createScriptProcessor(BUFFER_SIZE, 1, 1); let audioBuffer = []; const samplesPerChunk = SAMPLE_RATE * AUDIO_CHUNK_DURATION; - audioProcessor.onaudioprocess = async e => { + systemProcessor.onaudioprocess = async e => { const inputData = e.inputBuffer.getChannelData(0); + if (!inputData || inputData.length === 0) return; + audioBuffer.push(...inputData); - // Process audio in chunks while (audioBuffer.length >= samplesPerChunk) { const chunk = audioBuffer.splice(0, samplesPerChunk); const pcmData16 = convertFloat32ToInt16(chunk); const base64Data = arrayBufferToBase64(pcmData16.buffer); - await ipcRenderer.invoke('send-audio-content', { - data: base64Data, - mimeType: 'audio/pcm;rate=24000', - }); + try { + await ipcRenderer.invoke('send-system-audio-content', { + data: base64Data, + mimeType: 'audio/pcm;rate=24000', + }); + } catch (error) { + console.error('Failed to send system audio:', error); + } } }; - source.connect(audioProcessor); - audioProcessor.connect(audioContext.destination); + systemSource.connect(systemProcessor); + systemProcessor.connect(systemAudioContext.destination); + + return { context: systemAudioContext, processor: systemProcessor }; } // --------------------------- @@ -534,7 +543,9 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu }); console.log('macOS microphone capture started'); - setupMicProcessing(micMediaStream); + const { context, processor } = setupMicProcessing(micMediaStream); + audioContext = context; + audioProcessor = processor; } catch (micErr) { console.warn('Failed to get microphone on macOS:', micErr); } @@ -577,27 +588,62 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu console.log('Linux screen capture started'); } else { - // Windows - use display media for audio, main process for screenshots + // Windows - capture mic and system audio separately using native loopback + console.log('Starting Windows capture with native loopback audio...'); + + // Start screen capture in main process for screenshots const screenResult = await ipcRenderer.invoke('start-screen-capture'); if (!screenResult.success) { throw new Error('Failed to start screen capture: ' + screenResult.error); } - mediaStream = await navigator.mediaDevices.getDisplayMedia({ - video: false, // We don't need video in renderer - audio: { - sampleRate: SAMPLE_RATE, - channelCount: 1, - echoCancellation: true, - noiseSuppression: true, - autoGainControl: true, - }, - }); + // Ensure STT sessions are initialized before starting audio capture + const sessionActive = await ipcRenderer.invoke('is-session-active'); + if (!sessionActive) { + throw new Error('STT sessions not initialized - please wait for initialization to complete'); + } - console.log('Windows capture started with loopback audio'); + // 1. Get user's microphone + try { + micMediaStream = await navigator.mediaDevices.getUserMedia({ + audio: { + sampleRate: SAMPLE_RATE, + channelCount: 1, + echoCancellation: true, + noiseSuppression: true, + autoGainControl: true, + }, + video: false, + }); + console.log('Windows microphone capture started'); + const { context, processor } = setupMicProcessing(micMediaStream); + audioContext = context; + audioProcessor = processor; + } catch (micErr) { + console.warn('Could not get microphone access on Windows:', micErr); + } - // Setup audio processing for Windows loopback audio only - setupWindowsLoopbackProcessing(); + // 2. Get system audio using native Electron loopback + try { + mediaStream = await navigator.mediaDevices.getDisplayMedia({ + video: true, + audio: true // This will now use native loopback from our handler + }); + + // Verify we got audio tracks + const audioTracks = mediaStream.getAudioTracks(); + if (audioTracks.length === 0) { + throw new Error('No audio track in native loopback stream'); + } + + console.log('Windows native loopback audio capture started'); + const { context, processor } = setupSystemAudioProcessing(mediaStream); + systemAudioContext = context; + systemAudioProcessor = processor; + } catch (sysAudioErr) { + console.error('Failed to start Windows native loopback audio:', sysAudioErr); + // Continue without system audio + } } // Start capturing screenshots - check if manual mode @@ -626,21 +672,31 @@ function stopCapture() { screenshotInterval = null; } + // Clean up microphone resources if (audioProcessor) { audioProcessor.disconnect(); audioProcessor = null; } - if (audioContext) { audioContext.close(); audioContext = null; } + // Clean up system audio resources + if (systemAudioProcessor) { + systemAudioProcessor.disconnect(); + systemAudioProcessor = null; + } + if (systemAudioContext) { + systemAudioContext.close(); + systemAudioContext = null; + } + + // Stop and release media stream tracks if (mediaStream) { mediaStream.getTracks().forEach(track => track.stop()); mediaStream = null; } - if (micMediaStream) { micMediaStream.getTracks().forEach(t => t.stop()); micMediaStream = null; diff --git a/src/features/listen/stt/sttService.js b/src/features/listen/stt/sttService.js index 294bd74..1206d5f 100644 --- a/src/features/listen/stt/sttService.js +++ b/src/features/listen/stt/sttService.js @@ -300,6 +300,21 @@ class SttService { await this.mySttSession.sendRealtimeInput(payload); } + async sendSystemAudioContent(data, mimeType) { + const provider = await this.getAiProvider(); + const isGemini = provider === 'gemini'; + + if (!this.theirSttSession) { + throw new Error('Their STT session not active'); + } + + const payload = isGemini + ? { audio: { data, mimeType: mimeType || 'audio/pcm;rate=24000' } } + : data; + + await this.theirSttSession.sendRealtimeInput(payload); + } + killExistingSystemAudioDump() { return new Promise(resolve => { console.log('Checking for existing SystemAudioDump processes...'); diff --git a/src/features/listen/summary/repositories/sqlite.repository.js b/src/features/listen/summary/repositories/sqlite.repository.js index b365090..008aa21 100644 --- a/src/features/listen/summary/repositories/sqlite.repository.js +++ b/src/features/listen/summary/repositories/sqlite.repository.js @@ -1,28 +1,30 @@ const sqliteClient = require('../../../../common/services/sqliteClient'); function saveSummary({ sessionId, tldr, text, bullet_json, action_json, model = 'gpt-4.1' }) { - const db = sqliteClient.getDb(); - const now = Math.floor(Date.now() / 1000); - const query = ` - INSERT INTO summaries (session_id, generated_at, model, text, tldr, bullet_json, action_json, updated_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(session_id) DO UPDATE SET - generated_at=excluded.generated_at, - model=excluded.model, - text=excluded.text, - tldr=excluded.tldr, - bullet_json=excluded.bullet_json, - action_json=excluded.action_json, - updated_at=excluded.updated_at - `; - - try { - const result = db.prepare(query).run(sessionId, now, model, text, tldr, bullet_json, action_json, now); - return { changes: result.changes }; - } catch (err) { - console.error('Error saving summary:', err); - throw err; - } + return new Promise((resolve, reject) => { + try { + const db = sqliteClient.getDb(); + const now = Math.floor(Date.now() / 1000); + const query = ` + INSERT INTO summaries (session_id, generated_at, model, text, tldr, bullet_json, action_json, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(session_id) DO UPDATE SET + generated_at=excluded.generated_at, + model=excluded.model, + text=excluded.text, + tldr=excluded.tldr, + bullet_json=excluded.bullet_json, + action_json=excluded.action_json, + updated_at=excluded.updated_at + `; + + const result = db.prepare(query).run(sessionId, now, model, text, tldr, bullet_json, action_json, now); + resolve({ changes: result.changes }); + } catch (err) { + console.error('Error saving summary:', err); + reject(err); + } + }); } function getSummaryBySessionId(sessionId) { diff --git a/src/index.js b/src/index.js index 52c057f..340e91b 100644 --- a/src/index.js +++ b/src/index.js @@ -11,7 +11,7 @@ if (require('electron-squirrel-startup')) { process.exit(0); } -const { app, BrowserWindow, shell, ipcMain, dialog } = require('electron'); +const { app, BrowserWindow, shell, ipcMain, dialog, desktopCapturer, session } = require('electron'); const { createWindows } = require('./electron/windowManager.js'); const ListenService = require('./features/listen/listenService'); const { initializeFirebase } = require('./common/services/firebaseClient'); @@ -162,6 +162,17 @@ setupProtocolHandling(); app.whenReady().then(async () => { + // Setup native loopback audio capture for Windows + session.defaultSession.setDisplayMediaRequestHandler((request, callback) => { + desktopCapturer.getSources({ types: ['screen'] }).then((sources) => { + // Grant access to the first screen found with loopback audio + callback({ video: sources[0], audio: 'loopback' }); + }).catch((error) => { + console.error('Failed to get desktop capturer sources:', error); + callback({}); + }); + }); + // Initialize core services initializeFirebase(); From 17557053392d8f1225da591477b9dde1f0372060 Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Tue, 8 Jul 2025 02:50:57 +0900 Subject: [PATCH 32/52] summary fix --- src/features/listen/summary/summaryService.js | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/features/listen/summary/summaryService.js b/src/features/listen/summary/summaryService.js index 860fa35..58a4ecc 100644 --- a/src/features/listen/summary/summaryService.js +++ b/src/features/listen/summary/summaryService.js @@ -174,14 +174,18 @@ Keep all points concise and build upon previous analysis if provided.`, const structuredData = this.parseResponseText(responseText, this.previousAnalysisResult); if (this.currentSessionId) { - summaryRepository.saveSummary({ - sessionId: this.currentSessionId, - text: responseText, - tldr: structuredData.summary.join('\n'), - bullet_json: JSON.stringify(structuredData.topic.bullets), - action_json: JSON.stringify(structuredData.actions), - model: 'gpt-4.1' - }).catch(err => console.error('[DB] Failed to save summary:', err)); + try { + summaryRepository.saveSummary({ + sessionId: this.currentSessionId, + text: responseText, + tldr: structuredData.summary.join('\n'), + bullet_json: JSON.stringify(structuredData.topic.bullets), + action_json: JSON.stringify(structuredData.actions), + model: 'gpt-4.1' + }); + } catch (err) { + console.error('[DB] Failed to save summary:', err); + } } // 분석 결과 저장 From 649c3b5c3150b5640d4d4479652275b7b3347c0e Mon Sep 17 00:00:00 2001 From: sanio Date: Tue, 8 Jul 2025 06:09:14 +0900 Subject: [PATCH 33/52] add modelStateService for provider, model, apikey selection --- src/app/ApiKeyHeader.js | 344 +++++-------- src/app/HeaderController.js | 42 +- src/common/ai/factory.js | 141 +++-- src/common/services/authService.js | 53 +- src/common/services/modelStateService.js | 324 ++++++++++++ src/electron/windowManager.js | 220 +++++--- src/features/ask/askService.js | 45 +- src/features/listen/stt/sttService.js | 123 +++-- src/features/listen/summary/summaryService.js | 59 +-- src/features/settings/SettingsView.js | 483 ++++++++++++++++-- src/index.js | 9 + 11 files changed, 1282 insertions(+), 561 deletions(-) create mode 100644 src/common/services/modelStateService.js diff --git a/src/app/ApiKeyHeader.js b/src/app/ApiKeyHeader.js index 25f1571..92962c8 100644 --- a/src/app/ApiKeyHeader.js +++ b/src/app/ApiKeyHeader.js @@ -1,12 +1,17 @@ import { html, css, LitElement } from "../assets/lit-core-2.7.4.min.js" export class ApiKeyHeader extends LitElement { + //////// after_modelStateService //////// static properties = { - apiKey: { type: String }, + llmApiKey: { type: String }, + sttApiKey: { type: String }, + llmProvider: { type: String }, + sttProvider: { type: String }, isLoading: { type: Boolean }, errorMessage: { type: String }, - selectedProvider: { type: String }, + providers: { type: Object, state: true }, } + //////// after_modelStateService //////// static styles = css` :host { @@ -45,7 +50,7 @@ export class ApiKeyHeader extends LitElement { } .container { - width: 285px; + width: 350px; min-height: 260px; padding: 18px 20px; background: rgba(0, 0, 0, 0.3); @@ -153,28 +158,22 @@ export class ApiKeyHeader extends LitElement { outline: none; } - .provider-select { + .providers-container { display: flex; gap: 12px; width: 100%; } + .provider-column { flex: 1; display: flex; flex-direction: column; align-items: center; } + .provider-label { color: rgba(255, 255, 255, 0.7); font-size: 11px; font-weight: 500; margin-bottom: 6px; } + .api-input, .provider-select { width: 100%; height: 34px; + text-align: center; background: rgba(255, 255, 255, 0.1); border-radius: 10px; border: 1px solid rgba(255, 255, 255, 0.2); padding: 0 10px; color: white; font-size: 12px; - font-weight: 400; margin-bottom: 6px; - text-align: center; - cursor: pointer; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2714%27%20height%3D%278%27%20viewBox%3D%270%200%2014%208%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%3E%3Cpath%20d%3D%27M1%201l6%206%206-6%27%20stroke%3D%27%23ffffff%27%20stroke-width%3D%271.5%27%20fill%3D%27none%27%20fill-rule%3D%27evenodd%27/%3E%3C/svg%3E'); - background-repeat: no-repeat; - background-position: right 10px center; - background-size: 12px; - padding-right: 30px; } + .provider-select option { background: #1a1a1a; color: white; } .provider-select:hover { background-color: rgba(255, 255, 255, 0.15); @@ -187,11 +186,6 @@ export class ApiKeyHeader extends LitElement { border-color: rgba(255, 255, 255, 0.4); } - .provider-select option { - background: #1a1a1a; - color: white; - padding: 5px; - } .action-button { width: 100%; @@ -239,15 +233,7 @@ export class ApiKeyHeader extends LitElement { font-weight: 500; /* Medium */ margin: 10px 0; } - - .provider-label { - color: rgba(255, 255, 255, 0.7); - font-size: 11px; - font-weight: 400; - margin-bottom: 4px; - width: 100%; - text-align: left; - } + /* ────────────────[ GLASS BYPASS ]─────────────── */ :host-context(body.has-glass) .container, @@ -278,11 +264,16 @@ export class ApiKeyHeader extends LitElement { super() this.dragState = null this.wasJustDragged = false - this.apiKey = "" this.isLoading = false this.errorMessage = "" - this.validatedApiKey = null - this.selectedProvider = "openai" + //////// after_modelStateService //////// + this.llmApiKey = ""; + this.sttApiKey = ""; + this.llmProvider = "openai"; + this.sttProvider = "openai"; + this.providers = { llm: [], stt: [] }; // 초기화 + this.loadProviderConfig(); + //////// after_modelStateService //////// this.handleMouseMove = this.handleMouseMove.bind(this) this.handleMouseUp = this.handleMouseUp.bind(this) @@ -303,6 +294,35 @@ export class ApiKeyHeader extends LitElement { this.requestUpdate() } + async loadProviderConfig() { + if (!window.require) return; + const { ipcRenderer } = window.require('electron'); + const config = await ipcRenderer.invoke('model:get-provider-config'); + + const llmProviders = []; + const sttProviders = []; + + for (const id in config) { + // 'openai-glass' 같은 가상 Provider는 UI에 표시하지 않음 + if (id.includes('-glass')) continue; + + if (config[id].llmModels.length > 0) { + llmProviders.push({ id, name: config[id].name }); + } + if (config[id].sttModels.length > 0) { + sttProviders.push({ id, name: config[id].name }); + } + } + + this.providers = { llm: llmProviders, stt: sttProviders }; + + // 기본 선택 값 설정 + if (llmProviders.length > 0) this.llmProvider = llmProviders[0].id; + if (sttProviders.length > 0) this.sttProvider = sttProviders[0].id; + + this.requestUpdate(); +} + async handleMouseDown(e) { if (e.target.tagName === "INPUT" || e.target.tagName === "BUTTON" || e.target.tagName === "SELECT") { return @@ -409,144 +429,45 @@ export class ApiKeyHeader extends LitElement { } } + //////// after_modelStateService //////// async handleSubmit() { - if (this.wasJustDragged || this.isLoading || !this.apiKey.trim()) { - console.log("Submit blocked:", { - wasJustDragged: this.wasJustDragged, - isLoading: this.isLoading, - hasApiKey: !!this.apiKey.trim(), - }) - return + console.log('[ApiKeyHeader] handleSubmit: Submitting API keys...'); + if (this.isLoading || !this.llmApiKey.trim() || !this.sttApiKey.trim()) { + this.errorMessage = "Please enter keys for both LLM and STT."; + return; } - console.log("Starting API key validation...") - this.isLoading = true - this.errorMessage = "" - this.requestUpdate() + this.isLoading = true; + this.errorMessage = ""; + this.requestUpdate(); - const apiKey = this.apiKey.trim() - const isValid = false - try { - const isValid = await this.validateApiKey(this.apiKey.trim(), this.selectedProvider) + const { ipcRenderer } = window.require('electron'); - if (isValid) { - console.log("API key valid - starting slide out animation") - this.startSlideOutAnimation() - this.validatedApiKey = this.apiKey.trim() - this.validatedProvider = this.selectedProvider - } else { - this.errorMessage = "Invalid API key - please check and try again" - console.log("API key validation failed") - } - } catch (error) { - console.error("API key validation error:", error) - this.errorMessage = "Validation error - please try again" - } finally { - this.isLoading = false - this.requestUpdate() - } - } + console.log('[ApiKeyHeader] handleSubmit: Validating LLM key...'); + const llmValidation = ipcRenderer.invoke('model:validate-key', { provider: this.llmProvider, key: this.llmApiKey.trim() }); + const sttValidation = ipcRenderer.invoke('model:validate-key', { provider: this.sttProvider, key: this.sttApiKey.trim() }); - async validateApiKey(apiKey, provider = "openai") { - if (!apiKey || apiKey.length < 15) return false + const [llmResult, sttResult] = await Promise.all([llmValidation, sttValidation]); - if (provider === "openai") { - if (!apiKey.match(/^[A-Za-z0-9_-]+$/)) return false - - try { - console.log("Validating OpenAI API key...") - - const response = await fetch("https://api.openai.com/v1/models", { - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${apiKey}`, - }, - }) - - if (response.ok) { - const data = await response.json() - - const hasGPTModels = data.data && data.data.some((m) => m.id.startsWith("gpt-")) - if (hasGPTModels) { - console.log("OpenAI API key validation successful") - return true - } else { - console.log("API key valid but no GPT models available") - return false - } - } else { - const errorData = await response.json().catch(() => ({})) - console.log("API key validation failed:", response.status, errorData.error?.message || "Unknown error") - return false - } - } catch (error) { - console.error("API key validation network error:", error) - return apiKey.length >= 20 // Fallback for network issues - } - } else if (provider === "gemini") { - // Gemini API keys typically start with 'AIza' - if (!apiKey.match(/^[A-Za-z0-9_-]+$/)) return false - - try { - console.log("Validating Gemini API key...") - - // Test the API key with a simple models list request - const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`) - - if (response.ok) { - const data = await response.json() - if (data.models && data.models.length > 0) { - console.log("Gemini API key validation successful") - return true - } - } - - console.log("Gemini API key validation failed") - return false - } catch (error) { - console.error("Gemini API key validation network error:", error) - return apiKey.length >= 20 // Fallback - } - } else if (provider === "anthropic") { - // Anthropic API keys typically start with 'sk-ant-' - if (!apiKey.startsWith("sk-ant-") || !apiKey.match(/^[A-Za-z0-9_-]+$/)) return false - - try { - console.log("Validating Anthropic API key...") - - // Test the API key with a simple request - const response = await fetch("https://api.anthropic.com/v1/messages", { - method: "POST", - headers: { - "Content-Type": "application/json", - "x-api-key": apiKey, - "anthropic-version": "2023-06-01", - }, - body: JSON.stringify({ - model: "claude-3-haiku-20240307", - max_tokens: 10, - messages: [{ role: "user", content: "Hi" }], - }), - }) - - if (response.ok || response.status === 400) { - // 400 is also acceptable as it means the API key is valid but request format might be wrong - console.log("Anthropic API key validation successful") - return true - } - - console.log("Anthropic API key validation failed:", response.status) - return false - } catch (error) { - console.error("Anthropic API key validation network error:", error) - return apiKey.length >= 20 // Fallback - } + if (llmResult.success && sttResult.success) { + console.log('[ApiKeyHeader] handleSubmit: Both LLM and STT keys are valid.'); + this.startSlideOutAnimation(); + } else { + console.log('[ApiKeyHeader] handleSubmit: Validation failed.'); + let errorParts = []; + if (!llmResult.success) errorParts.push(`LLM Key: ${llmResult.error || 'Invalid'}`); + if (!sttResult.success) errorParts.push(`STT Key: ${sttResult.error || 'Invalid'}`); + this.errorMessage = errorParts.join(' | '); } - return false - } + this.isLoading = false; + this.requestUpdate(); +} +//////// after_modelStateService //////// + startSlideOutAnimation() { + console.log('[ApiKeyHeader] startSlideOutAnimation: Starting slide out animation.'); this.classList.add("sliding-out") } @@ -567,25 +488,18 @@ export class ApiKeyHeader extends LitElement { } } + + //////// after_modelStateService //////// handleAnimationEnd(e) { - if (e.target !== this) return - - if (this.classList.contains("sliding-out")) { - this.classList.remove("sliding-out") - this.classList.add("hidden") - - if (this.validatedApiKey) { - if (window.require) { - window.require("electron").ipcRenderer.invoke("api-key-validated", { - apiKey: this.validatedApiKey, - provider: this.validatedProvider || "openai", - }) - } - this.validatedApiKey = null - this.validatedProvider = null - } - } + if (e.target !== this || !this.classList.contains('sliding-out')) return; + this.classList.remove("sliding-out"); + this.classList.add("hidden"); + window.require('electron').ipcRenderer.invoke('get-current-user').then(userState => { + console.log('[ApiKeyHeader] handleAnimationEnd: User state updated:', userState); + this.stateUpdateCallback?.(userState); + }); } +//////// after_modelStateService //////// connectedCallback() { super.connectedCallback() @@ -598,64 +512,40 @@ export class ApiKeyHeader extends LitElement { } render() { - const isButtonDisabled = this.isLoading || !this.apiKey || !this.apiKey.trim() - console.log("Rendering with provider:", this.selectedProvider) + const isButtonDisabled = this.isLoading || !this.llmApiKey.trim() || !this.sttApiKey.trim(); return html` -
- -

Choose how to power your AI

+
+

Enter Your API Keys

-
-
${this.errorMessage}
-
Select AI Provider:
- this.llmProvider = e.target.value} ?disabled=${this.isLoading}> + ${this.providers.llm.map(p => html``)} - (this.errorMessage = "")} - ?disabled=${this.isLoading} - autocomplete="off" - spellcheck="false" - tabindex="0" - /> + this.llmApiKey = e.target.value} ?disabled=${this.isLoading}> +
- - -
or
- - +
+
+ + this.sttApiKey = e.target.value} ?disabled=${this.isLoading}>
- ` - } + +
${this.errorMessage}
+ + +
or
+ +
+ `; +} } customElements.define("apikey-header", ApiKeyHeader) diff --git a/src/app/HeaderController.js b/src/app/HeaderController.js index 26313f1..e2c5fe8 100644 --- a/src/app/HeaderController.js +++ b/src/app/HeaderController.js @@ -15,7 +15,11 @@ class HeaderTransitionManager { * @param {'apikey'|'main'|'permission'} type */ this.ensureHeader = (type) => { - if (this.currentHeaderType === type) return; + console.log('[HeaderController] ensureHeader: Ensuring header of type:', type); + if (this.currentHeaderType === type) { + console.log('[HeaderController] ensureHeader: Header of type:', type, 'already exists.'); + return; + } this.headerContainer.innerHTML = ''; @@ -26,6 +30,7 @@ class HeaderTransitionManager { // Create new header element if (type === 'apikey') { this.apiKeyHeader = document.createElement('apikey-header'); + this.apiKeyHeader.stateUpdateCallback = (userState) => this.handleStateUpdate(userState); this.headerContainer.appendChild(this.apiKeyHeader); } else if (type === 'permission') { this.permissionHeader = document.createElement('permission-setup'); @@ -60,6 +65,11 @@ class HeaderTransitionManager { this.apiKeyHeader.isLoading = false; } }); + ipcRenderer.on('force-show-apikey-header', async () => { + console.log('[HeaderController] Received broadcast to show apikey header. Switching now.'); + await this._resizeForApiKey(); + this.ensureHeader('apikey'); + }); } } @@ -83,26 +93,30 @@ class HeaderTransitionManager { } } - async handleStateUpdate(userState) { - const { isLoggedIn, hasApiKey } = userState; - if (isLoggedIn) { - // Firebase user: Check permissions, then show Main or Permission header - const permissionResult = await this.checkPermissions(); - if (permissionResult.success) { - this.transitionToMainHeader(); + //////// after_modelStateService //////// + async handleStateUpdate(userState) { + const { ipcRenderer } = window.require('electron'); + const isConfigured = await ipcRenderer.invoke('model:are-providers-configured'); + + if (isConfigured) { + const { isLoggedIn } = userState; + if (isLoggedIn) { + const permissionResult = await this.checkPermissions(); + if (permissionResult.success) { + this.transitionToMainHeader(); + } else { + this.transitionToPermissionHeader(); + } } else { - this.transitionToPermissionHeader(); + this.transitionToMainHeader(); } - } else if (hasApiKey) { - // API Key only user: Skip permission check, go directly to Main - this.transitionToMainHeader(); } else { - // No auth at all await this._resizeForApiKey(); this.ensureHeader('apikey'); } } + //////// after_modelStateService //////// async transitionToPermissionHeader() { // Prevent duplicate transitions @@ -159,7 +173,7 @@ class HeaderTransitionManager { if (!window.require) return; return window .require('electron') - .ipcRenderer.invoke('resize-header-window', { width: 285, height: 300 }) + .ipcRenderer.invoke('resize-header-window', { width: 350, height: 300 }) .catch(() => {}); } diff --git a/src/common/ai/factory.js b/src/common/ai/factory.js index 8d0d6b5..ea86ff0 100644 --- a/src/common/ai/factory.js +++ b/src/common/ai/factory.js @@ -1,68 +1,121 @@ -const providers = { - openai: require("./providers/openai"), - gemini: require("./providers/gemini"), - anthropic: require("./providers/anthropic"), - // 추가 provider는 여기에 등록 -} +// factory.js /** - * Creates an STT session based on provider - * @param {string} provider - Provider name ('openai', 'gemini', etc.) - * @param {object} opts - Configuration options (apiKey, language, callbacks, etc.) - * @returns {Promise} STT session object with sendRealtimeInput and close methods + * @typedef {object} ModelOption + * @property {string} id + * @property {string} name */ + +/** + * @typedef {object} Provider + * @property {string} name + * @property {() => any} handler + * @property {ModelOption[]} llmModels + * @property {ModelOption[]} sttModels + */ + +/** + * @type {Object.} + */ +const PROVIDERS = { + 'openai': { + name: 'OpenAI', + handler: () => require("./providers/openai"), + llmModels: [ + { id: 'gpt-4.1', name: 'GPT-4.1' }, + ], + sttModels: [ + { id: 'gpt-4o-mini-transcribe', name: 'GPT-4o Mini Transcribe' } + ], + }, + + 'openai-glass': { + name: 'OpenAI (Glass)', + handler: () => require("./providers/openai"), + llmModels: [ + { id: 'gpt-4.1-glass', name: 'GPT-4.1 (glass)' }, + ], + sttModels: [ + { id: 'gpt-4o-mini-transcribe-glass', name: 'GPT-4o Mini Transcribe (glass)' } + ], + }, + 'gemini': { + name: 'Gemini', + handler: () => require("./providers/gemini"), + llmModels: [ + { id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash' }, + ], + sttModels: [ + { id: 'gemini-live-2.5-flash-preview', name: 'Gemini Live 2.5 Flash' } + ], + }, + 'anthropic': { + name: 'Anthropic', + handler: () => require("./providers/anthropic"), + llmModels: [ + { id: 'claude-3-5-sonnet-20241022', name: 'Claude 3.5 Sonnet' }, + ], + sttModels: [], + }, +}; + +function sanitizeModelId(model) { + return (typeof model === 'string') ? model.replace(/-glass$/, '') : model; +} + function createSTT(provider, opts) { - if (!providers[provider]?.createSTT) { - throw new Error(`STT not supported for provider: ${provider}`) + if (provider === 'openai-glass') provider = 'openai'; + + const handler = PROVIDERS[provider]?.handler(); + if (!handler?.createSTT) { + throw new Error(`STT not supported for provider: ${provider}`); } - return providers[provider].createSTT(opts) + if (opts && opts.model) { + opts = { ...opts, model: sanitizeModelId(opts.model) }; + } + return handler.createSTT(opts); } -/** - * Creates an LLM instance based on provider - * @param {string} provider - Provider name ('openai', 'gemini', etc.) - * @param {object} opts - Configuration options (apiKey, model, temperature, etc.) - * @returns {object} LLM instance with generateContent method - */ function createLLM(provider, opts) { - if (!providers[provider]?.createLLM) { - throw new Error(`LLM not supported for provider: ${provider}`) + if (provider === 'openai-glass') provider = 'openai'; + + const handler = PROVIDERS[provider]?.handler(); + if (!handler?.createLLM) { + throw new Error(`LLM not supported for provider: ${provider}`); } - return providers[provider].createLLM(opts) + if (opts && opts.model) { + opts = { ...opts, model: sanitizeModelId(opts.model) }; + } + return handler.createLLM(opts); } -/** - * Creates a streaming LLM instance based on provider - * @param {string} provider - Provider name ('openai', 'gemini', etc.) - * @param {object} opts - Configuration options (apiKey, model, temperature, etc.) - * @returns {object} Streaming LLM instance - */ function createStreamingLLM(provider, opts) { - if (!providers[provider]?.createStreamingLLM) { - throw new Error(`Streaming LLM not supported for provider: ${provider}`) + if (provider === 'openai-glass') provider = 'openai'; + + const handler = PROVIDERS[provider]?.handler(); + if (!handler?.createStreamingLLM) { + throw new Error(`Streaming LLM not supported for provider: ${provider}`); } - return providers[provider].createStreamingLLM(opts) + if (opts && opts.model) { + opts = { ...opts, model: sanitizeModelId(opts.model) }; + } + return handler.createStreamingLLM(opts); } -/** - * Gets list of available providers - * @returns {object} Object with stt and llm arrays - */ function getAvailableProviders() { - const sttProviders = [] - const llmProviders = [] - - for (const [name, provider] of Object.entries(providers)) { - if (provider.createSTT) sttProviders.push(name) - if (provider.createLLM) llmProviders.push(name) + const stt = []; + const llm = []; + for (const [id, provider] of Object.entries(PROVIDERS)) { + if (provider.sttModels.length > 0) stt.push(id); + if (provider.llmModels.length > 0) llm.push(id); } - - return { stt: sttProviders, llm: llmProviders } + return { stt: [...new Set(stt)], llm: [...new Set(llm)] }; } module.exports = { + PROVIDERS, createSTT, createLLM, createStreamingLLM, getAvailableProviders, -} +}; \ No newline at end of file diff --git a/src/common/services/authService.js b/src/common/services/authService.js index f41f87e..a664ba1 100644 --- a/src/common/services/authService.js +++ b/src/common/services/authService.js @@ -36,7 +36,6 @@ class AuthService { this.currentUserId = 'default_user'; this.currentUserMode = 'local'; // 'local' or 'firebase' this.currentUser = null; - this.hasApiKey = false; // Add a flag for API key status this.isInitialized = false; } @@ -53,20 +52,18 @@ class AuthService { this.currentUser = user; this.currentUserId = user.uid; this.currentUserMode = 'firebase'; - this.hasApiKey = false; // Optimistically assume no key yet - - // Broadcast immediately to make UI feel responsive - this.broadcastUserState(); // Start background task to fetch and save virtual key (async () => { try { const idToken = await user.getIdToken(true); const virtualKey = await getVirtualKeyByEmail(user.email, idToken); - await userRepository.saveApiKey(virtualKey, user.uid, 'openai'); - console.log(`[AuthService] BG: Virtual key for ${user.email} has been saved.`); - // Now update the key status, which will trigger another broadcast - await this.updateApiKeyStatus(); + + if (global.modelStateService) { + global.modelStateService.setFirebaseVirtualKey(virtualKey); + } + console.log(`[AuthService] BG: Virtual key for ${user.email} has been processed.`); + } catch (error) { console.error('[AuthService] BG: Failed to fetch or save virtual key:', error); } @@ -74,23 +71,20 @@ class AuthService { } else { // User signed OUT - console.log(`[AuthService] Firebase user signed out.`); + console.log(`[AuthService] No Firebase user.`); if (previousUser) { console.log(`[AuthService] Clearing API key for logged-out user: ${previousUser.uid}`); - await userRepository.saveApiKey(null, previousUser.uid); + if (global.modelStateService) { + global.modelStateService.setFirebaseVirtualKey(null); + } } this.currentUser = null; this.currentUserId = 'default_user'; this.currentUserMode = 'local'; - // Update API key status (e.g., if a local key for default_user exists) - // This will also broadcast the final logged-out state. - await this.updateApiKeyStatus(); } + this.broadcastUserState(); }); - // Check for initial API key state - this.updateApiKeyStatus(); - this.isInitialized = true; console.log('[AuthService] Initialized and attached to Firebase Auth state.'); } @@ -129,23 +123,6 @@ class AuthService { }); } - /** - * Updates the internal API key status from the repository and broadcasts if changed. - */ - async updateApiKeyStatus() { - try { - const user = await userRepository.getById(this.currentUserId); - const newStatus = !!(user && user.api_key); - if (this.hasApiKey !== newStatus) { - console.log(`[AuthService] API key status changed to: ${newStatus}`); - this.hasApiKey = newStatus; - this.broadcastUserState(); - } - } catch (error) { - console.error('[AuthService] Error checking API key status:', error); - this.hasApiKey = false; - } - } getCurrentUserId() { return this.currentUserId; @@ -161,7 +138,9 @@ class AuthService { displayName: this.currentUser.displayName, mode: 'firebase', isLoggedIn: true, - hasApiKey: this.hasApiKey // Always true for firebase users, but good practice + //////// before_modelStateService //////// + // hasApiKey: this.hasApiKey // Always true for firebase users, but good practice + //////// before_modelStateService //////// }; } return { @@ -170,7 +149,9 @@ class AuthService { displayName: 'Default User', mode: 'local', isLoggedIn: false, - hasApiKey: this.hasApiKey + //////// before_modelStateService //////// + // hasApiKey: this.hasApiKey + //////// before_modelStateService //////// }; } } diff --git a/src/common/services/modelStateService.js b/src/common/services/modelStateService.js new file mode 100644 index 0000000..33de127 --- /dev/null +++ b/src/common/services/modelStateService.js @@ -0,0 +1,324 @@ +const Store = require('electron-store'); +const fetch = require('node-fetch'); +const { ipcMain, webContents } = require('electron'); +const { PROVIDERS } = require('../ai/factory'); + +class ModelStateService { + constructor(authService) { + this.authService = authService; + this.store = new Store({ name: 'pickle-glass-model-state' }); + this.state = {}; + } + + initialize() { + this._loadStateForCurrentUser(); + + this.setupIpcHandlers(); + console.log('[ModelStateService] Initialized.'); + } + + _logCurrentSelection() { + const llmModel = this.state.selectedModels.llm; + const sttModel = this.state.selectedModels.stt; + const llmProvider = this.getProviderForModel('llm', llmModel) || 'None'; + const sttProvider = this.getProviderForModel('stt', sttModel) || 'None'; + + console.log(`[ModelStateService] 🌟 Current Selection -> LLM: ${llmModel || 'None'} (Provider: ${llmProvider}), STT: ${sttModel || 'None'} (Provider: ${sttProvider})`); + } + + _autoSelectAvailableModels() { + console.log('[ModelStateService] Running auto-selection for models...'); + const types = ['llm', 'stt']; + + types.forEach(type => { + const currentModelId = this.state.selectedModels[type]; + let isCurrentModelValid = false; + + if (currentModelId) { + const provider = this.getProviderForModel(type, currentModelId); + if (provider && this.getApiKey(provider)) { + isCurrentModelValid = true; + } + } + + if (!isCurrentModelValid) { + console.log(`[ModelStateService] No valid ${type.toUpperCase()} model selected. Finding an alternative...`); + const availableModels = this.getAvailableModels(type); + if (availableModels.length > 0) { + this.state.selectedModels[type] = availableModels[0].id; + console.log(`[ModelStateService] Auto-selected ${type.toUpperCase()} model: ${availableModels[0].id}`); + } else { + this.state.selectedModels[type] = null; + } + } + }); + } + + _loadStateForCurrentUser() { + const userId = this.authService.getCurrentUserId(); + const initialApiKeys = Object.keys(PROVIDERS).reduce((acc, key) => { + acc[key] = null; + return acc; + }, {}); + + const defaultState = { + apiKeys: initialApiKeys, + selectedModels: { llm: null, stt: null }, + }; + this.state = this.store.get(`users.${userId}`, defaultState); + console.log(`[ModelStateService] State loaded for user: ${userId}`); + this._autoSelectAvailableModels(); + this._saveState(); + this._logCurrentSelection(); + } + + + _saveState() { + const userId = this.authService.getCurrentUserId(); + this.store.set(`users.${userId}`, this.state); + console.log(`[ModelStateService] State saved for user: ${userId}`); + this._logCurrentSelection(); + } + + async validateApiKey(provider, key) { + if (!key || key.trim() === '') { + return { success: false, error: 'API key cannot be empty.' }; + } + + let validationUrl, headers; + const body = undefined; + + switch (provider) { + case 'openai': + validationUrl = 'https://api.openai.com/v1/models'; + headers = { 'Authorization': `Bearer ${key}` }; + break; + case 'gemini': + validationUrl = `https://generativelanguage.googleapis.com/v1beta/models?key=${key}`; + headers = {}; + break; + case 'anthropic': { + if (!key.startsWith('sk-ant-')) { + throw new Error('Invalid Anthropic key format.'); + } + const response = await fetch("https://api.anthropic.com/v1/messages", { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-api-key": key, + "anthropic-version": "2023-06-01", + }, + body: JSON.stringify({ + model: "claude-3-haiku-20240307", + max_tokens: 1, + messages: [{ role: "user", content: "Hi" }], + }), + }); + + if (!response.ok && response.status !== 400) { + const errorData = await response.json().catch(() => ({})); + return { success: false, error: errorData.error?.message || `Validation failed with status: ${response.status}` }; + } + + console.log(`[ModelStateService] API key for ${provider} is valid.`); + this.setApiKey(provider, key); + return { success: true }; + } + default: + return { success: false, error: 'Unknown provider.' }; + } + + try { + const response = await fetch(validationUrl, { headers, body }); + if (response.ok) { + console.log(`[ModelStateService] API key for ${provider} is valid.`); + this.setApiKey(provider, key); + return { success: true }; + } else { + const errorData = await response.json().catch(() => ({})); + const message = errorData.error?.message || `Validation failed with status: ${response.status}`; + console.log(`[ModelStateService] API key for ${provider} is invalid: ${message}`); + return { success: false, error: message }; + } + } catch (error) { + console.error(`[ModelStateService] Network error during ${provider} key validation:`, error); + return { success: false, error: 'A network error occurred during validation.' }; + } + } + + setFirebaseVirtualKey(virtualKey) { + console.log(`[ModelStateService] Setting Firebase virtual key (for openai-glass).`); + this.state.apiKeys['openai-glass'] = virtualKey; + + const llmModels = PROVIDERS['openai-glass']?.llmModels; + const sttModels = PROVIDERS['openai-glass']?.sttModels; + + if (!this.state.selectedModels.llm && llmModels?.length > 0) { + this.state.selectedModels.llm = llmModels[0].id; + } + if (!this.state.selectedModels.stt && sttModels?.length > 0) { + this.state.selectedModels.stt = sttModels[0].id; + } + this._autoSelectAvailableModels(); + this._saveState(); + this._logCurrentSelection(); + } + + setApiKey(provider, key) { + if (provider in this.state.apiKeys) { + this.state.apiKeys[provider] = key; + + const llmModels = PROVIDERS[provider]?.llmModels; + const sttModels = PROVIDERS[provider]?.sttModels; + + if (!this.state.selectedModels.llm && llmModels?.length > 0) { + this.state.selectedModels.llm = llmModels[0].id; + } + if (!this.state.selectedModels.stt && sttModels?.length > 0) { + this.state.selectedModels.stt = sttModels[0].id; + } + this._saveState(); + this._logCurrentSelection(); + return true; + } + return false; + } + + getApiKey(provider) { + return this.state.apiKeys[provider] || null; + } + + getAllApiKeys() { + const { 'openai-glass': _, ...displayKeys } = this.state.apiKeys; + return displayKeys; + } + + removeApiKey(provider) { + if (provider in this.state.apiKeys) { + this.state.apiKeys[provider] = null; + const llmProvider = this.getProviderForModel('llm', this.state.selectedModels.llm); + if (llmProvider === provider) this.state.selectedModels.llm = null; + + const sttProvider = this.getProviderForModel('stt', this.state.selectedModels.stt); + if (sttProvider === provider) this.state.selectedModels.stt = null; + + this._autoSelectAvailableModels(); + this._saveState(); + this._logCurrentSelection(); + return true; + } + return false; + } + + getProviderForModel(type, modelId) { + if (!modelId) return null; + for (const providerId in PROVIDERS) { + const models = type === 'llm' ? PROVIDERS[providerId].llmModels : PROVIDERS[providerId].sttModels; + if (models.some(m => m.id === modelId)) { + return providerId; + } + } + return null; + } + + getCurrentProvider(type) { + const selectedModel = this.state.selectedModels[type]; + return this.getProviderForModel(type, selectedModel); + } + + isLoggedInWithFirebase() { + return this.authService.getCurrentUser().isLoggedIn; + } + + areProvidersConfigured() { + if (this.isLoggedInWithFirebase()) return true; + + // LLM과 STT 모델을 제공하는 Provider 중 하나라도 API 키가 설정되었는지 확인 + const hasLlmKey = Object.entries(this.state.apiKeys).some(([provider, key]) => key && PROVIDERS[provider]?.llmModels.length > 0); + const hasSttKey = Object.entries(this.state.apiKeys).some(([provider, key]) => key && PROVIDERS[provider]?.sttModels.length > 0); + + return hasLlmKey && hasSttKey; + } + + + getAvailableModels(type) { + const available = []; + const modelList = type === 'llm' ? 'llmModels' : 'sttModels'; + + Object.entries(this.state.apiKeys).forEach(([providerId, key]) => { + if (key && PROVIDERS[providerId]?.[modelList]) { + available.push(...PROVIDERS[providerId][modelList]); + } + }); + return [...new Map(available.map(item => [item.id, item])).values()]; + } + + getSelectedModels() { + return this.state.selectedModels; + } + + setSelectedModel(type, modelId) { + const provider = this.getProviderForModel(type, modelId); + if (provider && this.state.apiKeys[provider]) { + this.state.selectedModels[type] = modelId; + this._saveState(); + return true; + } + return false; + } + + /** + * + * @param {('llm' | 'stt')} type + * @returns {{provider: string, model: string, apiKey: string} | null} + */ + getCurrentModelInfo(type) { + this._logCurrentSelection(); + const model = this.state.selectedModels[type]; + if (!model) { + return null; + } + + const provider = this.getProviderForModel(type, model); + if (!provider) { + return null; + } + + const apiKey = this.getApiKey(provider); + return { provider, model, apiKey }; + } + + setupIpcHandlers() { + ipcMain.handle('model:validate-key', (e, { provider, key }) => this.validateApiKey(provider, key)); + ipcMain.handle('model:get-all-keys', () => this.getAllApiKeys()); + ipcMain.handle('model:set-api-key', (e, { provider, key }) => this.setApiKey(provider, key)); + ipcMain.handle('model:remove-api-key', (e, { provider }) => { + const success = this.removeApiKey(provider); + if (success) { + const selectedModels = this.getSelectedModels(); + if (!selectedModels.llm || !selectedModels.stt) { + webContents.getAllWebContents().forEach(wc => { + wc.send('force-show-apikey-header'); + }); + } + } + return success; + }); + ipcMain.handle('model:get-selected-models', () => this.getSelectedModels()); + ipcMain.handle('model:set-selected-model', (e, { type, modelId }) => this.setSelectedModel(type, modelId)); + ipcMain.handle('model:get-available-models', (e, { type }) => this.getAvailableModels(type)); + ipcMain.handle('model:are-providers-configured', () => this.areProvidersConfigured()); + ipcMain.handle('model:get-current-model-info', (e, { type }) => this.getCurrentModelInfo(type)); + + ipcMain.handle('model:get-provider-config', () => { + const serializableProviders = {}; + for (const key in PROVIDERS) { + const { handler, ...rest } = PROVIDERS[key]; + serializableProviders[key] = rest; + } + return serializableProviders; + }); + } +} + +module.exports = ModelStateService; \ No newline at end of file diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 4b540f6..32441b7 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -971,13 +971,15 @@ function setupIpcHandlers(movementManager) { console.log('[WindowManager] Received request to log out.'); await authService.signOut(); - await setApiKey(null); + //////// before_modelStateService //////// + // await setApiKey(null); - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-removed'); - } - }); + // windowPool.forEach(win => { + // if (win && !win.isDestroyed()) { + // win.webContents.send('api-key-removed'); + // } + // }); + //////// before_modelStateService //////// }); ipcMain.handle('check-system-permissions', async () => { @@ -1112,95 +1114,150 @@ function setupIpcHandlers(movementManager) { } -async function setApiKey(apiKey, provider = 'openai') { - console.log('[WindowManager] Persisting API key and provider to DB'); +//////// before_modelStateService //////// +// async function setApiKey(apiKey, provider = 'openai') { +// console.log('[WindowManager] Persisting API key and provider to DB'); - try { - await userRepository.saveApiKey(apiKey, authService.getCurrentUserId(), provider); - console.log('[WindowManager] API key and provider saved to SQLite'); +// try { +// await userRepository.saveApiKey(apiKey, authService.getCurrentUserId(), provider); +// console.log('[WindowManager] API key and provider saved to SQLite'); - // Notify authService that the key status may have changed - await authService.updateApiKeyStatus(); +// // Notify authService that the key status may have changed +// await authService.updateApiKeyStatus(); - } catch (err) { - console.error('[WindowManager] Failed to save API key to SQLite:', err); - } +// } catch (err) { +// console.error('[WindowManager] Failed to save API key to SQLite:', err); +// } - windowPool.forEach(win => { - if (win && !win.isDestroyed()) { - const js = apiKey ? ` - localStorage.setItem('openai_api_key', ${JSON.stringify(apiKey)}); - localStorage.setItem('ai_provider', ${JSON.stringify(provider)}); - ` : ` - localStorage.removeItem('openai_api_key'); - localStorage.removeItem('ai_provider'); - `; - win.webContents.executeJavaScript(js).catch(() => {}); - } - }); -} +// windowPool.forEach(win => { +// if (win && !win.isDestroyed()) { +// const js = apiKey ? ` +// localStorage.setItem('openai_api_key', ${JSON.stringify(apiKey)}); +// localStorage.setItem('ai_provider', ${JSON.stringify(provider)}); +// ` : ` +// localStorage.removeItem('openai_api_key'); +// localStorage.removeItem('ai_provider'); +// `; +// win.webContents.executeJavaScript(js).catch(() => {}); +// } +// }); +// } + +// async function getStoredApiKey() { +// const userId = authService.getCurrentUserId(); +// if (!userId) return null; +// const user = await userRepository.getById(userId); +// return user?.api_key || null; +// } + +// async function getStoredProvider() { +// const userId = authService.getCurrentUserId(); +// if (!userId) return 'openai'; +// const user = await userRepository.getById(userId); +// return user?.provider || 'openai'; +// } + +// function setupApiKeyIPC() { +// const { ipcMain } = require('electron'); + +// // Both handlers now do the same thing: fetch the key from the source of truth. +// ipcMain.handle('get-stored-api-key', getStoredApiKey); + +// ipcMain.handle('api-key-validated', async (event, data) => { +// console.log('[WindowManager] API key validation completed, saving...'); + +// // Support both old format (string) and new format (object) +// const apiKey = typeof data === 'string' ? data : data.apiKey; +// const provider = typeof data === 'string' ? 'openai' : (data.provider || 'openai'); + +// await setApiKey(apiKey, provider); + +// windowPool.forEach((win, name) => { +// if (win && !win.isDestroyed()) { +// win.webContents.send('api-key-validated', { apiKey, provider }); +// } +// }); + +// return { success: true }; +// }); + +// ipcMain.handle('remove-api-key', async () => { +// console.log('[WindowManager] API key removal requested'); +// await setApiKey(null); + +// windowPool.forEach((win, name) => { +// if (win && !win.isDestroyed()) { +// win.webContents.send('api-key-removed'); +// } +// }); + +// const settingsWindow = windowPool.get('settings'); +// if (settingsWindow && settingsWindow.isVisible()) { +// settingsWindow.hide(); +// console.log('[WindowManager] Settings window hidden after clearing API key.'); +// } + +// return { success: true }; +// }); + +// ipcMain.handle('get-ai-provider', getStoredProvider); + +// console.log('[WindowManager] API key related IPC handlers registered (SQLite-backed)'); +// } +//////// before_modelStateService //////// + + + + +//////// after_modelStateService //////// async function getStoredApiKey() { - const userId = authService.getCurrentUserId(); - if (!userId) return null; - const user = await userRepository.getById(userId); - return user?.api_key || null; + if (global.modelStateService) { + const provider = await getStoredProvider(); + return global.modelStateService.getApiKey(provider); + } + return null; // Fallback } async function getStoredProvider() { - const userId = authService.getCurrentUserId(); - if (!userId) return 'openai'; - const user = await userRepository.getById(userId); - return user?.provider || 'openai'; + if (global.modelStateService) { + return global.modelStateService.getCurrentProvider('llm'); + } + return 'openai'; // Fallback +} + +/** + * 렌더러에서 요청한 타입('llm' 또는 'stt')에 대한 모델 정보를 반환합니다. + * @param {IpcMainInvokeEvent} event - 일렉트론 IPC 이벤트 객체 + * @param {{type: 'llm' | 'stt'}} { type } - 요청할 모델 타입 + */ +async function getCurrentModelInfo(event, { type }) { + if (global.modelStateService && (type === 'llm' || type === 'stt')) { + return global.modelStateService.getCurrentModelInfo(type); + } + return null; // 서비스가 없거나 유효하지 않은 타입일 경우 null 반환 } function setupApiKeyIPC() { const { ipcMain } = require('electron'); - // Both handlers now do the same thing: fetch the key from the source of truth. ipcMain.handle('get-stored-api-key', getStoredApiKey); + ipcMain.handle('get-ai-provider', getStoredProvider); + ipcMain.handle('get-current-model-info', getCurrentModelInfo); ipcMain.handle('api-key-validated', async (event, data) => { - console.log('[WindowManager] API key validation completed, saving...'); - - // Support both old format (string) and new format (object) - const apiKey = typeof data === 'string' ? data : data.apiKey; - const provider = typeof data === 'string' ? 'openai' : (data.provider || 'openai'); - - await setApiKey(apiKey, provider); - - windowPool.forEach((win, name) => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-validated', { apiKey, provider }); - } - }); - + console.warn("[DEPRECATED] 'api-key-validated' IPC was called. This logic is now handled by 'model:validate-key'."); return { success: true }; }); ipcMain.handle('remove-api-key', async () => { - console.log('[WindowManager] API key removal requested'); - await setApiKey(null); - - windowPool.forEach((win, name) => { - if (win && !win.isDestroyed()) { - win.webContents.send('api-key-removed'); - } - }); - - const settingsWindow = windowPool.get('settings'); - if (settingsWindow && settingsWindow.isVisible()) { - settingsWindow.hide(); - console.log('[WindowManager] Settings window hidden after clearing API key.'); - } - + console.warn("[DEPRECATED] 'remove-api-key' IPC was called. This is now handled by 'model:remove-api-key'."); return { success: true }; }); - ipcMain.handle('get-ai-provider', getStoredProvider); - - console.log('[WindowManager] API key related IPC handlers registered (SQLite-backed)'); + console.log('[WindowManager] API key related IPC handlers have been updated for ModelStateService.'); } +//////// after_modelStateService //////// function getDefaultKeybinds() { @@ -1222,7 +1279,7 @@ function getDefaultKeybinds() { } function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementManager) { - console.log('Updating global shortcuts with:', keybinds); + // console.log('Updating global shortcuts with:', keybinds); // Unregister all existing shortcuts globalShortcut.unregisterAll(); @@ -1276,7 +1333,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan movementManager.moveStep(direction); } }); - console.log(`Registered global shortcut: ${key} -> ${direction}`); + // console.log(`Registered global shortcut: ${key} -> ${direction}`); } catch (error) { console.error(`Failed to register ${key}:`, error); } @@ -1316,7 +1373,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan } mainWindow.webContents.send('click-through-toggled', mouseEventsIgnored); }); - console.log(`Registered toggleClickThrough: ${keybinds.toggleClickThrough}`); + // console.log(`Registered toggleClickThrough: ${keybinds.toggleClickThrough}`); } catch (error) { console.error(`Failed to register toggleClickThrough (${keybinds.toggleClickThrough}):`, error); } @@ -1352,7 +1409,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan } } }); - console.log(`Registered Ask shortcut (nextStep): ${keybinds.nextStep}`); + // console.log(`Registered Ask shortcut (nextStep): ${keybinds.nextStep}`); } catch (error) { console.error(`Failed to register Ask shortcut (${keybinds.nextStep}):`, error); } @@ -1370,7 +1427,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan } `); }); - console.log(`Registered manualScreenshot: ${keybinds.manualScreenshot}`); + // console.log(`Registered manualScreenshot: ${keybinds.manualScreenshot}`); } catch (error) { console.error(`Failed to register manualScreenshot (${keybinds.manualScreenshot}):`, error); } @@ -1382,7 +1439,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan console.log('Previous response shortcut triggered'); sendToRenderer('navigate-previous-response'); }); - console.log(`Registered previousResponse: ${keybinds.previousResponse}`); + // console.log(`Registered previousResponse: ${keybinds.previousResponse}`); } catch (error) { console.error(`Failed to register previousResponse (${keybinds.previousResponse}):`, error); } @@ -1394,7 +1451,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan console.log('Next response shortcut triggered'); sendToRenderer('navigate-next-response'); }); - console.log(`Registered nextResponse: ${keybinds.nextResponse}`); + // console.log(`Registered nextResponse: ${keybinds.nextResponse}`); } catch (error) { console.error(`Failed to register nextResponse (${keybinds.nextResponse}):`, error); } @@ -1406,7 +1463,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan console.log('Scroll up shortcut triggered'); sendToRenderer('scroll-response-up'); }); - console.log(`Registered scrollUp: ${keybinds.scrollUp}`); + // console.log(`Registered scrollUp: ${keybinds.scrollUp}`); } catch (error) { console.error(`Failed to register scrollUp (${keybinds.scrollUp}):`, error); } @@ -1418,7 +1475,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan console.log('Scroll down shortcut triggered'); sendToRenderer('scroll-response-down'); }); - console.log(`Registered scrollDown: ${keybinds.scrollDown}`); + // console.log(`Registered scrollDown: ${keybinds.scrollDown}`); } catch (error) { console.error(`Failed to register scrollDown (${keybinds.scrollDown}):`, error); } @@ -1495,8 +1552,11 @@ module.exports = { createWindows, windowPool, fixedYPosition, - setApiKey, + //////// before_modelStateService //////// + // setApiKey, + //////// before_modelStateService //////// getStoredApiKey, getStoredProvider, + getCurrentModelInfo, captureScreenshot, }; \ No newline at end of file diff --git a/src/features/ask/askService.js b/src/features/ask/askService.js index 33428be..b59b65d 100644 --- a/src/features/ask/askService.js +++ b/src/features/ask/askService.js @@ -1,6 +1,6 @@ const { ipcMain, BrowserWindow } = require('electron'); const { createStreamingLLM } = require('../../common/ai/factory'); -const { getStoredApiKey, getStoredProvider, windowPool, captureScreenshot } = require('../../electron/windowManager'); +const { getStoredApiKey, getStoredProvider, getCurrentModelInfo, windowPool, captureScreenshot } = require('../../electron/windowManager'); const authService = require('../../common/services/authService'); const sessionRepository = require('../../common/repositories/session'); const askRepository = require('./repositories'); @@ -31,6 +31,12 @@ async function sendMessage(userPrompt) { try { console.log(`[AskService] 🤖 Processing message: ${userPrompt.substring(0, 50)}...`); + const modelInfo = await getCurrentModelInfo(null, { type: 'llm' }); + if (!modelInfo || !modelInfo.apiKey) { + throw new Error('AI model or API key not configured.'); + } + console.log(`[AskService] Using model: ${modelInfo.model} for provider: ${modelInfo.provider}`); + const screenshotResult = await captureScreenshot({ quality: 'medium' }); const screenshotBase64 = screenshotResult.success ? screenshotResult.base64 : null; @@ -39,10 +45,6 @@ async function sendMessage(userPrompt) { const systemPrompt = getSystemPrompt('pickle_glass_analysis', conversationHistory, false); - const API_KEY = await getStoredApiKey(); - if (!API_KEY) { - throw new Error('No API key found'); - } const messages = [ { role: 'system', content: systemPrompt }, @@ -61,36 +63,13 @@ async function sendMessage(userPrompt) { }); } - const provider = await getStoredProvider(); - const { isLoggedIn } = authService.getCurrentUser(); - - console.log(`[AskService] 🚀 Sending request to ${provider} AI...`); - - // FIX: Proper model selection for each provider - let model; - switch (provider) { - case 'openai': - model = 'gpt-4o'; // Use a valid OpenAI model - break; - case 'gemini': - model = 'gemini-2.0-flash-exp'; // Use a valid Gemini model - break; - case 'anthropic': - model = 'claude-3-5-sonnet-20241022'; // Use a valid Claude model - break; - default: - model = 'gpt-4o'; // Default fallback - } - - console.log(`[AskService] Using model: ${model} for provider: ${provider}`); - - const streamingLLM = createStreamingLLM(provider, { - apiKey: API_KEY, - model: model, + const streamingLLM = createStreamingLLM(modelInfo.provider, { + apiKey: modelInfo.apiKey, + model: modelInfo.model, temperature: 0.7, maxTokens: 2048, - usePortkey: provider === 'openai' && isLoggedIn, - portkeyVirtualKey: isLoggedIn ? API_KEY : undefined + usePortkey: modelInfo.provider === 'openai-glass', + portkeyVirtualKey: modelInfo.provider === 'openai-glass' ? modelInfo.apiKey : undefined, }); const response = await streamingLLM.streamChat(messages); diff --git a/src/features/listen/stt/sttService.js b/src/features/listen/stt/sttService.js index 294bd74..3722549 100644 --- a/src/features/listen/stt/sttService.js +++ b/src/features/listen/stt/sttService.js @@ -1,7 +1,7 @@ const { BrowserWindow } = require('electron'); const { spawn } = require('child_process'); const { createSTT } = require('../../../common/ai/factory'); -const { getStoredApiKey, getStoredProvider } = require('../../../electron/windowManager'); +const { getStoredApiKey, getStoredProvider, getCurrentModelInfo } = require('../../../electron/windowManager'); const COMPLETION_DEBOUNCE_MS = 2000; @@ -29,6 +29,8 @@ class SttService { // Callbacks this.onTranscriptionComplete = null; this.onStatusUpdate = null; + + this.modelInfo = null; } setCallbacks({ onTranscriptionComplete, onStatusUpdate }) { @@ -36,32 +38,32 @@ class SttService { this.onStatusUpdate = onStatusUpdate; } - async getApiKey() { - const storedKey = await getStoredApiKey(); - if (storedKey) { - console.log('[SttService] Using stored API key'); - return storedKey; - } + // async getApiKey() { + // const storedKey = await getStoredApiKey(); + // if (storedKey) { + // console.log('[SttService] Using stored API key'); + // return storedKey; + // } - const envKey = process.env.OPENAI_API_KEY; - if (envKey) { - console.log('[SttService] Using environment API key'); - return envKey; - } + // const envKey = process.env.OPENAI_API_KEY; + // if (envKey) { + // console.log('[SttService] Using environment API key'); + // return envKey; + // } - console.error('[SttService] No API key found in storage or environment'); - return null; - } + // console.error('[SttService] No API key found in storage or environment'); + // return null; + // } - async getAiProvider() { - try { - const { ipcRenderer } = require('electron'); - const provider = await ipcRenderer.invoke('get-ai-provider'); - return provider || 'openai'; - } catch (error) { - return getStoredProvider ? getStoredProvider() : 'openai'; - } - } + // async getAiProvider() { + // try { + // const { ipcRenderer } = require('electron'); + // const provider = await ipcRenderer.invoke('get-ai-provider'); + // return provider || 'openai'; + // } catch (error) { + // return getStoredProvider ? getStoredProvider() : 'openai'; + // } + // } sendToRenderer(channel, data) { BrowserWindow.getAllWindows().forEach(win => { @@ -156,17 +158,25 @@ class SttService { async initializeSttSessions(language = 'en') { const effectiveLanguage = process.env.OPENAI_TRANSCRIBE_LANG || language || 'en'; - const API_KEY = await this.getApiKey(); - if (!API_KEY) { - throw new Error('No API key available'); - } + // const API_KEY = await this.getApiKey(); + // if (!API_KEY) { + // throw new Error('No API key available'); + // } + // const provider = await this.getAiProvider(); - const provider = await this.getAiProvider(); - const isGemini = provider === 'gemini'; - console.log(`[SttService] Initializing STT for provider: ${provider}`); + const modelInfo = await getCurrentModelInfo(null, { type: 'stt' }); + if (!modelInfo || !modelInfo.apiKey) { + throw new Error('AI model or API key is not configured.'); + } + this.modelInfo = modelInfo; + console.log(`[SttService] Initializing STT for ${modelInfo.provider} using model ${modelInfo.model}`); + + + // const isGemini = modelInfo.provider === 'gemini'; + // console.log(`[SttService] Initializing STT for provider: ${modelInfo.provider}`); const handleMyMessage = message => { - if (isGemini) { + if (this.modelInfo.provider === 'gemini') { const text = message.serverContent?.inputTranscription?.text || ''; if (text && text.trim()) { const finalUtteranceText = text.trim().replace(//g, '').trim(); @@ -207,7 +217,7 @@ class SttService { }; const handleTheirMessage = message => { - if (isGemini) { + if (this.modelInfo.provider === 'gemini') { const text = message.serverContent?.inputTranscription?.text || ''; if (text && text.trim()) { const finalUtteranceText = text.trim().replace(//g, '').trim(); @@ -265,20 +275,20 @@ class SttService { }; // Determine auth options for providers that support it - const authService = require('../../../common/services/authService'); - const userState = authService.getCurrentUser(); - const loggedIn = userState.isLoggedIn; + // const authService = require('../../../common/services/authService'); + // const userState = authService.getCurrentUser(); + // const loggedIn = userState.isLoggedIn; const sttOptions = { - apiKey: API_KEY, + apiKey: this.modelInfo.apiKey, language: effectiveLanguage, - usePortkey: !isGemini && loggedIn, // Only OpenAI supports Portkey - portkeyVirtualKey: loggedIn ? API_KEY : undefined + usePortkey: this.modelInfo.provider === 'openai-glass', + portkeyVirtualKey: this.modelInfo.provider === 'openai-glass' ? this.modelInfo.apiKey : undefined, }; [this.mySttSession, this.theirSttSession] = await Promise.all([ - createSTT(provider, { ...sttOptions, callbacks: mySttConfig.callbacks }), - createSTT(provider, { ...sttOptions, callbacks: theirSttConfig.callbacks }), + createSTT(this.modelInfo.provider, { ...sttOptions, callbacks: mySttConfig.callbacks }), + createSTT(this.modelInfo.provider, { ...sttOptions, callbacks: theirSttConfig.callbacks }), ]); console.log('✅ Both STT sessions initialized successfully.'); @@ -286,14 +296,23 @@ class SttService { } async sendAudioContent(data, mimeType) { - const provider = await this.getAiProvider(); - const isGemini = provider === 'gemini'; + // const provider = await this.getAiProvider(); + // const isGemini = provider === 'gemini'; if (!this.mySttSession) { throw new Error('User STT session not active'); } - const payload = isGemini + let modelInfo = this.modelInfo; + if (!modelInfo) { + console.warn('[SttService] modelInfo not found, fetching on-the-fly as a fallback...'); + modelInfo = await getCurrentModelInfo(null, { type: 'stt' }); + } + if (!modelInfo) { + throw new Error('STT model info could not be retrieved.'); + } + + const payload = modelInfo.provider === 'gemini' ? { audio: { data, mimeType: mimeType || 'audio/pcm;rate=24000' } } : data; @@ -362,8 +381,17 @@ class SttService { let audioBuffer = Buffer.alloc(0); - const provider = await this.getAiProvider(); - const isGemini = provider === 'gemini'; + // const provider = await this.getAiProvider(); + // const isGemini = provider === 'gemini'; + + let modelInfo = this.modelInfo; + if (!modelInfo) { + console.warn('[SttService] modelInfo not found, fetching on-the-fly as a fallback...'); + modelInfo = await getCurrentModelInfo(null, { type: 'stt' }); + } + if (!modelInfo) { + throw new Error('STT model info could not be retrieved.'); + } this.systemAudioProc.stdout.on('data', async data => { audioBuffer = Buffer.concat([audioBuffer, data]); @@ -379,7 +407,7 @@ class SttService { if (this.theirSttSession) { try { - const payload = isGemini + const payload = modelInfo.provider === 'gemini' ? { audio: { data: base64Data, mimeType: 'audio/pcm;rate=24000' } } : base64Data; await this.theirSttSession.sendRealtimeInput(payload); @@ -472,6 +500,7 @@ class SttService { this.theirLastPartialText = ''; this.myCompletionBuffer = ''; this.theirCompletionBuffer = ''; + this.modelInfo = null; } } diff --git a/src/features/listen/summary/summaryService.js b/src/features/listen/summary/summaryService.js index 860fa35..fef6cf0 100644 --- a/src/features/listen/summary/summaryService.js +++ b/src/features/listen/summary/summaryService.js @@ -4,7 +4,7 @@ const { createLLM } = require('../../../common/ai/factory'); const authService = require('../../../common/services/authService'); const sessionRepository = require('../../../common/repositories/session'); const summaryRepository = require('./repositories'); -const { getStoredApiKey, getStoredProvider } = require('../../../electron/windowManager'); +const { getStoredApiKey, getStoredProvider, getCurrentModelInfo } = require('../../../electron/windowManager'); class SummaryService { constructor() { @@ -27,22 +27,22 @@ class SummaryService { this.currentSessionId = sessionId; } - async getApiKey() { - const storedKey = await getStoredApiKey(); - if (storedKey) { - console.log('[SummaryService] Using stored API key'); - return storedKey; - } + // async getApiKey() { + // const storedKey = await getStoredApiKey(); + // if (storedKey) { + // console.log('[SummaryService] Using stored API key'); + // return storedKey; + // } - const envKey = process.env.OPENAI_API_KEY; - if (envKey) { - console.log('[SummaryService] Using environment API key'); - return envKey; - } + // const envKey = process.env.OPENAI_API_KEY; + // if (envKey) { + // console.log('[SummaryService] Using environment API key'); + // return envKey; + // } - console.error('[SummaryService] No API key found in storage or environment'); - return null; - } + // console.error('[SummaryService] No API key found in storage or environment'); + // return null; + // } sendToRenderer(channel, data) { BrowserWindow.getAllWindows().forEach(win => { @@ -114,6 +114,12 @@ Please build upon this context while analyzing the new conversation segments. if (this.currentSessionId) { await sessionRepository.touch(this.currentSessionId); } + + const modelInfo = await getCurrentModelInfo('llm'); + if (!modelInfo || !modelInfo.apiKey) { + throw new Error('AI model or API key is not configured.'); + } + console.log(`🤖 Sending analysis request to ${modelInfo.provider} using model ${modelInfo.model}`); const messages = [ { @@ -148,23 +154,13 @@ Keep all points concise and build upon previous analysis if provided.`, console.log('🤖 Sending analysis request to AI...'); - const API_KEY = await this.getApiKey(); - if (!API_KEY) { - throw new Error('No API key available'); - } - - const provider = getStoredProvider ? await getStoredProvider() : 'openai'; - const loggedIn = authService.getCurrentUser().isLoggedIn; - - console.log(`[SummaryService] provider: ${provider}, loggedIn: ${loggedIn}`); - - const llm = createLLM(provider, { - apiKey: API_KEY, - model: provider === 'openai' ? 'gpt-4.1' : 'gemini-2.5-flash', + const llm = createLLM(modelInfo.provider, { + apiKey: modelInfo.apiKey, + model: modelInfo.model, temperature: 0.7, maxTokens: 1024, - usePortkey: provider === 'openai' && loggedIn, - portkeyVirtualKey: loggedIn ? API_KEY : undefined + usePortkey: modelInfo.provider === 'openai-glass', + portkeyVirtualKey: modelInfo.provider === 'openai-glass' ? modelInfo.apiKey : undefined, }); const completion = await llm.chat(messages); @@ -180,7 +176,7 @@ Keep all points concise and build upon previous analysis if provided.`, tldr: structuredData.summary.join('\n'), bullet_json: JSON.stringify(structuredData.topic.bullets), action_json: JSON.stringify(structuredData.actions), - model: 'gpt-4.1' + model: modelInfo.model }).catch(err => console.error('[DB] Failed to save summary:', err)); } @@ -192,7 +188,6 @@ Keep all points concise and build upon previous analysis if provided.`, conversationLength: conversationTexts.length, }); - // 히스토리 크기 제한 (최근 10개만 유지) if (this.analysisHistory.length > 10) { this.analysisHistory.shift(); } diff --git a/src/features/settings/SettingsView.js b/src/features/settings/SettingsView.js index 49a0854..d78703c 100644 --- a/src/features/settings/SettingsView.js +++ b/src/features/settings/SettingsView.js @@ -374,6 +374,43 @@ export class SettingsView extends LitElement { .hidden { display: none; } + + .api-key-section, .model-selection-section { + padding: 8px 0; + border-top: 1px solid rgba(255, 255, 255, 0.1); + display: flex; + flex-direction: column; + gap: 10px; + } + .provider-key-group, .model-select-group { + display: flex; + flex-direction: column; + gap: 4px; + } + label { + font-size: 11px; + font-weight: 500; + color: rgba(255, 255, 255, 0.8); + margin-left: 2px; + } + label > strong { + color: white; + font-weight: 600; + } + .provider-key-group input { + width: 100%; background: rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.2); + color: white; border-radius: 4px; padding: 5px 8px; font-size: 11px; box-sizing: border-box; + } + .key-buttons { display: flex; gap: 4px; } + .key-buttons .settings-button { flex: 1; padding: 4px; } + .model-list { + display: flex; flex-direction: column; gap: 2px; max-height: 120px; + overflow-y: auto; background: rgba(0,0,0,0.3); border-radius: 4px; + padding: 4px; margin-top: 4px; + } + .model-item { padding: 5px 8px; font-size: 11px; border-radius: 3px; cursor: pointer; transition: background-color 0.15s; } + .model-item:hover { background-color: rgba(255,255,255,0.1); } + .model-item.selected { background-color: rgba(0, 122, 255, 0.4); font-weight: 500; } /* ────────────────[ GLASS BYPASS ]─────────────── */ :host-context(body.has-glass) { @@ -400,71 +437,237 @@ export class SettingsView extends LitElement { } `; + //////// before_modelStateService //////// + // static properties = { + // firebaseUser: { type: Object, state: true }, + // apiKey: { type: String, state: true }, + // isLoading: { type: Boolean, state: true }, + // isContentProtectionOn: { type: Boolean, state: true }, + // settings: { type: Object, state: true }, + // presets: { type: Array, state: true }, + // selectedPreset: { type: Object, state: true }, + // showPresets: { type: Boolean, state: true }, + // saving: { type: Boolean, state: true }, + // }; + //////// before_modelStateService //////// + + //////// after_modelStateService //////// static properties = { firebaseUser: { type: Object, state: true }, - apiKey: { type: String, state: true }, isLoading: { type: Boolean, state: true }, isContentProtectionOn: { type: Boolean, state: true }, - settings: { type: Object, state: true }, + saving: { type: Boolean, state: true }, + providerConfig: { type: Object, state: true }, + apiKeys: { type: Object, state: true }, + availableLlmModels: { type: Array, state: true }, + availableSttModels: { type: Array, state: true }, + selectedLlm: { type: String, state: true }, + selectedStt: { type: String, state: true }, + isLlmListVisible: { type: Boolean }, + isSttListVisible: { type: Boolean }, presets: { type: Array, state: true }, selectedPreset: { type: Object, state: true }, showPresets: { type: Boolean, state: true }, - saving: { type: Boolean, state: true }, }; + //////// after_modelStateService //////// constructor() { super(); + //////// before_modelStateService //////// + // this.firebaseUser = null; + // this.apiKey = null; + // this.isLoading = false; + // this.isContentProtectionOn = true; + // this.settings = null; + // this.presets = []; + // this.selectedPreset = null; + // this.showPresets = false; + // this.saving = false; + // this.loadInitialData(); + //////// before_modelStateService //////// + + //////// after_modelStateService //////// this.firebaseUser = null; - this.apiKey = null; - this.isLoading = false; + this.apiKeys = { openai: '', gemini: '', anthropic: '' }; + this.providerConfig = {}; + this.isLoading = true; this.isContentProtectionOn = true; - this.settings = null; + this.saving = false; + this.availableLlmModels = []; + this.availableSttModels = []; + this.selectedLlm = null; + this.selectedStt = null; + this.isLlmListVisible = false; + this.isSttListVisible = false; this.presets = []; this.selectedPreset = null; this.showPresets = false; - this.saving = false; + this.handleUsePicklesKey = this.handleUsePicklesKey.bind(this) this.loadInitialData(); + //////// after_modelStateService //////// } + + //////// before_modelStateService //////// + // async loadInitialData() { + // if (!window.require) return; + + // try { + // this.isLoading = true; + // const { ipcRenderer } = window.require('electron'); + + // // Load all data in parallel + // const [settings, presets, apiKey, contentProtection, userState] = await Promise.all([ + // ipcRenderer.invoke('settings:getSettings'), + // ipcRenderer.invoke('settings:getPresets'), + // ipcRenderer.invoke('get-stored-api-key'), + // ipcRenderer.invoke('get-content-protection-status'), + // ipcRenderer.invoke('get-current-user') + // ]); + + // this.settings = settings; + // this.presets = presets || []; + // this.apiKey = apiKey; + // this.isContentProtectionOn = contentProtection; + + // // Set first user preset as selected + // if (this.presets.length > 0) { + // const firstUserPreset = this.presets.find(p => p.is_default === 0); + // if (firstUserPreset) { + // this.selectedPreset = firstUserPreset; + // } + // } + + // if (userState && userState.isLoggedIn) { + // this.firebaseUser = userState.user; + // } + // } catch (error) { + // console.error('Error loading initial data:', error); + // } finally { + // this.isLoading = false; + // } + // } + //////// before_modelStateService //////// + + //////// after_modelStateService //////// async loadInitialData() { if (!window.require) return; - + this.isLoading = true; + const { ipcRenderer } = window.require('electron'); try { - this.isLoading = true; - const { ipcRenderer } = window.require('electron'); - - // Load all data in parallel - const [settings, presets, apiKey, contentProtection, userState] = await Promise.all([ - ipcRenderer.invoke('settings:getSettings'), + const [userState, config, storedKeys, availableLlm, availableStt, selectedModels, presets, contentProtection] = await Promise.all([ + ipcRenderer.invoke('get-current-user'), + ipcRenderer.invoke('model:get-provider-config'), // Provider 설정 로드 + ipcRenderer.invoke('model:get-all-keys'), + ipcRenderer.invoke('model:get-available-models', { type: 'llm' }), + ipcRenderer.invoke('model:get-available-models', { type: 'stt' }), + ipcRenderer.invoke('model:get-selected-models'), ipcRenderer.invoke('settings:getPresets'), - ipcRenderer.invoke('get-stored-api-key'), - ipcRenderer.invoke('get-content-protection-status'), - ipcRenderer.invoke('get-current-user') + ipcRenderer.invoke('get-content-protection-status') ]); - this.settings = settings; + if (userState && userState.isLoggedIn) this.firebaseUser = userState; + this.providerConfig = config; + this.apiKeys = storedKeys; + this.availableLlmModels = availableLlm; + this.availableSttModels = availableStt; + this.selectedLlm = selectedModels.llm; + this.selectedStt = selectedModels.stt; this.presets = presets || []; - this.apiKey = apiKey; this.isContentProtectionOn = contentProtection; - - // Set first user preset as selected if (this.presets.length > 0) { const firstUserPreset = this.presets.find(p => p.is_default === 0); - if (firstUserPreset) { - this.selectedPreset = firstUserPreset; - } - } - - if (userState && userState.isLoggedIn) { - this.firebaseUser = userState.user; + if (firstUserPreset) this.selectedPreset = firstUserPreset; } } catch (error) { - console.error('Error loading initial data:', error); + console.error('Error loading initial settings data:', error); } finally { this.isLoading = false; } } + async handleSaveKey(provider) { + const input = this.shadowRoot.querySelector(`#key-input-${provider}`); + if (!input) return; + const key = input.value; + this.saving = true; + + const { ipcRenderer } = window.require('electron'); + const result = await ipcRenderer.invoke('model:validate-key', { provider, key }); + + if (result.success) { + this.apiKeys = { ...this.apiKeys, [provider]: key }; + await this.refreshModelData(); + } else { + alert(`Failed to save ${provider} key: ${result.error}`); + input.value = this.apiKeys[provider] || ''; + } + this.saving = false; + } + + async handleClearKey(provider) { + this.saving = true; + const { ipcRenderer } = window.require('electron'); + await ipcRenderer.invoke('model:remove-api-key', { provider }); + this.apiKeys = { ...this.apiKeys, [provider]: '' }; + await this.refreshModelData(); + this.saving = false; + } + + async refreshModelData() { + const { ipcRenderer } = window.require('electron'); + const [availableLlm, availableStt, selected] = await Promise.all([ + ipcRenderer.invoke('model:get-available-models', { type: 'llm' }), + ipcRenderer.invoke('model:get-available-models', { type: 'stt' }), + ipcRenderer.invoke('model:get-selected-models') + ]); + this.availableLlmModels = availableLlm; + this.availableSttModels = availableStt; + this.selectedLlm = selected.llm; + this.selectedStt = selected.stt; + this.requestUpdate(); + } + + async toggleModelList(type) { + const visibilityProp = type === 'llm' ? 'isLlmListVisible' : 'isSttListVisible'; + + if (!this[visibilityProp]) { + this.saving = true; + this.requestUpdate(); + + await this.refreshModelData(); + + this.saving = false; + } + + // 데이터 새로고침 후, 목록의 표시 상태를 토글합니다. + this[visibilityProp] = !this[visibilityProp]; + this.requestUpdate(); + } + + async selectModel(type, modelId) { + this.saving = true; + const { ipcRenderer } = window.require('electron'); + await ipcRenderer.invoke('model:set-selected-model', { type, modelId }); + if (type === 'llm') this.selectedLlm = modelId; + if (type === 'stt') this.selectedStt = modelId; + this.isLlmListVisible = false; + this.isSttListVisible = false; + this.saving = false; + this.requestUpdate(); + } + + handleUsePicklesKey(e) { + e.preventDefault() + if (this.wasJustDragged) return + + console.log("Requesting Firebase authentication from main process...") + if (window.require) { + window.require("electron").ipcRenderer.invoke("start-firebase-auth") + } + } + //////// after_modelStateService //////// + connectedCallback() { super.connectedCallback(); @@ -697,6 +900,140 @@ export class SettingsView extends LitElement { } } + + //////// before_modelStateService //////// + // render() { + // if (this.isLoading) { + // return html` + //
+ //
+ //
+ // Loading... + //
+ //
+ // `; + // } + + // const loggedIn = !!this.firebaseUser; + + // return html` + //
+ //
+ //
+ //

Pickle Glass

+ // + //
+ //
+ // + // + // + //
+ //
+ + //
+ // + // + //
+ + //
+ // ${this.getMainShortcuts().map(shortcut => html` + //
+ // ${shortcut.name} + //
+ // + // ${shortcut.key} + //
+ //
+ // `)} + //
+ + // + //
+ //
+ // + // My Presets + // (${this.presets.filter(p => p.is_default === 0).length}) + // + // + // ${this.showPresets ? '▼' : '▶'} + // + //
+ + //
+ // ${this.presets.filter(p => p.is_default === 0).length === 0 ? html` + //
+ // No custom presets yet.
+ // + // Create your first preset + // + //
+ // ` : this.presets.filter(p => p.is_default === 0).map(preset => html` + //
this.handlePresetSelect(preset)}> + // ${preset.title} + // ${this.selectedPreset?.id === preset.id ? html`Selected` : ''} + //
+ // `)} + //
+ //
+ + //
+ // + + //
+ // + // + //
+ + // + + //
+ // ${this.firebaseUser + // ? html` + // + // ` + // : html` + // + // ` + // } + // + //
+ //
+ //
+ // `; + // } + //////// before_modelStateService //////// + + //////// after_modelStateService //////// render() { if (this.isLoading) { return html` @@ -711,6 +1048,68 @@ export class SettingsView extends LitElement { const loggedIn = !!this.firebaseUser; + const apiKeyManagementHTML = html` +
+ ${Object.entries(this.providerConfig) + .filter(([id, config]) => !id.includes('-glass')) + .map(([id, config]) => html` +
+ + +
+ + +
+
+ `)} +
+ `; + + const getModelName = (type, id) => { + const models = type === 'llm' ? this.availableLlmModels : this.availableSttModels; + const model = models.find(m => m.id === id); + return model ? model.name : id; + } + + const modelSelectionHTML = html` +
+
+ + + ${this.isLlmListVisible ? html` +
+ ${this.availableLlmModels.map(model => html` +
this.selectModel('llm', model.id)}> + ${model.name} +
+ `)} +
+ ` : ''} +
+
+ + + ${this.isSttListVisible ? html` +
+ ${this.availableSttModels.map(model => html` +
this.selectModel('stt', model.id)}> + ${model.name} +
+ `)} +
+ ` : ''} +
+
+ `; + return html`
@@ -719,9 +1118,7 @@ export class SettingsView extends LitElement {
@@ -732,19 +1129,9 @@ export class SettingsView extends LitElement {
-
- - -
- + ${apiKeyManagementHTML} + ${modelSelectionHTML} +
${this.getMainShortcuts().map(shortcut => html`
@@ -757,7 +1144,6 @@ export class SettingsView extends LitElement { `)}
-
@@ -813,8 +1199,8 @@ export class SettingsView extends LitElement { ` : html` - ` } @@ -826,6 +1212,7 @@ export class SettingsView extends LitElement {
`; } + //////// after_modelStateService //////// } customElements.define('settings-view', SettingsView); \ No newline at end of file diff --git a/src/index.js b/src/index.js index e0fcde4..e7f9a07 100644 --- a/src/index.js +++ b/src/index.js @@ -25,6 +25,7 @@ const { EventEmitter } = require('events'); const askService = require('./features/ask/askService'); const settingsService = require('./features/settings/settingsService'); const sessionRepository = require('./common/repositories/session'); +const ModelStateService = require('./common/services/modelStateService'); const eventBridge = new EventEmitter(); let WEB_PORT = 3000; @@ -33,6 +34,11 @@ const listenService = new ListenService(); // Make listenService globally accessible so other modules (e.g., windowManager, askService) can reuse the same instance global.listenService = listenService; +//////// after_modelStateService //////// +const modelStateService = new ModelStateService(authService); +global.modelStateService = modelStateService; +//////// after_modelStateService //////// + // Native deep link handling - cross-platform compatible let pendingDeepLinkUrl = null; @@ -173,6 +179,9 @@ app.whenReady().then(async () => { sessionRepository.endAllActiveSessions(); authService.initialize(); + //////// after_modelStateService //////// + modelStateService.initialize(); + //////// after_modelStateService //////// listenService.setupIpcHandlers(); askService.initialize(); settingsService.initialize(); From 8abb6b49aa8e7da29ec614b12ba8062ee88eacdc Mon Sep 17 00:00:00 2001 From: sanio Date: Tue, 8 Jul 2025 06:16:15 +0900 Subject: [PATCH 34/52] fix index.js conflict --- src/index.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/index.js b/src/index.js index f6071b4..9194356 100644 --- a/src/index.js +++ b/src/index.js @@ -189,18 +189,14 @@ app.whenReady().then(async () => { // Clean up zombie sessions from previous runs first sessionRepository.endAllActiveSessions(); - authService.initialize(); - //////// after_modelStateService //////// - modelStateService.initialize(); - //////// after_modelStateService //////// - listenService.setupIpcHandlers(); - askService.initialize(); - settingsService.initialize(); - setupGeneralIpcHandlers(); - }) - .catch(err => { - console.error('>>> [index.js] Database initialization failed - some features may not work', err); - }); + authService.initialize(); + //////// after_modelStateService //////// + modelStateService.initialize(); + //////// after_modelStateService //////// + listenService.setupIpcHandlers(); + askService.initialize(); + settingsService.initialize(); + setupGeneralIpcHandlers(); // Start web server and create windows ONLY after all initializations are successful WEB_PORT = await startWebStack(); From b3d9892b07f675a03ca756b8dbb97fd44e227a4c Mon Sep 17 00:00:00 2001 From: sanio Date: Tue, 8 Jul 2025 06:17:54 +0900 Subject: [PATCH 35/52] apply CI --- pickleglass_web/package-lock.json | 6976 ----------------------------- 1 file changed, 6976 deletions(-) delete mode 100644 pickleglass_web/package-lock.json diff --git a/pickleglass_web/package-lock.json b/pickleglass_web/package-lock.json deleted file mode 100644 index c7d23a8..0000000 --- a/pickleglass_web/package-lock.json +++ /dev/null @@ -1,6976 +0,0 @@ -{ - "name": "pickleglass-frontend", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "pickleglass-frontend", - "version": "0.1.0", - "dependencies": { - "@headlessui/react": "^1.7.17", - "autoprefixer": "^10.4.16", - "axios": "^1.6.0", - "firebase": "^11.10.0", - "lucide-react": "^0.294.0", - "next": "^14.2.30", - "postcss": "^8.4.32", - "react": "^18", - "react-dom": "^18", - "react-hot-toast": "^2.5.2", - "tailwindcss": "^3.3.0" - }, - "devDependencies": { - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "eslint": "^8", - "eslint-config-next": "14.0.4", - "typescript": "^5" - } - }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@emnapi/core": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz", - "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", - "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz", - "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "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/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@firebase/ai": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-1.4.1.tgz", - "integrity": "sha512-bcusQfA/tHjUjBTnMx6jdoPMpDl3r8K15Z+snHz9wq0Foox0F/V+kNLXucEOHoTL2hTc9l+onZCyBJs2QoIC3g==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.3", - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x", - "@firebase/app-types": "0.x" - } - }, - "node_modules/@firebase/analytics": { - "version": "0.10.17", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.17.tgz", - "integrity": "sha512-n5vfBbvzduMou/2cqsnKrIes4auaBjdhg8QNA2ZQZ59QgtO2QiwBaXQZQE4O4sgB0Ds1tvLgUUkY+pwzu6/xEg==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/installations": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/analytics-compat": { - "version": "0.2.23", - "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.23.tgz", - "integrity": "sha512-3AdO10RN18G5AzREPoFgYhW6vWXr3u+OYQv6pl3CX6Fky8QRk0AHurZlY3Q1xkXO0TDxIsdhO3y65HF7PBOJDw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/analytics": "0.10.17", - "@firebase/analytics-types": "0.8.3", - "@firebase/component": "0.6.18", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/analytics-types": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", - "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/app": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.2.tgz", - "integrity": "sha512-jwtMmJa1BXXDCiDx1vC6SFN/+HfYG53UkfJa6qeN5ogvOunzbFDO3wISZy5n9xgYFUrEP6M7e8EG++riHNTv9w==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/app-check": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.10.1.tgz", - "integrity": "sha512-MgNdlms9Qb0oSny87pwpjKush9qUwCJhfmTJHDfrcKo4neLGiSeVE4qJkzP7EQTIUFKp84pbTxobSAXkiuQVYQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/app-check-compat": { - "version": "0.3.26", - "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.26.tgz", - "integrity": "sha512-PkX+XJMLDea6nmnopzFKlr+s2LMQGqdyT2DHdbx1v1dPSqOol2YzgpgymmhC67vitXVpNvS3m/AiWQWWhhRRPQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check": "0.10.1", - "@firebase/app-check-types": "0.5.3", - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/app-check-interop-types": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", - "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/app-check-types": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", - "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/app-compat": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.4.2.tgz", - "integrity": "sha512-LssbyKHlwLeiV8GBATyOyjmHcMpX/tFjzRUCS1jnwGAew1VsBB4fJowyS5Ud5LdFbYpJeS+IQoC+RQxpK7eH3Q==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app": "0.13.2", - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/app-types": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/auth-compat": { - "version": "0.5.28", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.28.tgz", - "integrity": "sha512-HpMSo/cc6Y8IX7bkRIaPPqT//Jt83iWy5rmDWeThXQCAImstkdNo3giFLORJwrZw2ptiGkOij64EH1ztNJzc7Q==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/auth": "1.10.8", - "@firebase/auth-types": "0.13.0", - "@firebase/component": "0.6.18", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/auth-compat/node_modules/@firebase/auth": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", - "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x", - "@react-native-async-storage/async-storage": "^1.18.1" - }, - "peerDependenciesMeta": { - "@react-native-async-storage/async-storage": { - "optional": true - } - } - }, - "node_modules/@firebase/auth-interop-types": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", - "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/auth-types": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", - "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/component": { - "version": "0.6.18", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.18.tgz", - "integrity": "sha512-n28kPCkE2dL2U28fSxZJjzPPVpKsQminJ6NrzcKXAI0E/lYC8YhfwpyllScqVEvAI3J2QgJZWYgrX+1qGI+SQQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/data-connect": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.10.tgz", - "integrity": "sha512-VMVk7zxIkgwlVQIWHOKFahmleIjiVFwFOjmakXPd/LDgaB/5vzwsB5DWIYo+3KhGxWpidQlR8geCIn39YflJIQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/database": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.20.tgz", - "integrity": "sha512-H9Rpj1pQ1yc9+4HQOotFGLxqAXwOzCHsRSRjcQFNOr8lhUt6LeYjf0NSRL04sc4X0dWe8DsCvYKxMYvFG/iOJw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.3", - "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/database-compat": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.11.tgz", - "integrity": "sha512-itEsHARSsYS95+udF/TtIzNeQ0Uhx4uIna0sk4E0wQJBUnLc/G1X6D7oRljoOuwwCezRLGvWBRyNrugv/esOEw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/database": "1.0.20", - "@firebase/database-types": "1.0.15", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/database-types": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.15.tgz", - "integrity": "sha512-XWHJ0VUJ0k2E9HDMlKxlgy/ZuTa9EvHCGLjaKSUvrQnwhgZuRU5N3yX6SZ+ftf2hTzZmfRkv+b3QRvGg40bKNw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-types": "0.9.3", - "@firebase/util": "1.12.1" - } - }, - "node_modules/@firebase/firestore": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.8.0.tgz", - "integrity": "sha512-QSRk+Q1/CaabKyqn3C32KSFiOdZpSqI9rpLK5BHPcooElumOBooPFa6YkDdiT+/KhJtel36LdAacha9BptMj2A==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "@firebase/webchannel-wrapper": "1.0.3", - "@grpc/grpc-js": "~1.9.0", - "@grpc/proto-loader": "^0.7.8", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/firestore-compat": { - "version": "0.3.53", - "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.53.tgz", - "integrity": "sha512-qI3yZL8ljwAYWrTousWYbemay2YZa+udLWugjdjju2KODWtLG94DfO4NALJgPLv8CVGcDHNFXoyQexdRA0Cz8Q==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/firestore": "4.8.0", - "@firebase/firestore-types": "3.0.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/firestore-types": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", - "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/functions": { - "version": "0.12.9", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.9.tgz", - "integrity": "sha512-FG95w6vjbUXN84Ehezc2SDjGmGq225UYbHrb/ptkRT7OTuCiQRErOQuyt1jI1tvcDekdNog+anIObihNFz79Lg==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.3", - "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.18", - "@firebase/messaging-interop-types": "0.2.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/functions-compat": { - "version": "0.3.26", - "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.26.tgz", - "integrity": "sha512-A798/6ff5LcG2LTWqaGazbFYnjBW8zc65YfID/en83ALmkhu2b0G8ykvQnLtakbV9ajrMYPn7Yc/XcYsZIUsjA==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/functions": "0.12.9", - "@firebase/functions-types": "0.6.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/functions-types": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", - "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/installations": { - "version": "0.6.18", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.18.tgz", - "integrity": "sha512-NQ86uGAcvO8nBRwVltRL9QQ4Reidc/3whdAasgeWCPIcrhOKDuNpAALa6eCVryLnK14ua2DqekCOX5uC9XbU/A==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/util": "1.12.1", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/installations-compat": { - "version": "0.2.18", - "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.18.tgz", - "integrity": "sha512-aLFohRpJO5kKBL/XYL4tN+GdwEB/Q6Vo9eZOM/6Kic7asSUgmSfGPpGUZO1OAaSRGwF4Lqnvi1f/f9VZnKzChw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/installations": "0.6.18", - "@firebase/installations-types": "0.5.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/installations-types": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", - "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x" - } - }, - "node_modules/@firebase/logger": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", - "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/messaging": { - "version": "0.12.22", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.22.tgz", - "integrity": "sha512-GJcrPLc+Hu7nk+XQ70Okt3M1u1eRr2ZvpMbzbc54oTPJZySHcX9ccZGVFcsZbSZ6o1uqumm8Oc7OFkD3Rn1/og==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/installations": "0.6.18", - "@firebase/messaging-interop-types": "0.2.3", - "@firebase/util": "1.12.1", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/messaging-compat": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.22.tgz", - "integrity": "sha512-5ZHtRnj6YO6f/QPa/KU6gryjmX4Kg33Kn4gRpNU6M1K47Gm8kcQwPkX7erRUYEH1mIWptfvjvXMHWoZaWjkU7A==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/messaging": "0.12.22", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/messaging-interop-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", - "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/performance": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.7.tgz", - "integrity": "sha512-JTlTQNZKAd4+Q5sodpw6CN+6NmwbY72av3Lb6wUKTsL7rb3cuBIhQSrslWbVz0SwK3x0ZNcqX24qtRbwKiv+6w==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/installations": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0", - "web-vitals": "^4.2.4" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/performance-compat": { - "version": "0.2.20", - "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.20.tgz", - "integrity": "sha512-XkFK5NmOKCBuqOKWeRgBUFZZGz9SzdTZp4OqeUg+5nyjapTiZ4XoiiUL8z7mB2q+63rPmBl7msv682J3rcDXIQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/performance": "0.7.7", - "@firebase/performance-types": "0.2.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/performance-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", - "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/remote-config": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.5.tgz", - "integrity": "sha512-fU0c8HY0vrVHwC+zQ/fpXSqHyDMuuuglV94VF6Yonhz8Fg2J+KOowPGANM0SZkLvVOYpTeWp3ZmM+F6NjwWLnw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/installations": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/remote-config-compat": { - "version": "0.2.18", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.18.tgz", - "integrity": "sha512-YiETpldhDy7zUrnS8e+3l7cNs0sL7+tVAxvVYU0lu7O+qLHbmdtAxmgY+wJqWdW2c9nDvBFec7QiF58pEUu0qQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/remote-config": "0.6.5", - "@firebase/remote-config-types": "0.4.0", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/remote-config-types": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", - "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/storage": { - "version": "0.13.14", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.14.tgz", - "integrity": "sha512-xTq5ixxORzx+bfqCpsh+o3fxOsGoDjC1nO0Mq2+KsOcny3l7beyBhP/y1u5T6mgsFQwI1j6oAkbT5cWdDBx87g==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/storage-compat": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.24.tgz", - "integrity": "sha512-XHn2tLniiP7BFKJaPZ0P8YQXKiVJX+bMyE2j2YWjYfaddqiJnROJYqSomwW6L3Y+gZAga35ONXUJQju6MB6SOQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/storage": "0.13.14", - "@firebase/storage-types": "0.8.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/storage-types": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", - "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/util": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.1.tgz", - "integrity": "sha512-zGlBn/9Dnya5ta9bX/fgEoNC3Cp8s6h+uYPYaDieZsFOAdHP/ExzQ/eaDgxD3GOROdPkLKpvKY0iIzr9adle0w==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/webchannel-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", - "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==", - "license": "Apache-2.0" - }, - "node_modules/@grpc/grpc-js": { - "version": "1.9.15", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", - "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", - "license": "Apache-2.0", - "dependencies": { - "@grpc/proto-loader": "^0.7.8", - "@types/node": ">=12.12.47" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", - "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", - "license": "Apache-2.0", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@headlessui/react": { - "version": "1.7.19", - "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz", - "integrity": "sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==", - "license": "MIT", - "dependencies": { - "@tanstack/react-virtual": "^3.0.0-beta.60", - "client-only": "^0.0.1" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": "^16 || ^17 || ^18", - "react-dom": "^16 || ^17 || ^18" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.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/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz", - "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.9.0" - } - }, - "node_modules/@next/env": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.30.tgz", - "integrity": "sha512-KBiBKrDY6kxTQWGzKjQB7QirL3PiiOkV7KW98leHFjtVRKtft76Ra5qSA/SL75xT44dp6hOcqiiJ6iievLOYug==", - "license": "MIT" - }, - "node_modules/@next/eslint-plugin-next": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.0.4.tgz", - "integrity": "sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "7.1.7" - } - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.30.tgz", - "integrity": "sha512-EAqfOTb3bTGh9+ewpO/jC59uACadRHM6TSA9DdxJB/6gxOpyV+zrbqeXiFTDy9uV6bmipFDkfpAskeaDcO+7/g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.30.tgz", - "integrity": "sha512-TyO7Wz1IKE2kGv8dwQ0bmPL3s44EKVencOqwIY69myoS3rdpO1NPg5xPM5ymKu7nfX4oYJrpMxv8G9iqLsnL4A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.30.tgz", - "integrity": "sha512-I5lg1fgPJ7I5dk6mr3qCH1hJYKJu1FsfKSiTKoYwcuUf53HWTrEkwmMI0t5ojFKeA6Vu+SfT2zVy5NS0QLXV4Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.30.tgz", - "integrity": "sha512-8GkNA+sLclQyxgzCDs2/2GSwBc92QLMrmYAmoP2xehe5MUKBLB2cgo34Yu242L1siSkwQkiV4YLdCnjwc/Micw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.30.tgz", - "integrity": "sha512-8Ly7okjssLuBoe8qaRCcjGtcMsv79hwzn/63wNeIkzJVFVX06h5S737XNr7DZwlsbTBDOyI6qbL2BJB5n6TV/w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.30.tgz", - "integrity": "sha512-dBmV1lLNeX4mR7uI7KNVHsGQU+OgTG5RGFPi3tBJpsKPvOPtg9poyav/BYWrB3GPQL4dW5YGGgalwZ79WukbKQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.30.tgz", - "integrity": "sha512-6MMHi2Qc1Gkq+4YLXAgbYslE1f9zMGBikKMdmQRHXjkGPot1JY3n5/Qrbg40Uvbi8//wYnydPnyvNhI1DMUW1g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.30.tgz", - "integrity": "sha512-pVZMnFok5qEX4RT59mK2hEVtJX+XFfak+/rjHpyFh7juiT52r177bfFKhnlafm0UOSldhXjj32b+LZIOdswGTg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.30.tgz", - "integrity": "sha512-4KCo8hMZXMjpTzs3HOqOGYYwAXymXIy7PEPAXNEcEOyKqkjiDlECumrWziy+JEF0Oi4ILHGxzgQ3YiMGG2t/Lg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "license": "BSD-3-Clause" - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.12.0.tgz", - "integrity": "sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "license": "Apache-2.0" - }, - "node_modules/@swc/helpers": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", - "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3", - "tslib": "^2.4.0" - } - }, - "node_modules/@tanstack/react-virtual": { - "version": "3.13.12", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.12.tgz", - "integrity": "sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA==", - "license": "MIT", - "dependencies": { - "@tanstack/virtual-core": "3.13.12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/@tanstack/virtual-core": { - "version": "3.13.12", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.12.tgz", - "integrity": "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", - "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "20.19.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.4.tgz", - "integrity": "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/prop-types": { - "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "18.3.23", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz", - "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.3.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", - "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^18.0.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.0.tgz", - "integrity": "sha512-LRw5BW29sYj9NsQC6QoqeLVQhEa+BwVINYyMlcve+6stwdBsSt5UB7zw4UZB4+4PNqIVilHoMaPWCb/KhABHQw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.0.tgz", - "integrity": "sha512-zYX8D2zcWCAHqghA8tPjbp7LwjVXbIZP++mpU/Mrf5jUVlk3BWIxkeB8yYzZi5GpFSlqMcRZQxQqbMI0c2lASQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.0.tgz", - "integrity": "sha512-YsYOT049hevAY/lTYD77GhRs885EXPeAfExG5KenqMJ417nYLS2N/kpRpYbABhFZBVQn+2uRPasTe4ypmYoo3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.0.tgz", - "integrity": "sha512-PSjvk3OZf1aZImdGY5xj9ClFG3bC4gnSSYWrt+id0UAv+GwwVldhpMFjAga8SpMo2T1GjV9UKwM+QCsQCQmtdA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.0.tgz", - "integrity": "sha512-KC/iFaEN/wsTVYnHClyHh5RSYA9PpuGfqkFua45r4sweXpC0KHZ+BYY7ikfcGPt5w1lMpR1gneFzuqWLQxsRKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.0.tgz", - "integrity": "sha512-CDh/0v8uot43cB4yKtDL9CVY8pbPnMV0dHyQCE4lFz6PW/+9tS0i9eqP5a91PAqEBVMqH1ycu+k8rP6wQU846w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.0.tgz", - "integrity": "sha512-+TE7epATDSnvwr3L/hNHX3wQ8KQYB+jSDTdywycg3qDqvavRP8/HX9qdq/rMcnaRDn4EOtallb3vL/5wCWGCkw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.0.tgz", - "integrity": "sha512-VBAYGg3VahofpQ+L4k/ZO8TSICIbUKKTaMYOWHWfuYBFqPbSkArZZLezw3xd27fQkxX4BaLGb/RKnW0dH9Y/UA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.0.tgz", - "integrity": "sha512-9IgGFUUb02J1hqdRAHXpZHIeUHRrbnGo6vrRbz0fREH7g+rzQy53/IBSyadZ/LG5iqMxukriNPu4hEMUn+uWEg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.0.tgz", - "integrity": "sha512-LR4iQ/LPjMfivpL2bQ9kmm3UnTas3U+umcCnq/CV7HAkukVdHxrDD1wwx74MIWbbgzQTLPYY7Ur2MnnvkYJCBQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.0.tgz", - "integrity": "sha512-HCupFQwMrRhrOg7YHrobbB5ADg0Q8RNiuefqMHVsdhEy9lLyXm/CxsCXeLJdrg27NAPsCaMDtdlm8Z2X8x91Tg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.0.tgz", - "integrity": "sha512-Ckxy76A5xgjWa4FNrzcKul5qFMWgP5JSQ5YKd0XakmWOddPLSkQT+uAvUpQNnFGNbgKzv90DyQlxPDYPQ4nd6A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.0.tgz", - "integrity": "sha512-HfO0PUCCRte2pMJmVyxPI+eqT7KuV3Fnvn2RPvMe5mOzb2BJKf4/Vth8sSt9cerQboMaTVpbxyYjjLBWIuI5BQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.0.tgz", - "integrity": "sha512-9PZdjP7tLOEjpXHS6+B/RNqtfVUyDEmaViPOuSqcbomLdkJnalt5RKQ1tr2m16+qAufV0aDkfhXtoO7DQos/jg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.0.tgz", - "integrity": "sha512-qkE99ieiSKMnFJY/EfyGKVtNra52/k+lVF/PbO4EL5nU6AdvG4XhtJ+WHojAJP7ID9BNIra/yd75EHndewNRfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.0.tgz", - "integrity": "sha512-MjXek8UL9tIX34gymvQLecz2hMaQzOlaqYJJBomwm1gsvK2F7hF+YqJJ2tRyBDTv9EZJGMt4KlKkSD/gZWCOiw==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.0.tgz", - "integrity": "sha512-9LT6zIGO7CHybiQSh7DnQGwFMZvVr0kUjah6qQfkH2ghucxPV6e71sUXJdSM4Ba0MaGE6DC/NwWf7mJmc3DAng==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.0.tgz", - "integrity": "sha512-HYchBYOZ7WN266VjoGm20xFv5EonG/ODURRgwl9EZT7Bq1nLEs6VKJddzfFdXEAho0wfFlt8L/xIiE29Pmy1RA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.0.tgz", - "integrity": "sha512-+oLKLHw3I1UQo4MeHfoLYF+e6YBa8p5vYUw3Rgt7IDzCs+57vIZqQlIo62NDpYM0VG6BjWOwnzBczMvbtH8hag==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "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/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "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/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "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-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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.findlastindex": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", - "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-shim-unscopables": "^1.1.0" - }, - "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/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true, - "license": "MIT" - }, - "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/autoprefixer": { - "version": "10.4.21", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", - "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.24.4", - "caniuse-lite": "^1.0.30001702", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/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/axe-core": { - "version": "4.10.3", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", - "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", - "dev": true, - "license": "MPL-2.0", - "engines": { - "node": ">=4" - } - }, - "node_modules/axios": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", - "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "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/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/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/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "license": "MIT" - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/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/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/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/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true, - "license": "BSD-2-Clause" - }, - "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/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "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/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "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/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "license": "Apache-2.0" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "license": "MIT" - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "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/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.179", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.179.tgz", - "integrity": "sha512-UWKi/EbBopgfFsc5k61wFpV7WrnnSlSzW/e2XcBmS6qKYTivZlLtoll5/rdqRTxGglGHkmkW0j0pFNJG10EUIQ==", - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", - "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.2.1", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", - "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", - "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-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.6", - "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.4", - "safe-array-concat": "^1.1.3" - }, - "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/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-next": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.0.4.tgz", - "integrity": "sha512-9/xbOHEQOmQtqvQ1UsTQZpnA7SlDMBtuKJ//S4JnoyK3oGLhILKXdBgu/UO7lQo/2xOykQULS1qQ6p2+EpHgAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@next/eslint-plugin-next": "14.0.4", - "@rushstack/eslint-patch": "^1.3.3", - "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-import-resolver-typescript": "^3.5.2", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" - }, - "peerDependencies": { - "eslint": "^7.23.0 || ^8.0.0", - "typescript": ">=3.3.1" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", - "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.4.0", - "get-tsconfig": "^4.10.0", - "is-bun-module": "^2.0.0", - "stable-hash": "^0.0.5", - "tinyglobby": "^0.2.13", - "unrs-resolver": "^1.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-resolver-typescript" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", - "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.32.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", - "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.9", - "array.prototype.findlastindex": "^1.2.6", - "array.prototype.flat": "^1.3.3", - "array.prototype.flatmap": "^1.3.3", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.1", - "hasown": "^2.0.2", - "is-core-module": "^2.16.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.1", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.9", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/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/eslint-plugin-import/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/eslint-plugin-jsx-a11y": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", - "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "aria-query": "^5.3.2", - "array-includes": "^3.1.8", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "^4.10.0", - "axobject-query": "^4.1.0", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "hasown": "^2.0.2", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.1" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" - } - }, - "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": "5.0.0-canary-7118f5dd7-20230705", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz", - "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/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/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-plugin-react/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/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "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/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "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/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/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/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/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/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/firebase": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.10.0.tgz", - "integrity": "sha512-nKBXoDzF0DrXTBQJlZa+sbC5By99ysYU1D6PkMRYknm0nCW7rJly47q492Ht7Ndz5MeYSBuboKuhS1e6mFC03w==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/ai": "1.4.1", - "@firebase/analytics": "0.10.17", - "@firebase/analytics-compat": "0.2.23", - "@firebase/app": "0.13.2", - "@firebase/app-check": "0.10.1", - "@firebase/app-check-compat": "0.3.26", - "@firebase/app-compat": "0.4.2", - "@firebase/app-types": "0.9.3", - "@firebase/auth": "1.10.8", - "@firebase/auth-compat": "0.5.28", - "@firebase/data-connect": "0.3.10", - "@firebase/database": "1.0.20", - "@firebase/database-compat": "2.0.11", - "@firebase/firestore": "4.8.0", - "@firebase/firestore-compat": "0.3.53", - "@firebase/functions": "0.12.9", - "@firebase/functions-compat": "0.3.26", - "@firebase/installations": "0.6.18", - "@firebase/installations-compat": "0.2.18", - "@firebase/messaging": "0.12.22", - "@firebase/messaging-compat": "0.2.22", - "@firebase/performance": "0.7.7", - "@firebase/performance-compat": "0.2.20", - "@firebase/remote-config": "0.6.5", - "@firebase/remote-config-compat": "0.2.18", - "@firebase/storage": "0.13.14", - "@firebase/storage-compat": "0.3.24", - "@firebase/util": "1.12.1" - } - }, - "node_modules/firebase/node_modules/@firebase/auth": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", - "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x", - "@react-native-async-storage/async-storage": "^1.18.1" - }, - "peerDependenciesMeta": { - "@react-native-async-storage/async-storage": { - "optional": true - } - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "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/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "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": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/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==", - "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/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-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-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/get-tsconfig": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", - "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "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==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "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==", - "dev": 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/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/goober": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", - "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", - "license": "MIT", - "peerDependencies": { - "csstype": "^3.0.10" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "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==", - "dev": 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.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", - "license": "MIT" - }, - "node_modules/idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", - "license": "ISC" - }, - "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/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-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-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-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-bun-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", - "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.7.1" - } - }, - "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.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-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-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-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": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-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-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/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-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/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "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/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "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-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/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/language-subtag-registry": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "dev": true, - "license": "MIT", - "dependencies": { - "language-subtag-registry": "^0.3.20" - }, - "engines": { - "node": ">=0.10" - } - }, - "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/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/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.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "license": "MIT" - }, - "node_modules/lodash.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/long": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0" - }, - "node_modules/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==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, - "node_modules/lucide-react": { - "version": "0.294.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.294.0.tgz", - "integrity": "sha512-V7o0/VECSGbLHn3/1O67FUgBwWB+hmzshrgDVRJQhMh8uj5D3HBuIvhuAmQTtlupILSplwIZg5FTc4tTKMA2SA==", - "license": "ISC", - "peerDependencies": { - "react": "^16.5.1 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/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/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "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.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/napi-postinstall": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.0.tgz", - "integrity": "sha512-M7NqKyhODKV1gRLdkwE7pDsZP2/SC2a2vHkOYh9MCpKMbWVfyVfUw5MaH83Fv6XMjxr5jryUp3IDDL9rlxsTeA==", - "dev": true, - "license": "MIT", - "bin": { - "napi-postinstall": "lib/cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" - } - }, - "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/next": { - "version": "14.2.30", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.30.tgz", - "integrity": "sha512-+COdu6HQrHHFQ1S/8BBsCag61jZacmvbuL2avHvQFbWa2Ox7bE+d8FyNgxRLjXQ5wtPyQwEmk85js/AuaG2Sbg==", - "license": "MIT", - "dependencies": { - "@next/env": "14.2.30", - "@swc/helpers": "0.5.5", - "busboy": "1.6.0", - "caniuse-lite": "^1.0.30001579", - "graceful-fs": "^4.2.11", - "postcss": "8.4.31", - "styled-jsx": "5.1.1" - }, - "bin": { - "next": "dist/bin/next" - }, - "engines": { - "node": ">=18.17.0" - }, - "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.30", - "@next/swc-darwin-x64": "14.2.30", - "@next/swc-linux-arm64-gnu": "14.2.30", - "@next/swc-linux-arm64-musl": "14.2.30", - "@next/swc-linux-x64-gnu": "14.2.30", - "@next/swc-linux-x64-musl": "14.2.30", - "@next/swc-win32-arm64-msvc": "14.2.30", - "@next/swc-win32-ia32-msvc": "14.2.30", - "@next/swc-win32-x64-msvc": "14.2.30" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0", - "@playwright/test": "^1.41.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "sass": "^1.3.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "@playwright/test": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, - "node_modules/next/node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "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.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "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==", - "dev": 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.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "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-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/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "license": "BlueOak-1.0.0" - }, - "node_modules/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/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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/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.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "license": "MIT" - }, - "node_modules/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/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/protobufjs": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", - "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/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/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-hot-toast": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.2.tgz", - "integrity": "sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==", - "license": "MIT", - "dependencies": { - "csstype": "^3.1.3", - "goober": "^2.1.16" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": ">=16", - "react-dom": ">=16" - } - }, - "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/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/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/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/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/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safe-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/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/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.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "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": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stable-hash": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", - "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", - "dev": true, - "license": "MIT" - }, - "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/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/string.prototype.includes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", - "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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/styled-jsx": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", - "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", - "license": "MIT", - "dependencies": { - "client-only": "0.0.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/sucrase/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/sucrase/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sucrase/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/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==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tailwindcss": { - "version": "3.4.17", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", - "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.6.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.6", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tailwindcss/node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-api-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", - "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "license": "Apache-2.0" - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/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": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "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.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "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-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/unrs-resolver": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.0.tgz", - "integrity": "sha512-uw3hCGO/RdAEAb4zgJ3C/v6KIAFFOtBoxR86b2Ejc5TnH7HrhTWJR2o0A9ullC3eWMegKQCw/arQ/JivywQzkg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "napi-postinstall": "^0.3.0" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.0", - "@unrs/resolver-binding-android-arm64": "1.11.0", - "@unrs/resolver-binding-darwin-arm64": "1.11.0", - "@unrs/resolver-binding-darwin-x64": "1.11.0", - "@unrs/resolver-binding-freebsd-x64": "1.11.0", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.0", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.0", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.0", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.0", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.0", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.0", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.0", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.0", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.0", - "@unrs/resolver-binding-linux-x64-musl": "1.11.0", - "@unrs/resolver-binding-wasm32-wasi": "1.11.0", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.0", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.0", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/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/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/web-vitals": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", - "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", - "license": "Apache-2.0" - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/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.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", - "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==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yaml": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", - "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/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" - } - } - } -} From bcfdac1569acafec48ac46f397fedcc2dce445cd Mon Sep 17 00:00:00 2001 From: sanio Date: Tue, 8 Jul 2025 06:18:12 +0900 Subject: [PATCH 36/52] apply CI --- package-lock.json | 12077 -------------------------------------------- 1 file changed, 12077 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index edabde8..0000000 --- a/package-lock.json +++ /dev/null @@ -1,12077 +0,0 @@ -{ - "name": "pickle-glass", - "version": "0.2.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "pickle-glass", - "version": "0.2.1", - "hasInstallScript": true, - "license": "GPL-3.0", - "dependencies": { - "@google/genai": "^1.8.0", - "@google/generative-ai": "^0.24.1", - "axios": "^1.10.0", - "better-sqlite3": "^9.4.3", - "cors": "^2.8.5", - "dotenv": "^17.0.0", - "electron-squirrel-startup": "^1.0.1", - "electron-store": "^8.2.0", - "electron-updater": "^6.6.2", - "express": "^4.18.2", - "firebase": "^11.10.0", - "firebase-admin": "^13.4.0", - "jsonwebtoken": "^9.0.2", - "node-fetch": "^2.7.0", - "openai": "^4.70.0", - "react-hot-toast": "^2.5.2", - "sharp": "^0.34.2", - "validator": "^13.11.0", - "wait-on": "^8.0.3", - "ws": "^8.18.0" - }, - "devDependencies": { - "@electron-forge/cli": "^7.8.1", - "@electron-forge/maker-deb": "^7.8.1", - "@electron-forge/maker-dmg": "^7.8.1", - "@electron-forge/maker-rpm": "^7.8.1", - "@electron-forge/maker-squirrel": "^7.8.1", - "@electron-forge/maker-zip": "^7.8.1", - "@electron-forge/plugin-auto-unpack-natives": "^7.8.1", - "@electron-forge/plugin-fuses": "^7.8.1", - "@electron/fuses": "^1.8.0", - "@electron/notarize": "^2.5.0", - "electron": "^30.5.1", - "electron-builder": "^26.0.12", - "electron-reloader": "^1.2.3", - "esbuild": "^0.25.5" - }, - "optionalDependencies": { - "electron-liquid-glass": "^1.0.1" - } - }, - "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-forge/cli": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-7.8.1.tgz", - "integrity": "sha512-QI3EShutfq9Y+2TWWrPjm4JZM3eSAKzoQvRZdVhAfVpUbyJ8K23VqJShg3kGKlPf9BXHAGvE+8LyH5s2yDr1qA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-cli?utm_medium=referral&utm_source=npm_fund" - } - ], - "license": "MIT", - "dependencies": { - "@electron-forge/core": "7.8.1", - "@electron-forge/core-utils": "7.8.1", - "@electron-forge/shared-types": "7.8.1", - "@electron/get": "^3.0.0", - "chalk": "^4.0.0", - "commander": "^11.1.0", - "debug": "^4.3.1", - "fs-extra": "^10.0.0", - "listr2": "^7.0.2", - "log-symbols": "^4.0.0", - "semver": "^7.2.1" - }, - "bin": { - "electron-forge": "dist/electron-forge.js", - "electron-forge-vscode-nix": "script/vscode.sh", - "electron-forge-vscode-win": "script/vscode.cmd" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/core": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-7.8.1.tgz", - "integrity": "sha512-jkh0QPW5p0zmruu1E8+2XNufc4UMxy13WLJcm7hn9jbaXKLkMbKuEvhrN1tH/9uGp1mhr/t8sC4N67gP+gS87w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-core?utm_medium=referral&utm_source=npm_fund" - } - ], - "license": "MIT", - "dependencies": { - "@electron-forge/core-utils": "7.8.1", - "@electron-forge/maker-base": "7.8.1", - "@electron-forge/plugin-base": "7.8.1", - "@electron-forge/publisher-base": "7.8.1", - "@electron-forge/shared-types": "7.8.1", - "@electron-forge/template-base": "7.8.1", - "@electron-forge/template-vite": "7.8.1", - "@electron-forge/template-vite-typescript": "7.8.1", - "@electron-forge/template-webpack": "7.8.1", - "@electron-forge/template-webpack-typescript": "7.8.1", - "@electron-forge/tracer": "7.8.1", - "@electron/get": "^3.0.0", - "@electron/packager": "^18.3.5", - "@electron/rebuild": "^3.7.0", - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.3.1", - "fast-glob": "^3.2.7", - "filenamify": "^4.1.0", - "find-up": "^5.0.0", - "fs-extra": "^10.0.0", - "global-dirs": "^3.0.0", - "got": "^11.8.5", - "interpret": "^3.1.1", - "jiti": "^2.4.2", - "listr2": "^7.0.2", - "lodash": "^4.17.20", - "log-symbols": "^4.0.0", - "node-fetch": "^2.6.7", - "rechoir": "^0.8.0", - "semver": "^7.2.1", - "source-map-support": "^0.5.13", - "sudo-prompt": "^9.1.1", - "username": "^5.1.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/core-utils": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/core-utils/-/core-utils-7.8.1.tgz", - "integrity": "sha512-mRoPLDNZgmjyOURE/K0D3Op53XGFmFRgfIvFC7c9S/BqsRpovVblrqI4XxPRdNmH9dvhd8On9gGz+XIYAKD3aQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.8.1", - "@electron/rebuild": "^3.7.0", - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.3.1", - "find-up": "^5.0.0", - "fs-extra": "^10.0.0", - "log-symbols": "^4.0.0", - "semver": "^7.2.1" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/maker-base": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-7.8.1.tgz", - "integrity": "sha512-GUZqschGuEBzSzE0bMeDip65IDds48DZXzldlRwQ+85SYVA6RMU2AwDDqx3YiYsvP2OuxKruuqIJZtOF5ps4FQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.8.1", - "fs-extra": "^10.0.0", - "which": "^2.0.2" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/maker-deb": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-deb/-/maker-deb-7.8.1.tgz", - "integrity": "sha512-tjjeesQtCP5Xht1X7gl4+K9bwoETPmQfBkOVAY/FZIxPj40uQh/hOUtLX2tYENNGNVZ1ryDYRs8TuPi+I41Vfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/maker-base": "7.8.1", - "@electron-forge/shared-types": "7.8.1" - }, - "engines": { - "node": ">= 16.4.0" - }, - "optionalDependencies": { - "electron-installer-debian": "^3.2.0" - } - }, - "node_modules/@electron-forge/maker-dmg": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-dmg/-/maker-dmg-7.8.1.tgz", - "integrity": "sha512-l449QvY2Teu+J9rHnjkTHEm/wOJ1LRfmrQ2QkGtFoTRcqvFWdUAEN8nK2/08w3j2h6tvOY3QSUjRzXrhJZRNRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/maker-base": "7.8.1", - "@electron-forge/shared-types": "7.8.1", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 16.4.0" - }, - "optionalDependencies": { - "electron-installer-dmg": "^5.0.1" - } - }, - "node_modules/@electron-forge/maker-rpm": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-rpm/-/maker-rpm-7.8.1.tgz", - "integrity": "sha512-TF6wylft3BHkw9zdHcxmjEPBZYgTIc0jE31skFnMEQ/aExbNRiNaCZvsXy+7ptTWZxhxUKRc9KHhLFRMCmOK8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/maker-base": "7.8.1", - "@electron-forge/shared-types": "7.8.1" - }, - "engines": { - "node": ">= 16.4.0" - }, - "optionalDependencies": { - "electron-installer-redhat": "^3.2.0" - } - }, - "node_modules/@electron-forge/maker-squirrel": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-squirrel/-/maker-squirrel-7.8.1.tgz", - "integrity": "sha512-qT1PMvT7ALF0ONOkxlA0oc0PiFuKCAKgoMPoxYo9gGOqFvnAb+TBcnLxflQ4ashE/ZkrHpykr4LcDJxqythQTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/maker-base": "7.8.1", - "@electron-forge/shared-types": "7.8.1", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 16.4.0" - }, - "optionalDependencies": { - "electron-winstaller": "^5.3.0" - } - }, - "node_modules/@electron-forge/maker-zip": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-zip/-/maker-zip-7.8.1.tgz", - "integrity": "sha512-unIxEoV1lnK4BLVqCy3L2y897fTyg8nKY1WT4rrpv0MUKnQG4qmigDfST5zZNNHHaulEn/ElAic2GEiP7d6bhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/maker-base": "7.8.1", - "@electron-forge/shared-types": "7.8.1", - "cross-zip": "^4.0.0", - "fs-extra": "^10.0.0", - "got": "^11.8.5" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/plugin-auto-unpack-natives": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/plugin-auto-unpack-natives/-/plugin-auto-unpack-natives-7.8.1.tgz", - "integrity": "sha512-4URAgWX9qqqKe6Bfad0VmpFRrwINYMODfKGd2nFQrfHxmBtdpXnsWlLwVGE/wGssIQaTMI5bWQ6F2RNeXTgnhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/plugin-base": "7.8.1", - "@electron-forge/shared-types": "7.8.1" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/plugin-base": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/plugin-base/-/plugin-base-7.8.1.tgz", - "integrity": "sha512-iCZC2d7CbsZ9l6j5d+KPIiyQx0U1QBfWAbKnnQhWCSizjcrZ7A9V4sMFZeTO6+PVm48b/r9GFPm+slpgZtYQLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.8.1" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/plugin-fuses": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/plugin-fuses/-/plugin-fuses-7.8.1.tgz", - "integrity": "sha512-dYTwvbV1HcDOIQ0wTybpdtPq6YoBYXIWBTb7DJuvFu/c/thj1eoEdnbwr8mT9hEivjlu5p4ls46n16P5EtZ0oA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/plugin-base": "7.8.1", - "@electron-forge/shared-types": "7.8.1" - }, - "engines": { - "node": ">= 16.4.0" - }, - "peerDependencies": { - "@electron/fuses": ">=1.0.0" - } - }, - "node_modules/@electron-forge/publisher-base": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/publisher-base/-/publisher-base-7.8.1.tgz", - "integrity": "sha512-z2C+C4pcFxyCXIFwXGDcxhU8qtVUPZa3sPL6tH5RuMxJi77768chLw2quDWk2/dfupcSELXcOMYCs7aLysCzeQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.8.1" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/shared-types": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/shared-types/-/shared-types-7.8.1.tgz", - "integrity": "sha512-guLyGjIISKQQRWHX+ugmcjIOjn2q/BEzCo3ioJXFowxiFwmZw/oCZ2KlPig/t6dMqgUrHTH5W/F0WKu0EY4M+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/tracer": "7.8.1", - "@electron/packager": "^18.3.5", - "@electron/rebuild": "^3.7.0", - "listr2": "^7.0.2" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-base": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/template-base/-/template-base-7.8.1.tgz", - "integrity": "sha512-k8jEUr0zWFWb16ZGho+Es2OFeKkcbTgbC6mcH4eNyF/sumh/4XZMcwRtX1i7EiZAYiL9sVxyI6KVwGu254g+0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/core-utils": "7.8.1", - "@electron-forge/shared-types": "7.8.1", - "@malept/cross-spawn-promise": "^2.0.0", - "debug": "^4.3.1", - "fs-extra": "^10.0.0", - "username": "^5.1.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-vite": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/template-vite/-/template-vite-7.8.1.tgz", - "integrity": "sha512-qzSlJaBYYqQAbBdLk4DqAE3HCNz4yXbpkb+VC74ddL4JGwPdPU57DjCthr6YetKJ2FsOVy9ipovA8HX5UbXpAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.8.1", - "@electron-forge/template-base": "7.8.1", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-vite-typescript": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/template-vite-typescript/-/template-vite-typescript-7.8.1.tgz", - "integrity": "sha512-CccQhwUjZcc6svzuOi3BtbDal591DzyX2J5GPa6mwVutDP8EMtqJL1VyOHdcWO/7XjI6GNAD0fiXySOJiUAECA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.8.1", - "@electron-forge/template-base": "7.8.1", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-webpack": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-7.8.1.tgz", - "integrity": "sha512-DA77o9kTCHrq+W211pyNP49DyAt0d1mzMp2gisyNz7a+iKvlv2DsMAeRieLoCQ44akb/z8ZsL0YLteSjKLy4AA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.8.1", - "@electron-forge/template-base": "7.8.1", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-webpack-typescript": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-7.8.1.tgz", - "integrity": "sha512-h922E+6zWwym1RT6WKD79BLTc4H8YxEMJ7wPWkBX59kw/exsTB/KFdiJq6r82ON5jSJ+Q8sDGqSmDWdyCfo+Gg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.8.1", - "@electron-forge/template-base": "7.8.1", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/tracer": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@electron-forge/tracer/-/tracer-7.8.1.tgz", - "integrity": "sha512-r2i7aHVp2fylGQSPDw3aTcdNfVX9cpL1iL2MKHrCRNwgrfR+nryGYg434T745GGm1rNQIv5Egdkh5G9xf00oWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chrome-trace-event": "^1.0.3" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "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/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/@electron/fuses": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@electron/fuses/-/fuses-1.8.0.tgz", - "integrity": "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.1", - "fs-extra": "^9.0.1", - "minimist": "^1.2.5" - }, - "bin": { - "electron-fuses": "dist/bin.js" - } - }, - "node_modules/@electron/fuses/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/get": { - "version": "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/@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/@electron/get/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/get/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@electron/get/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/@electron/node-gyp": { - "version": "10.2.0-electron.1", - "resolved": "git+ssh://git@github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", - "integrity": "sha512-CrYo6TntjpoMO1SHjl5Pa/JoUsECNqNdB7Kx49WLQpWzPw53eEITJ2Hs9fh/ryUYDn4pxZz11StaBYBrLFJdqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^8.1.0", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.2.1", - "nopt": "^6.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "tar": "^6.2.1", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/@electron/node-gyp/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@electron/node-gyp/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@electron/node-gyp/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/notarize": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz", - "integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^9.0.1", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@electron/notarize/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/osx-sign": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.3.tgz", - "integrity": "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "compare-version": "^0.1.2", - "debug": "^4.3.4", - "fs-extra": "^10.0.0", - "isbinaryfile": "^4.0.8", - "minimist": "^1.2.6", - "plist": "^3.0.5" - }, - "bin": { - "electron-osx-flat": "bin/electron-osx-flat.js", - "electron-osx-sign": "bin/electron-osx-sign.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@electron/packager": { - "version": "18.3.6", - "resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.3.6.tgz", - "integrity": "sha512-1eXHB5t+SQKvUiDpWGpvr90ZSSbXj+isrh3YbjCTjKT4bE4SQrKSBfukEAaBvp67+GXHFtCHjQgN9qSTFIge+Q==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@electron/asar": "^3.2.13", - "@electron/get": "^3.0.0", - "@electron/notarize": "^2.1.0", - "@electron/osx-sign": "^1.0.5", - "@electron/universal": "^2.0.1", - "@electron/windows-sign": "^1.0.0", - "debug": "^4.0.1", - "extract-zip": "^2.0.0", - "filenamify": "^4.1.0", - "fs-extra": "^11.1.0", - "galactus": "^1.0.0", - "get-package-info": "^1.0.0", - "junk": "^3.1.0", - "parse-author": "^2.0.0", - "plist": "^3.0.0", - "resedit": "^2.0.0", - "resolve": "^1.1.6", - "semver": "^7.1.3", - "yargs-parser": "^21.1.1" - }, - "bin": { - "electron-packager": "bin/electron-packager.js" - }, - "engines": { - "node": ">= 16.13.0" - }, - "funding": { - "url": "https://github.com/electron/packager?sponsor=1" - } - }, - "node_modules/@electron/packager/node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/@electron/rebuild": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.2.tgz", - "integrity": "sha512-19/KbIR/DAxbsCkiaGMXIdPnMCJLkcf8AvGnduJtWBs/CBwiAjY1apCqOLVxrXg+rtXFCngbXhBanWjxLUt1Mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.1.1", - "detect-libc": "^2.0.1", - "fs-extra": "^10.0.0", - "got": "^11.7.0", - "node-abi": "^3.45.0", - "node-api-version": "^0.2.0", - "ora": "^5.1.0", - "read-binary-file-arch": "^1.0.6", - "semver": "^7.3.5", - "tar": "^6.0.5", - "yargs": "^17.0.1" - }, - "bin": { - "electron-rebuild": "lib/cli.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/@electron/universal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.3.tgz", - "integrity": "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@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/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@electron/universal/node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/@electron/universal/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@electron/windows-sign": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz", - "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==", - "dev": true, - "license": "BSD-2-Clause", - "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.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", - "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", - "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", - "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", - "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", - "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", - "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", - "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", - "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", - "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", - "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", - "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", - "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", - "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", - "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", - "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", - "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", - "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", - "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", - "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", - "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", - "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", - "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", - "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", - "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", - "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", - "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@fastify/busboy": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz", - "integrity": "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==", - "license": "MIT" - }, - "node_modules/@firebase/ai": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-1.4.1.tgz", - "integrity": "sha512-bcusQfA/tHjUjBTnMx6jdoPMpDl3r8K15Z+snHz9wq0Foox0F/V+kNLXucEOHoTL2hTc9l+onZCyBJs2QoIC3g==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.3", - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x", - "@firebase/app-types": "0.x" - } - }, - "node_modules/@firebase/analytics": { - "version": "0.10.17", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.17.tgz", - "integrity": "sha512-n5vfBbvzduMou/2cqsnKrIes4auaBjdhg8QNA2ZQZ59QgtO2QiwBaXQZQE4O4sgB0Ds1tvLgUUkY+pwzu6/xEg==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/installations": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/analytics-compat": { - "version": "0.2.23", - "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.23.tgz", - "integrity": "sha512-3AdO10RN18G5AzREPoFgYhW6vWXr3u+OYQv6pl3CX6Fky8QRk0AHurZlY3Q1xkXO0TDxIsdhO3y65HF7PBOJDw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/analytics": "0.10.17", - "@firebase/analytics-types": "0.8.3", - "@firebase/component": "0.6.18", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/analytics-types": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", - "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/app": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.2.tgz", - "integrity": "sha512-jwtMmJa1BXXDCiDx1vC6SFN/+HfYG53UkfJa6qeN5ogvOunzbFDO3wISZy5n9xgYFUrEP6M7e8EG++riHNTv9w==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/app-check": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.10.1.tgz", - "integrity": "sha512-MgNdlms9Qb0oSny87pwpjKush9qUwCJhfmTJHDfrcKo4neLGiSeVE4qJkzP7EQTIUFKp84pbTxobSAXkiuQVYQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/app-check-compat": { - "version": "0.3.26", - "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.26.tgz", - "integrity": "sha512-PkX+XJMLDea6nmnopzFKlr+s2LMQGqdyT2DHdbx1v1dPSqOol2YzgpgymmhC67vitXVpNvS3m/AiWQWWhhRRPQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check": "0.10.1", - "@firebase/app-check-types": "0.5.3", - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/app-check-interop-types": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", - "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/app-check-types": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", - "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/app-compat": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.4.2.tgz", - "integrity": "sha512-LssbyKHlwLeiV8GBATyOyjmHcMpX/tFjzRUCS1jnwGAew1VsBB4fJowyS5Ud5LdFbYpJeS+IQoC+RQxpK7eH3Q==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app": "0.13.2", - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/app-types": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/auth": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", - "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x", - "@react-native-async-storage/async-storage": "^1.18.1" - }, - "peerDependenciesMeta": { - "@react-native-async-storage/async-storage": { - "optional": true - } - } - }, - "node_modules/@firebase/auth-compat": { - "version": "0.5.28", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.28.tgz", - "integrity": "sha512-HpMSo/cc6Y8IX7bkRIaPPqT//Jt83iWy5rmDWeThXQCAImstkdNo3giFLORJwrZw2ptiGkOij64EH1ztNJzc7Q==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/auth": "1.10.8", - "@firebase/auth-types": "0.13.0", - "@firebase/component": "0.6.18", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/auth-interop-types": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", - "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/auth-types": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", - "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/component": { - "version": "0.6.18", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.18.tgz", - "integrity": "sha512-n28kPCkE2dL2U28fSxZJjzPPVpKsQminJ6NrzcKXAI0E/lYC8YhfwpyllScqVEvAI3J2QgJZWYgrX+1qGI+SQQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/data-connect": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.10.tgz", - "integrity": "sha512-VMVk7zxIkgwlVQIWHOKFahmleIjiVFwFOjmakXPd/LDgaB/5vzwsB5DWIYo+3KhGxWpidQlR8geCIn39YflJIQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/database": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.20.tgz", - "integrity": "sha512-H9Rpj1pQ1yc9+4HQOotFGLxqAXwOzCHsRSRjcQFNOr8lhUt6LeYjf0NSRL04sc4X0dWe8DsCvYKxMYvFG/iOJw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.3", - "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/database-compat": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.11.tgz", - "integrity": "sha512-itEsHARSsYS95+udF/TtIzNeQ0Uhx4uIna0sk4E0wQJBUnLc/G1X6D7oRljoOuwwCezRLGvWBRyNrugv/esOEw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/database": "1.0.20", - "@firebase/database-types": "1.0.15", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/database-types": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.15.tgz", - "integrity": "sha512-XWHJ0VUJ0k2E9HDMlKxlgy/ZuTa9EvHCGLjaKSUvrQnwhgZuRU5N3yX6SZ+ftf2hTzZmfRkv+b3QRvGg40bKNw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-types": "0.9.3", - "@firebase/util": "1.12.1" - } - }, - "node_modules/@firebase/firestore": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.8.0.tgz", - "integrity": "sha512-QSRk+Q1/CaabKyqn3C32KSFiOdZpSqI9rpLK5BHPcooElumOBooPFa6YkDdiT+/KhJtel36LdAacha9BptMj2A==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "@firebase/webchannel-wrapper": "1.0.3", - "@grpc/grpc-js": "~1.9.0", - "@grpc/proto-loader": "^0.7.8", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/firestore-compat": { - "version": "0.3.53", - "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.53.tgz", - "integrity": "sha512-qI3yZL8ljwAYWrTousWYbemay2YZa+udLWugjdjju2KODWtLG94DfO4NALJgPLv8CVGcDHNFXoyQexdRA0Cz8Q==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/firestore": "4.8.0", - "@firebase/firestore-types": "3.0.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/firestore-types": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", - "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/functions": { - "version": "0.12.9", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.9.tgz", - "integrity": "sha512-FG95w6vjbUXN84Ehezc2SDjGmGq225UYbHrb/ptkRT7OTuCiQRErOQuyt1jI1tvcDekdNog+anIObihNFz79Lg==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.3", - "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.18", - "@firebase/messaging-interop-types": "0.2.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/functions-compat": { - "version": "0.3.26", - "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.26.tgz", - "integrity": "sha512-A798/6ff5LcG2LTWqaGazbFYnjBW8zc65YfID/en83ALmkhu2b0G8ykvQnLtakbV9ajrMYPn7Yc/XcYsZIUsjA==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/functions": "0.12.9", - "@firebase/functions-types": "0.6.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/functions-types": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", - "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/installations": { - "version": "0.6.18", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.18.tgz", - "integrity": "sha512-NQ86uGAcvO8nBRwVltRL9QQ4Reidc/3whdAasgeWCPIcrhOKDuNpAALa6eCVryLnK14ua2DqekCOX5uC9XbU/A==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/util": "1.12.1", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/installations-compat": { - "version": "0.2.18", - "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.18.tgz", - "integrity": "sha512-aLFohRpJO5kKBL/XYL4tN+GdwEB/Q6Vo9eZOM/6Kic7asSUgmSfGPpGUZO1OAaSRGwF4Lqnvi1f/f9VZnKzChw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/installations": "0.6.18", - "@firebase/installations-types": "0.5.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/installations-types": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", - "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x" - } - }, - "node_modules/@firebase/logger": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", - "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/messaging": { - "version": "0.12.22", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.22.tgz", - "integrity": "sha512-GJcrPLc+Hu7nk+XQ70Okt3M1u1eRr2ZvpMbzbc54oTPJZySHcX9ccZGVFcsZbSZ6o1uqumm8Oc7OFkD3Rn1/og==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/installations": "0.6.18", - "@firebase/messaging-interop-types": "0.2.3", - "@firebase/util": "1.12.1", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/messaging-compat": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.22.tgz", - "integrity": "sha512-5ZHtRnj6YO6f/QPa/KU6gryjmX4Kg33Kn4gRpNU6M1K47Gm8kcQwPkX7erRUYEH1mIWptfvjvXMHWoZaWjkU7A==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/messaging": "0.12.22", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/messaging-interop-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", - "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/performance": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.7.tgz", - "integrity": "sha512-JTlTQNZKAd4+Q5sodpw6CN+6NmwbY72av3Lb6wUKTsL7rb3cuBIhQSrslWbVz0SwK3x0ZNcqX24qtRbwKiv+6w==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/installations": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0", - "web-vitals": "^4.2.4" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/performance-compat": { - "version": "0.2.20", - "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.20.tgz", - "integrity": "sha512-XkFK5NmOKCBuqOKWeRgBUFZZGz9SzdTZp4OqeUg+5nyjapTiZ4XoiiUL8z7mB2q+63rPmBl7msv682J3rcDXIQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/performance": "0.7.7", - "@firebase/performance-types": "0.2.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/performance-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", - "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/remote-config": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.5.tgz", - "integrity": "sha512-fU0c8HY0vrVHwC+zQ/fpXSqHyDMuuuglV94VF6Yonhz8Fg2J+KOowPGANM0SZkLvVOYpTeWp3ZmM+F6NjwWLnw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/installations": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/remote-config-compat": { - "version": "0.2.18", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.18.tgz", - "integrity": "sha512-YiETpldhDy7zUrnS8e+3l7cNs0sL7+tVAxvVYU0lu7O+qLHbmdtAxmgY+wJqWdW2c9nDvBFec7QiF58pEUu0qQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/logger": "0.4.4", - "@firebase/remote-config": "0.6.5", - "@firebase/remote-config-types": "0.4.0", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/remote-config-types": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", - "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/storage": { - "version": "0.13.14", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.14.tgz", - "integrity": "sha512-xTq5ixxORzx+bfqCpsh+o3fxOsGoDjC1nO0Mq2+KsOcny3l7beyBhP/y1u5T6mgsFQwI1j6oAkbT5cWdDBx87g==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/storage-compat": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.24.tgz", - "integrity": "sha512-XHn2tLniiP7BFKJaPZ0P8YQXKiVJX+bMyE2j2YWjYfaddqiJnROJYqSomwW6L3Y+gZAga35ONXUJQju6MB6SOQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.18", - "@firebase/storage": "0.13.14", - "@firebase/storage-types": "0.8.3", - "@firebase/util": "1.12.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/storage-types": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", - "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/util": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.1.tgz", - "integrity": "sha512-zGlBn/9Dnya5ta9bX/fgEoNC3Cp8s6h+uYPYaDieZsFOAdHP/ExzQ/eaDgxD3GOROdPkLKpvKY0iIzr9adle0w==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/webchannel-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", - "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==", - "license": "Apache-2.0" - }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@google-cloud/firestore": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.2.tgz", - "integrity": "sha512-BQCSbjWJndCZ6bj8BSGhi4EM1TDFs9HgZXXsJ7d2kEPo+x64fB3OnQE8ffmn3vWADqeAmYBPaMPF/k6PHETXKA==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@opentelemetry/api": "^1.3.0", - "fast-deep-equal": "^3.1.1", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^4.3.3", - "protobufjs": "^7.2.6" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/paginator": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", - "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/projectify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", - "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/promisify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", - "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@google-cloud/storage": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.16.0.tgz", - "integrity": "sha512-7/5LRgykyOfQENcm6hDKP8SX/u9XxE5YOiWOkgkwcoO+cG8xT/cyOvp9wwN3IxfdYgpHs8CE7Nq2PKX2lNaEXw==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@google-cloud/paginator": "^5.0.0", - "@google-cloud/projectify": "^4.0.0", - "@google-cloud/promisify": "<4.1.0", - "abort-controller": "^3.0.0", - "async-retry": "^1.3.3", - "duplexify": "^4.1.3", - "fast-xml-parser": "^4.4.1", - "gaxios": "^6.0.2", - "google-auth-library": "^9.6.3", - "html-entities": "^2.5.2", - "mime": "^3.0.0", - "p-limit": "^3.0.1", - "retry-request": "^7.0.0", - "teeny-request": "^9.0.0", - "uuid": "^8.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@google-cloud/storage/node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "license": "MIT", - "optional": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@google-cloud/storage/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@google/genai": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.8.0.tgz", - "integrity": "sha512-n3KiMFesQCy2R9iSdBIuJ0JWYQ1HZBJJkmt4PPZMGZKvlgHhBAGw1kUMyX+vsAIzprN3lK45DI755lm70wPOOg==", - "license": "Apache-2.0", - "dependencies": { - "google-auth-library": "^9.14.2", - "ws": "^8.18.0", - "zod": "^3.22.4", - "zod-to-json-schema": "^3.22.4" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@modelcontextprotocol/sdk": "^1.11.0" - }, - "peerDependenciesMeta": { - "@modelcontextprotocol/sdk": { - "optional": true - } - } - }, - "node_modules/@google/generative-ai": { - "version": "0.24.1", - "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz", - "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.9.15", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", - "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", - "license": "Apache-2.0", - "dependencies": { - "@grpc/proto-loader": "^0.7.8", - "@types/node": ">=12.12.47" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", - "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", - "license": "Apache-2.0", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz", - "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.1.0" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz", - "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.1.0" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", - "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", - "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", - "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", - "cpu": [ - "arm" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", - "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", - "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", - "cpu": [ - "ppc64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", - "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", - "cpu": [ - "s390x" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", - "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", - "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", - "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.2.tgz", - "integrity": "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.1.0" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.2.tgz", - "integrity": "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.1.0" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.2.tgz", - "integrity": "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.1.0" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.2.tgz", - "integrity": "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.1.0" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.2.tgz", - "integrity": "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.2.tgz", - "integrity": "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.1.0" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.2.tgz", - "integrity": "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.4.3" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.2.tgz", - "integrity": "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.2.tgz", - "integrity": "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.2.tgz", - "integrity": "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "license": "MIT", - "optional": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "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/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", - "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@npmcli/move-file": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", - "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "deprecated": "This functionality has been moved to @npmcli/fs", - "dev": true, - "license": "MIT", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "license": "BSD-3-Clause" - }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", - "license": "BSD-3-Clause" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@types/appdmg": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@types/appdmg/-/appdmg-0.5.5.tgz", - "integrity": "sha512-G+n6DgZTZFOteITE30LnWj+HRVIGr7wMlAiLWOO02uJFWVEitaPU9JVXm9wJokkgshBawb2O1OykdcsmkkZfgg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, - "node_modules/@types/caseless": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", - "license": "MIT", - "optional": true - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", - "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/fs-extra": { - "version": "9.0.13", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", - "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "license": "MIT" - }, - "node_modules/@types/jsonwebtoken": { - "version": "9.0.10", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", - "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", - "license": "MIT", - "dependencies": { - "@types/ms": "*", - "@types/node": "*" - } - }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", - "license": "MIT", - "optional": true - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "20.19.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.4.tgz", - "integrity": "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.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/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "license": "MIT" - }, - "node_modules/@types/request": { - "version": "2.48.12", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", - "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, - "node_modules/@types/request/node_modules/form-data": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.3.tgz", - "integrity": "sha512-XHIrMD0NpDrNM/Ckf7XJiBbLl57KEhT3+i3yY+eWm+cqYZJQTZrKo8Y8AWKnuV5GT4scfuUGt9LzNoIx3dU1nQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "mime-types": "^2.1.35", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/@types/responselike": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", - "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/send": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", - "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", - "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "license": "MIT", - "optional": true - }, - "node_modules/@types/verror": { - "version": "1.10.11", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", - "integrity": "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", - "dev": true, - "license": "MIT", - "engines": { - "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": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "license": "ISC" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/agent-base": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/agentkeepalive": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", - "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", - "license": "MIT", - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "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": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "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-escapes": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", - "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^1.0.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/app-builder-bin": { - "version": "5.0.0-alpha.12", - "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz", - "integrity": "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/app-builder-lib": { - "version": "26.0.12", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.0.12.tgz", - "integrity": "sha512-+/CEPH1fVKf6HowBUs6LcAIoRcjeqgvAeoSE+cl7Y7LndyQ9ViGPYibNk7wmhMHzNgHIuIbw4nWADPO+4mjgWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@develar/schema-utils": "~2.6.5", - "@electron/asar": "3.2.18", - "@electron/fuses": "^1.8.0", - "@electron/notarize": "2.5.0", - "@electron/osx-sign": "1.3.1", - "@electron/rebuild": "3.7.0", - "@electron/universal": "2.0.1", - "@malept/flatpak-bundler": "^0.4.0", - "@types/fs-extra": "9.0.13", - "async-exit-hook": "^2.0.1", - "builder-util": "26.0.11", - "builder-util-runtime": "9.3.1", - "chromium-pickle-js": "^0.2.0", - "config-file-ts": "0.2.8-rc1", - "debug": "^4.3.4", - "dotenv": "^16.4.5", - "dotenv-expand": "^11.0.6", - "ejs": "^3.1.8", - "electron-publish": "26.0.11", - "fs-extra": "^10.1.0", - "hosted-git-info": "^4.1.0", - "is-ci": "^3.0.0", - "isbinaryfile": "^5.0.0", - "js-yaml": "^4.1.0", - "json5": "^2.2.3", - "lazy-val": "^1.0.5", - "minimatch": "^10.0.0", - "plist": "3.1.0", - "resedit": "^1.7.0", - "semver": "^7.3.8", - "tar": "^6.1.12", - "temp-file": "^3.4.0", - "tiny-async-pool": "1.3.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "dmg-builder": "26.0.12", - "electron-builder-squirrel-windows": "26.0.12" - } - }, - "node_modules/app-builder-lib/node_modules/@electron/asar": { - "version": "3.2.18", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.18.tgz", - "integrity": "sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - }, - "bin": { - "asar": "bin/asar.js" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/app-builder-lib/node_modules/@electron/asar/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/app-builder-lib/node_modules/@electron/osx-sign": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.1.tgz", - "integrity": "sha512-BAfviURMHpmb1Yb50YbCxnOY0wfwaLXH5KJ4+80zS0gUkzDX3ec23naTlEqKsN+PwYn+a1cCzM7BJ4Wcd3sGzw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "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/app-builder-lib/node_modules/@electron/osx-sign/node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "node_modules/app-builder-lib/node_modules/@electron/rebuild": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.0.tgz", - "integrity": "sha512-VW++CNSlZwMYP7MyXEbrKjpzEwhB5kDNbzGtiPEjwYysqyTCF+YbNJ210Dj3AjWsGSV4iEEwNkmJN9yGZmVvmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.1.1", - "detect-libc": "^2.0.1", - "fs-extra": "^10.0.0", - "got": "^11.7.0", - "node-abi": "^3.45.0", - "node-api-version": "^0.2.0", - "ora": "^5.1.0", - "read-binary-file-arch": "^1.0.6", - "semver": "^7.3.5", - "tar": "^6.0.5", - "yargs": "^17.0.1" - }, - "bin": { - "electron-rebuild": "lib/cli.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/app-builder-lib/node_modules/@electron/universal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz", - "integrity": "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@electron/asar": "^3.2.7", - "@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/app-builder-lib/node_modules/@electron/universal/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/app-builder-lib/node_modules/@electron/universal/node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/app-builder-lib/node_modules/@electron/universal/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/app-builder-lib/node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/app-builder-lib/node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/app-builder-lib/node_modules/isbinaryfile": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.4.tgz", - "integrity": "sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 18.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "node_modules/app-builder-lib/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/app-builder-lib/node_modules/pe-library": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz", - "integrity": "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12", - "npm": ">=6" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jet2jet" - } - }, - "node_modules/app-builder-lib/node_modules/resedit": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/resedit/-/resedit-1.7.2.tgz", - "integrity": "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pe-library": "^0.4.1" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jet2jet" - } - }, - "node_modules/appdmg": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/appdmg/-/appdmg-0.6.6.tgz", - "integrity": "sha512-GRmFKlCG+PWbcYF4LUNonTYmy0GjguDy6Jh9WP8mpd0T6j80XIJyXBiWlD0U+MLNhqV9Nhx49Gl9GpVToulpLg==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "async": "^1.4.2", - "ds-store": "^0.1.5", - "execa": "^1.0.0", - "fs-temp": "^1.0.0", - "fs-xattr": "^0.3.0", - "image-size": "^0.7.4", - "is-my-json-valid": "^2.20.0", - "minimist": "^1.1.3", - "parse-color": "^1.0.0", - "path-exists": "^4.0.0", - "repeat-string": "^1.5.4" - }, - "bin": { - "appdmg": "bin/appdmg.js" - }, - "engines": { - "node": ">=8.5" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "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": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/async-exit-hook": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", - "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/async-retry": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", - "license": "MIT", - "optional": true, - "dependencies": { - "retry": "0.13.1" - } - }, - "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": "1.7.0", - "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", - "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", - "license": "MIT", - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/author-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", - "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/axios": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", - "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/base32-encode": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/base32-encode/-/base32-encode-1.2.0.tgz", - "integrity": "sha512-cHFU8XeRyx0GgmoWi5qHMCVRiqU6J3MHWxVgun7jggCBUpVzm1Ir7M9dYr2whjSNc3tFeXfQ/oZjQu/4u55h9A==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "to-data-view": "^1.1.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/better-sqlite3": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.6.0.tgz", - "integrity": "sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "bindings": "^1.5.0", - "prebuild-install": "^7.1.1" - } - }, - "node_modules/bignumber.js": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.0.tgz", - "integrity": "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/bplist-creator": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", - "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "stream-buffers": "~2.2.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/builder-util": { - "version": "26.0.11", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.0.11.tgz", - "integrity": "sha512-xNjXfsldUEe153h1DraD0XvDOpqGR0L5eKFkdReB7eFW5HqysDZFfly4rckda6y9dF39N3pkPlOblcfHKGw+uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/debug": "^4.1.6", - "7zip-bin": "~5.2.0", - "app-builder-bin": "5.0.0-alpha.12", - "builder-util-runtime": "9.3.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", - "is-ci": "^3.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.3.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.3.1.tgz", - "integrity": "sha512-2/egrNDDnRaxVwK3A+cJq6UOlqOdedGA7JPqCeJjN2Zjk1/QB/6QUi3b714ScIGS7HafFXTyzJEOr5b44I3kvQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacache": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", - "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/cacache/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/cacache/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/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/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/chromium-pickle-js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "license": "MIT", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "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": "10.2.0", - "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", - "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", - "license": "MIT", - "dependencies": { - "ajv": "^8.6.3", - "ajv-formats": "^2.1.1", - "atomically": "^1.7.0", - "debounce-fn": "^4.0.0", - "dot-prop": "^6.0.1", - "env-paths": "^2.2.1", - "json-schema-typed": "^7.0.3", - "onetime": "^5.1.2", - "pkg-up": "^3.1.0", - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/conf/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "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/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/config-file-ts": { - "version": "0.2.8-rc1", - "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.8-rc1.tgz", - "integrity": "sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "^10.3.12", - "typescript": "^5.4.3" - } - }, - "node_modules/config-file-ts/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/config-file-ts/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/config-file-ts/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/config-file-ts/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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" - }, - "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-zip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-4.0.1.tgz", - "integrity": "sha512-n63i0lZ0rvQ6FXiGQ+/JFCKAUyPFhLQYJIqKaa+tSJtfKeULF/IDNDAbdnSIxgS4NTuw2b0+lj8LzfITuq+ZxQ==", - "dev": true, - "funding": [ - { - "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", - "engines": { - "node": ">=12.10" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/date-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", - "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "time-zone": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/debounce-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", - "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", - "license": "MIT", - "dependencies": { - "mimic-fn": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/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-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/dir-compare": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz", - "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimatch": "^3.0.5", - "p-limit": "^3.1.0 " - } - }, - "node_modules/dmg-builder": { - "version": "26.0.12", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.0.12.tgz", - "integrity": "sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w==", - "dev": true, - "license": "MIT", - "dependencies": { - "app-builder-lib": "26.0.12", - "builder-util": "26.0.11", - "builder-util-runtime": "9.3.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-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/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "license": "MIT", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dotenv": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.0.1.tgz", - "integrity": "sha512-GLjkduuAL7IMJg/ZnOPm9AnWKJ82mSE2tzXLaJ/6hD6DhwGfZaXG77oB8qbReyiczNxnbxQKyh0OE5mXq0bAHA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "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/dotenv-expand/node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/ds-store": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ds-store/-/ds-store-0.1.6.tgz", - "integrity": "sha512-kY21M6Lz+76OS3bnCzjdsJSF7LBpLYGCVfavW8TgQD2XkcqIZ86W0y9qUDZu6fp7SIZzqosMDW2zi7zVFfv4hw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bplist-creator": "~0.0.3", - "macos-alias": "~0.2.5", - "tn1150": "^0.1.0" - } - }, - "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/duplexify": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", - "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", - "license": "MIT", - "optional": true, - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.2" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron": { - "version": "30.5.1", - "resolved": "https://registry.npmjs.org/electron/-/electron-30.5.1.tgz", - "integrity": "sha512-AhL7+mZ8Lg14iaNfoYTkXQ2qee8mmsQyllKdqxlpv/zrKgfxz6jNVtcRRbQtLxtF8yzcImWdfTQROpYiPumdbw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@electron/get": "^2.0.0", - "@types/node": "^20.9.0", - "extract-zip": "^2.0.1" - }, - "bin": { - "electron": "cli.js" - }, - "engines": { - "node": ">= 12.20.55" - } - }, - "node_modules/electron-builder": { - "version": "26.0.12", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.0.12.tgz", - "integrity": "sha512-cD1kz5g2sgPTMFHjLxfMjUK5JABq3//J4jPswi93tOPFz6btzXYtK5NrDt717NRbukCUDOrrvmYVOWERlqoiXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "app-builder-lib": "26.0.12", - "builder-util": "26.0.11", - "builder-util-runtime": "9.3.1", - "chalk": "^4.1.2", - "dmg-builder": "26.0.12", - "fs-extra": "^10.1.0", - "is-ci": "^3.0.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.0.12", - "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.0.12.tgz", - "integrity": "sha512-kpwXM7c/ayRUbYVErQbsZ0nQZX4aLHQrPEG9C4h9vuJCXylwFH8a7Jgi2VpKIObzCXO7LKHiCw4KdioFLFOgqA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "app-builder-lib": "26.0.12", - "builder-util": "26.0.11", - "electron-winstaller": "5.4.0" - } - }, - "node_modules/electron-installer-common": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/electron-installer-common/-/electron-installer-common-0.10.4.tgz", - "integrity": "sha512-8gMNPXfAqUE5CfXg8RL0vXpLE9HAaPkgLXVoHE3BMUzogMWenf4LmwQ27BdCUrEhkjrKl+igs2IHJibclR3z3Q==", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@electron/asar": "^3.2.5", - "@malept/cross-spawn-promise": "^1.0.0", - "debug": "^4.1.1", - "fs-extra": "^9.0.0", - "glob": "^7.1.4", - "lodash": "^4.17.15", - "parse-author": "^2.0.0", - "semver": "^7.1.1", - "tmp-promise": "^3.0.2" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "url": "https://github.com/electron-userland/electron-installer-common?sponsor=1" - }, - "optionalDependencies": { - "@types/fs-extra": "^9.0.1" - } - }, - "node_modules/electron-installer-common/node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "funding": [ - { - "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", - "optional": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/electron-installer-common/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "optional": true, - "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-installer-debian": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/electron-installer-debian/-/electron-installer-debian-3.2.0.tgz", - "integrity": "sha512-58ZrlJ1HQY80VucsEIG9tQ//HrTlG6sfofA3nRGr6TmkX661uJyu4cMPPh6kXW+aHdq/7+q25KyQhDrXvRL7jw==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin", - "linux" - ], - "dependencies": { - "@malept/cross-spawn-promise": "^1.0.0", - "debug": "^4.1.1", - "electron-installer-common": "^0.10.2", - "fs-extra": "^9.0.0", - "get-folder-size": "^2.0.1", - "lodash": "^4.17.4", - "word-wrap": "^1.2.3", - "yargs": "^16.0.2" - }, - "bin": { - "electron-installer-debian": "src/cli.js" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/electron-installer-debian/node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "funding": [ - { - "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", - "optional": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/electron-installer-debian/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-installer-debian/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/electron-installer-debian/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "optional": true, - "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-installer-debian/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-installer-debian/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "optional": true, - "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/electron-installer-debian/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-installer-debian/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "optional": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-installer-dmg": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/electron-installer-dmg/-/electron-installer-dmg-5.0.1.tgz", - "integrity": "sha512-qOa1aAQdX57C+vzhDk3549dd/PRlNL4F8y736MTD1a43qptD+PvHY97Bo9gSf+OZ8iUWE7BrYSpk/FgLUe40EA==", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@types/appdmg": "^0.5.5", - "debug": "^4.3.2", - "minimist": "^1.2.7" - }, - "bin": { - "electron-installer-dmg": "dist/electron-installer-dmg-bin.js" - }, - "engines": { - "node": ">= 16" - }, - "optionalDependencies": { - "appdmg": "^0.6.4" - } - }, - "node_modules/electron-installer-redhat": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/electron-installer-redhat/-/electron-installer-redhat-3.4.0.tgz", - "integrity": "sha512-gEISr3U32Sgtj+fjxUAlSDo3wyGGq6OBx7rF5UdpIgbnpUvMN4W5uYb0ThpnAZ42VEJh/3aODQXHbFS4f5J3Iw==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin", - "linux" - ], - "dependencies": { - "@malept/cross-spawn-promise": "^1.0.0", - "debug": "^4.1.1", - "electron-installer-common": "^0.10.2", - "fs-extra": "^9.0.0", - "lodash": "^4.17.15", - "word-wrap": "^1.2.3", - "yargs": "^16.0.2" - }, - "bin": { - "electron-installer-redhat": "src/cli.js" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/electron-installer-redhat/node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "funding": [ - { - "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", - "optional": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/electron-installer-redhat/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-installer-redhat/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/electron-installer-redhat/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "optional": true, - "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-installer-redhat/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-installer-redhat/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "optional": true, - "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/electron-installer-redhat/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-installer-redhat/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "optional": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-is-dev": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz", - "integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==", - "dev": true, - "license": "MIT" - }, - "node_modules/electron-liquid-glass": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/electron-liquid-glass/-/electron-liquid-glass-1.0.1.tgz", - "integrity": "sha512-XznNF0uDOmwvIQFGfgZM6PiQbrpXJiG4GYN6VnLzUrZwcOsQUGy51cJ5mPZCfwH+ST/ahorhLzwFEr+hsKRHXw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "node-addon-api": "^8.4.0" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "node-gyp-build": "^4" - } - }, - "node_modules/electron-publish": { - "version": "26.0.11", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.0.11.tgz", - "integrity": "sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/fs-extra": "^9.0.11", - "builder-util": "26.0.11", - "builder-util-runtime": "9.3.1", - "chalk": "^4.1.2", - "form-data": "^4.0.0", - "fs-extra": "^10.1.0", - "lazy-val": "^1.0.5", - "mime": "^2.5.2" - } - }, - "node_modules/electron-reloader": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/electron-reloader/-/electron-reloader-1.2.3.tgz", - "integrity": "sha512-aDnACAzNg0QvQhzw7LYOx/nVS10mEtbuG6M0QQvNQcLnJEwFs6is+EGRCnM+KQlQ4KcTbdwnt07nd7ZjHpY4iw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "chokidar": "^3.5.0", - "date-time": "^3.1.0", - "electron-is-dev": "^1.2.0", - "find-up": "^5.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/electron-squirrel-startup": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/electron-squirrel-startup/-/electron-squirrel-startup-1.0.1.tgz", - "integrity": "sha512-sTfFIHGku+7PsHLJ7v0dRcZNkALrV+YEozINTW8X1nM//e5O3L+rfYuvSW00lmGHnYmUjARZulD8F2V8ISI9RA==", - "license": "Apache-2.0", - "dependencies": { - "debug": "^2.2.0" - } - }, - "node_modules/electron-squirrel-startup/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/electron-squirrel-startup/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/electron-store": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.2.0.tgz", - "integrity": "sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw==", - "license": "MIT", - "dependencies": { - "conf": "^10.2.0", - "type-fest": "^2.17.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/electron-updater": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.6.2.tgz", - "integrity": "sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw==", - "license": "MIT", - "dependencies": { - "builder-util-runtime": "9.3.1", - "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.6.3", - "tiny-typed-emitter": "^2.1.0" - } - }, - "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", - "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", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/electron-winstaller/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-winstaller/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/electron/node_modules/@electron/get": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", - "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "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/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/electron/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/electron/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/encode-utf8": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "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/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/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "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-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/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/esbuild": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", - "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.5", - "@esbuild/android-arm": "0.25.5", - "@esbuild/android-arm64": "0.25.5", - "@esbuild/android-x64": "0.25.5", - "@esbuild/darwin-arm64": "0.25.5", - "@esbuild/darwin-x64": "0.25.5", - "@esbuild/freebsd-arm64": "0.25.5", - "@esbuild/freebsd-x64": "0.25.5", - "@esbuild/linux-arm": "0.25.5", - "@esbuild/linux-arm64": "0.25.5", - "@esbuild/linux-ia32": "0.25.5", - "@esbuild/linux-loong64": "0.25.5", - "@esbuild/linux-mips64el": "0.25.5", - "@esbuild/linux-ppc64": "0.25.5", - "@esbuild/linux-riscv64": "0.25.5", - "@esbuild/linux-s390x": "0.25.5", - "@esbuild/linux-x64": "0.25.5", - "@esbuild/netbsd-arm64": "0.25.5", - "@esbuild/netbsd-x64": "0.25.5", - "@esbuild/openbsd-arm64": "0.25.5", - "@esbuild/openbsd-x64": "0.25.5", - "@esbuild/sunos-x64": "0.25.5", - "@esbuild/win32-arm64": "0.25.5", - "@esbuild/win32-ia32": "0.25.5", - "@esbuild/win32-x64": "0.25.5" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true, - "license": "MIT" - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/execa/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/execa/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/execa/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, - "node_modules/exponential-backoff": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", - "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/farmhash-modern": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", - "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fast-xml-parser": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", - "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "strnum": "^1.1.1" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/firebase": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.10.0.tgz", - "integrity": "sha512-nKBXoDzF0DrXTBQJlZa+sbC5By99ysYU1D6PkMRYknm0nCW7rJly47q492Ht7Ndz5MeYSBuboKuhS1e6mFC03w==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/ai": "1.4.1", - "@firebase/analytics": "0.10.17", - "@firebase/analytics-compat": "0.2.23", - "@firebase/app": "0.13.2", - "@firebase/app-check": "0.10.1", - "@firebase/app-check-compat": "0.3.26", - "@firebase/app-compat": "0.4.2", - "@firebase/app-types": "0.9.3", - "@firebase/auth": "1.10.8", - "@firebase/auth-compat": "0.5.28", - "@firebase/data-connect": "0.3.10", - "@firebase/database": "1.0.20", - "@firebase/database-compat": "2.0.11", - "@firebase/firestore": "4.8.0", - "@firebase/firestore-compat": "0.3.53", - "@firebase/functions": "0.12.9", - "@firebase/functions-compat": "0.3.26", - "@firebase/installations": "0.6.18", - "@firebase/installations-compat": "0.2.18", - "@firebase/messaging": "0.12.22", - "@firebase/messaging-compat": "0.2.22", - "@firebase/performance": "0.7.7", - "@firebase/performance-compat": "0.2.20", - "@firebase/remote-config": "0.6.5", - "@firebase/remote-config-compat": "0.2.18", - "@firebase/storage": "0.13.14", - "@firebase/storage-compat": "0.3.24", - "@firebase/util": "1.12.1" - } - }, - "node_modules/firebase-admin": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.4.0.tgz", - "integrity": "sha512-Y8DcyKK+4pl4B93ooiy1G8qvdyRMkcNFfBSh+8rbVcw4cW8dgG0VXCCTp5NUwub8sn9vSPsOwpb9tE2OuFmcfQ==", - "license": "Apache-2.0", - "dependencies": { - "@fastify/busboy": "^3.0.0", - "@firebase/database-compat": "^2.0.0", - "@firebase/database-types": "^1.0.6", - "@types/node": "^22.8.7", - "farmhash-modern": "^1.1.0", - "google-auth-library": "^9.14.2", - "jsonwebtoken": "^9.0.0", - "jwks-rsa": "^3.1.0", - "node-forge": "^1.3.1", - "uuid": "^11.0.2" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@google-cloud/firestore": "^7.11.0", - "@google-cloud/storage": "^7.14.0" - } - }, - "node_modules/firebase-admin/node_modules/@types/node": { - "version": "22.16.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.0.tgz", - "integrity": "sha512-B2egV9wALML1JCpv3VQoQ+yesQKAmNMBIAY7OteVrikcOcAkWm+dGL6qpeCktPjAv6N1JLnhbNiqS35UpFyBsQ==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/flora-colossus": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-2.0.0.tgz", - "integrity": "sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4", - "fs-extra": "^10.1.0" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/fmix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", - "integrity": "sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "imul": "^1.0.0" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/form-data-encoder": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", - "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", - "license": "MIT" - }, - "node_modules/formdata-node": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", - "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", - "license": "MIT", - "dependencies": { - "node-domexception": "1.0.0", - "web-streams-polyfill": "4.0.0-beta.3" - }, - "engines": { - "node": ">= 12.20" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT" - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-temp": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-1.2.1.tgz", - "integrity": "sha512-okTwLB7/Qsq82G6iN5zZJFsOfZtx2/pqrA7Hk/9fvy+c+eJS9CvgGXT2uNxwnI14BDY9L/jQPkaBgSvlKfSW9w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "random-path": "^0.1.0" - } - }, - "node_modules/fs-xattr": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/fs-xattr/-/fs-xattr-0.3.1.tgz", - "integrity": "sha512-UVqkrEW0GfDabw4C3HOrFlxKfx0eeigfRne69FxSBdHIP8Qt5Sq6Pu3RM9KmMlkygtC4pPKkj5CiPO5USnj2GA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "!win32" - ], - "engines": { - "node": ">=8.6.0" - } - }, - "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/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "license": "MIT", - "optional": true - }, - "node_modules/galactus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/galactus/-/galactus-1.0.0.tgz", - "integrity": "sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4", - "flora-colossus": "^2.0.0", - "fs-extra": "^10.1.0" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/gar": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/gar/-/gar-1.0.4.tgz", - "integrity": "sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/gaxios": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", - "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", - "license": "Apache-2.0", - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.9", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/gaxios/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gaxios/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/gcp-metadata": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", - "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", - "license": "Apache-2.0", - "dependencies": { - "gaxios": "^6.1.1", - "google-logging-utils": "^0.0.2", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "is-property": "^1.0.2" - } - }, - "node_modules/generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "is-property": "^1.0.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==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-folder-size": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-2.0.1.tgz", - "integrity": "sha512-+CEb+GDCM7tkOS2wdMKTn9vU7DgnKUTuDlehkNJKNSovdCOVxs14OfKCk4cvSaR3za4gj+OBdl9opPN9xrJ0zA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "gar": "^1.0.4", - "tiny-each-async": "2.0.3" - }, - "bin": { - "get-folder-size": "bin/get-folder-size" - } - }, - "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-package-info": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", - "integrity": "sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "bluebird": "^3.1.1", - "debug": "^2.2.0", - "lodash.get": "^4.0.0", - "read-pkg-up": "^2.0.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/get-package-info/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/get-package-info/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "license": "MIT" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "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": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "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-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/goober": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", - "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", - "license": "MIT", - "peerDependencies": { - "csstype": "^3.0.10" - } - }, - "node_modules/google-auth-library": { - "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", - "license": "Apache-2.0", - "dependencies": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/google-gax": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.6.1.tgz", - "integrity": "sha512-V6eky/xz2mcKfAd1Ioxyd6nmA61gao3n01C+YeuIwu3vzM9EDR6wcVzMSIbLMDXWeoi9SHYctXuKYC5uJUT3eQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@grpc/grpc-js": "^1.10.9", - "@grpc/proto-loader": "^0.7.13", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "google-auth-library": "^9.3.0", - "node-fetch": "^2.7.0", - "object-hash": "^3.0.0", - "proto3-json-serializer": "^2.0.2", - "protobufjs": "^7.3.2", - "retry-request": "^7.0.0", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/google-gax/node_modules/@grpc/grpc-js": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.4.tgz", - "integrity": "sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@grpc/proto-loader": "^0.7.13", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/google-gax/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/google-logging-utils": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", - "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/gtoken": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", - "license": "MIT", - "dependencies": { - "gaxios": "^6.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "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.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/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/html-entities": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", - "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT", - "optional": true - }, - "node_modules/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", - "license": "MIT" - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.0.0" - } - }, - "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-corefoundation/node_modules/node-addon-api": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", - "license": "ISC" - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/image-size": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz", - "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/imul": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", - "integrity": "sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true, - "license": "ISC" - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-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-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-my-ip-valid": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz", - "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/is-my-json-valid": { - "version": "2.20.6", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", - "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^5.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/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/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "node_modules/jose": { - "version": "4.15.9", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", - "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "license": "MIT", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-typed": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", - "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==", - "license": "BSD-2-Clause" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "license": "MIT", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", - "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "license": "MIT", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/junk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", - "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jwa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jwks-rsa": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", - "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", - "license": "MIT", - "dependencies": { - "@types/express": "^4.17.20", - "@types/jsonwebtoken": "^9.0.4", - "debug": "^4.3.4", - "jose": "^4.15.4", - "limiter": "^1.1.5", - "lru-memoizer": "^2.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "license": "MIT", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/lazy-val": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", - "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", - "license": "MIT" - }, - "node_modules/limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" - }, - "node_modules/listr2": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz", - "integrity": "sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^5.0.1", - "rfdc": "^1.3.0", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/listr2/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/listr2/node_modules/cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/listr2/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/listr2/node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/listr2/node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/listr2/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "license": "MIT" - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "license": "MIT" - }, - "node_modules/lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", - "license": "MIT" - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", - "license": "MIT" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", - "license": "MIT" - }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", - "license": "MIT" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", - "license": "MIT" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", - "license": "MIT" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "license": "MIT" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "license": "MIT" - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", - "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^5.0.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^5.0.0", - "strip-ansi": "^7.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/long": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0" - }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lru-memoizer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", - "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", - "license": "MIT", - "dependencies": { - "lodash.clonedeep": "^4.5.0", - "lru-cache": "6.0.0" - } - }, - "node_modules/macos-alias": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/macos-alias/-/macos-alias-0.2.12.tgz", - "integrity": "sha512-yiLHa7cfJcGRFq4FrR4tMlpNHb4Vy4mWnpajlSSIFM5k4Lv8/7BbbDLzCAVogWNl0LlLhizRp1drXv0hK9h0Yw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "nan": "^2.4.0" - } - }, - "node_modules/make-fetch-happen": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", - "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", - "dev": true, - "license": "ISC", - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/make-fetch-happen/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/make-fetch-happen/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-defer": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "license": "MIT", - "optional": true, - "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/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mem/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, - "license": "MIT", - "bin": { - "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-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", - "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/murmur-32": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/murmur-32/-/murmur-32-0.2.0.tgz", - "integrity": "sha512-ZkcWZudylwF+ir3Ld1n7gL6bI2mQAzXvSobPwVtu8aYi2sbXeipeSkdcanRLzIofLcM5F53lGaKm2dk7orBi7Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "encode-utf8": "^1.0.3", - "fmix": "^0.1.0", - "imul": "^1.0.0" - } - }, - "node_modules/nan": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", - "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-abi": { - "version": "3.75.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", - "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz", - "integrity": "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==", - "license": "MIT", - "optional": true, - "engines": { - "node": "^18 || ^20 || >= 21" - } - }, - "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-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-gyp-build": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", - "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", - "license": "MIT", - "optional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "dev": true, - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/onetime/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/openai": { - "version": "4.104.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz", - "integrity": "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==", - "license": "Apache-2.0", - "dependencies": { - "@types/node": "^18.11.18", - "@types/node-fetch": "^2.6.4", - "abort-controller": "^3.0.0", - "agentkeepalive": "^4.2.1", - "form-data-encoder": "1.7.2", - "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7" - }, - "bin": { - "openai": "bin/cli" - }, - "peerDependencies": { - "ws": "^8.18.0", - "zod": "^3.23.8" - }, - "peerDependenciesMeta": { - "ws": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/openai/node_modules/@types/node": { - "version": "18.19.115", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.115.tgz", - "integrity": "sha512-kNrFiTgG4a9JAn1LMQeLOv3MvXIPokzXziohMrMsvpYgLpdEt/mMiVYc4sGKtDfyxM5gIDF4VgrPRyCw4fHOYg==", - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/openai/node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "license": "MIT" - }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "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/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/parse-author": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", - "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "author-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-color": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", - "integrity": "sha512-fuDHYgFHJGbpGMgw9skY/bj3HL/Jrn4l/5rSspy00DoT4RyLnDcRvPxdZ+r6OFwIsgAuhDh4I09tAId4mI12bw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "color-convert": "~0.5.0" - } - }, - "node_modules/parse-color/node_modules/color-convert": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", - "integrity": "sha512-RwBeO/B/vZR3dfKL1ye/vx8MHZ40ugzpyfeVG5GsiuGnrlMWe2o8wxBbLCpw9CsxV+wHuzYlCiWnybrIA0ling==", - "dev": true, - "optional": true - }, - "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-exists": { - "version": "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/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/path-scurry/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", - "license": "MIT" - }, - "node_modules/path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pe-library": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-1.0.1.tgz", - "integrity": "sha512-nh39Mo1eGWmZS7y+mK/dQIqg7S1lp38DpRxkyoHf0ZcUs/HDc+yyTjuOtTvSMZHmfSLuSQaX945u05Y2Q6UWZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14", - "npm": ">=7" - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "license": "MIT", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/plist": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", - "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@xmldom/xmldom": "^0.8.8", - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" - }, - "engines": { - "node": ">=10.4.0" - } - }, - "node_modules/postject": { - "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", - "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", - "dev": true, - "license": "MIT", - "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", - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/proc-log": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", - "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/promise-retry/node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/proto3-json-serializer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", - "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "protobufjs": "^7.2.5" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/protobufjs": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", - "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "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/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "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/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/random-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/random-path/-/random-path-0.1.2.tgz", - "integrity": "sha512-4jY0yoEaQ5v9StCl5kZbNIQlg1QheIDBrdkDn53EynpPb9FgO6//p3X/tgMnrC45XN6QZCzU1Xz/+pSSsJBpRw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "base32-encode": "^0.1.0 || ^1.0.0", - "murmur-32": "^0.1.0 || ^0.2.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", - "license": "MIT", - "peer": true, - "dependencies": { - "scheduler": "^0.26.0" - }, - "peerDependencies": { - "react": "^19.1.0" - } - }, - "node_modules/react-hot-toast": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.2.tgz", - "integrity": "sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==", - "license": "MIT", - "dependencies": { - "csstype": "^3.1.3", - "goober": "^2.1.16" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": ">=16", - "react-dom": ">=16" - } - }, - "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/read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-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": "2.0.3", - "resolved": "https://registry.npmjs.org/resedit/-/resedit-2.0.3.tgz", - "integrity": "sha512-oTeemxwoMuxxTYxXUwjkrOPfngTQehlv0/HoYFNkB4uzsP1Un1A9nI8JQKGOFkxpqkC7qkMs0lUsGrvUlbLNUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pe-library": "^1.0.1" - }, - "engines": { - "node": ">=14", - "npm": ">=7" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jet2jet" - } - }, - "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/retry-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/request": "^2.48.8", - "extend": "^3.0.2", - "teeny-request": "^9.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/sanitize-filename": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", - "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", - "dev": true, - "license": "WTFPL OR ISC", - "dependencies": { - "truncate-utf8-bytes": "^1.0.0" - } - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "license": "ISC" - }, - "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", - "license": "MIT", - "peer": true - }, - "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/sharp": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", - "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.4", - "semver": "^7.7.2" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.2", - "@img/sharp-darwin-x64": "0.34.2", - "@img/sharp-libvips-darwin-arm64": "1.1.0", - "@img/sharp-libvips-darwin-x64": "1.1.0", - "@img/sharp-libvips-linux-arm": "1.1.0", - "@img/sharp-libvips-linux-arm64": "1.1.0", - "@img/sharp-libvips-linux-ppc64": "1.1.0", - "@img/sharp-libvips-linux-s390x": "1.1.0", - "@img/sharp-libvips-linux-x64": "1.1.0", - "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", - "@img/sharp-libvips-linuxmusl-x64": "1.1.0", - "@img/sharp-linux-arm": "0.34.2", - "@img/sharp-linux-arm64": "0.34.2", - "@img/sharp-linux-s390x": "0.34.2", - "@img/sharp-linux-x64": "0.34.2", - "@img/sharp-linuxmusl-arm64": "0.34.2", - "@img/sharp-linuxmusl-x64": "0.34.2", - "@img/sharp-wasm32": "0.34.2", - "@img/sharp-win32-arm64": "0.34.2", - "@img/sharp-win32-ia32": "0.34.2", - "@img/sharp-win32-x64": "0.34.2" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "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/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "license": "MIT" - }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "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", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", - "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", - "dev": true, - "license": "MIT", - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/socks-proxy-agent/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.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-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/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", - "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/ssri": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "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/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stream-buffers": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", - "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", - "dev": true, - "license": "Unlicense", - "optional": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "license": "MIT", - "optional": true, - "dependencies": { - "stubs": "^3.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "license": "MIT", - "optional": true - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-outer/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/strnum": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", - "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "optional": true - }, - "node_modules/stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", - "license": "MIT", - "optional": true - }, - "node_modules/sudo-prompt": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", - "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "license": "MIT" - }, - "node_modules/sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "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/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-fs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", - "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/teeny-request": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.9", - "stream-events": "^1.0.5", - "uuid": "^9.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/teeny-request/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/teeny-request/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "license": "MIT", - "optional": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/teeny-request/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "optional": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/teeny-request/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/temp": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", - "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "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/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/temp/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/time-zone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", - "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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-each-async": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tiny-each-async/-/tiny-each-async-2.0.3.tgz", - "integrity": "sha512-5ROII7nElnAirvFn8g7H7MtpfV1daMcyfTGQwsn/x2VtyV+VPiO5CjReCJtWLvoKTDEDmZocf3cNPraiMnBXLA==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/tiny-typed-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", - "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==", - "license": "MIT" - }, - "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, - "license": "MIT", - "engines": { - "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/tn1150": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/tn1150/-/tn1150-0.1.0.tgz", - "integrity": "sha512-DbplOfQFkqG5IHcDyyrs/lkvSr3mPUVsFf/RbDppOshs22yTPnSJWEe6FkYd1txAwU/zcnR905ar2fi4kwF29w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "unorm": "^1.4.1" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/to-data-view": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", - "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/trim-repeated/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/truncate-utf8-bytes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", - "dev": true, - "license": "WTFPL", - "dependencies": { - "utf8-byte-length": "^1.0.1" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.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/unique-filename": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", - "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", - "dev": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/unique-slug": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", - "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unorm": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", - "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", - "dev": true, - "license": "MIT or GPL-2.0", - "optional": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/username": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz", - "integrity": "sha512-PCKbdWw85JsYMvmCv5GH3kXmM66rCd9m1hBEDutPNv94b/pqCMT4NtcKyeWYvLFiE8b+ha1Jdl8XAaUdPn5QTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^1.0.0", - "mem": "^4.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/utf8-byte-length": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", - "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", - "dev": true, - "license": "(WTFPL OR MIT)" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/validator": { - "version": "13.15.15", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz", - "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.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/wait-on": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.3.tgz", - "integrity": "sha512-nQFqAFzZDeRxsu7S3C7LbuxslHhk+gnJZHyethuGKAn2IVleIbTB9I3vJSQiSR+DifUqmdzfPMoMPJfLqMF2vw==", - "license": "MIT", - "dependencies": { - "axios": "^1.8.2", - "joi": "^17.13.3", - "lodash": "^4.17.21", - "minimist": "^1.2.8", - "rxjs": "^7.8.2" - }, - "bin": { - "wait-on": "bin/wait-on" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/web-vitals": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", - "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", - "license": "Apache-2.0" - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "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/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "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/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "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/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zod": { - "version": "3.25.75", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.75.tgz", - "integrity": "sha512-OhpzAmVzabPOL6C3A3gpAifqr9MqihV/Msx3gor2b2kviCgcb+HM9SEOpMWwwNp9MRunWnhtAKUoo0AHhjyPPg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.6", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", - "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } - } - } -} From ba3e8a153c0ff70de7d7e23ecbe65a452a1ffe62 Mon Sep 17 00:00:00 2001 From: sanio Date: Tue, 8 Jul 2025 06:20:10 +0900 Subject: [PATCH 37/52] apply CI --- package-lock.json | 12105 ++++++++++++++++++++++++++++ pickleglass_web/package-lock.json | 6976 ++++++++++++++++ 2 files changed, 19081 insertions(+) create mode 100644 package-lock.json create mode 100644 pickleglass_web/package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..55fc266 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,12105 @@ +{ + "name": "pickle-glass", + "version": "0.2.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "pickle-glass", + "version": "0.2.1", + "hasInstallScript": true, + "license": "GPL-3.0", + "dependencies": { + "@anthropic-ai/sdk": "^0.56.0", + "@google/genai": "^1.8.0", + "@google/generative-ai": "^0.24.1", + "axios": "^1.10.0", + "better-sqlite3": "^9.4.3", + "cors": "^2.8.5", + "dotenv": "^17.0.0", + "electron-squirrel-startup": "^1.0.1", + "electron-store": "^8.2.0", + "electron-updater": "^6.6.2", + "express": "^4.18.2", + "firebase": "^11.10.0", + "firebase-admin": "^13.4.0", + "jsonwebtoken": "^9.0.2", + "node-fetch": "^2.7.0", + "openai": "^4.70.0", + "react-hot-toast": "^2.5.2", + "sharp": "^0.34.2", + "validator": "^13.11.0", + "wait-on": "^8.0.3", + "ws": "^8.18.0" + }, + "devDependencies": { + "@electron-forge/cli": "^7.8.1", + "@electron-forge/maker-deb": "^7.8.1", + "@electron-forge/maker-dmg": "^7.8.1", + "@electron-forge/maker-rpm": "^7.8.1", + "@electron-forge/maker-squirrel": "^7.8.1", + "@electron-forge/maker-zip": "^7.8.1", + "@electron-forge/plugin-auto-unpack-natives": "^7.8.1", + "@electron-forge/plugin-fuses": "^7.8.1", + "@electron/fuses": "^1.8.0", + "@electron/notarize": "^2.5.0", + "electron": "^30.5.1", + "electron-builder": "^26.0.12", + "electron-reloader": "^1.2.3", + "esbuild": "^0.25.5" + }, + "optionalDependencies": { + "electron-liquid-glass": "^1.0.1" + } + }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.56.0.tgz", + "integrity": "sha512-SLCB8M8+VMg1cpCucnA1XWHGWqVSZtIWzmOdDOEu3eTFZMB+A0sGZ1ESO5MHDnqrNTXz3safMrWx9x4rMZSOqA==", + "license": "MIT", + "bin": { + "anthropic-ai-sdk": "bin/cli" + } + }, + "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-forge/cli": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-7.8.1.tgz", + "integrity": "sha512-QI3EShutfq9Y+2TWWrPjm4JZM3eSAKzoQvRZdVhAfVpUbyJ8K23VqJShg3kGKlPf9BXHAGvE+8LyH5s2yDr1qA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-cli?utm_medium=referral&utm_source=npm_fund" + } + ], + "license": "MIT", + "dependencies": { + "@electron-forge/core": "7.8.1", + "@electron-forge/core-utils": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "@electron/get": "^3.0.0", + "chalk": "^4.0.0", + "commander": "^11.1.0", + "debug": "^4.3.1", + "fs-extra": "^10.0.0", + "listr2": "^7.0.2", + "log-symbols": "^4.0.0", + "semver": "^7.2.1" + }, + "bin": { + "electron-forge": "dist/electron-forge.js", + "electron-forge-vscode-nix": "script/vscode.sh", + "electron-forge-vscode-win": "script/vscode.cmd" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/core": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-7.8.1.tgz", + "integrity": "sha512-jkh0QPW5p0zmruu1E8+2XNufc4UMxy13WLJcm7hn9jbaXKLkMbKuEvhrN1tH/9uGp1mhr/t8sC4N67gP+gS87w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-core?utm_medium=referral&utm_source=npm_fund" + } + ], + "license": "MIT", + "dependencies": { + "@electron-forge/core-utils": "7.8.1", + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/plugin-base": "7.8.1", + "@electron-forge/publisher-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "@electron-forge/template-base": "7.8.1", + "@electron-forge/template-vite": "7.8.1", + "@electron-forge/template-vite-typescript": "7.8.1", + "@electron-forge/template-webpack": "7.8.1", + "@electron-forge/template-webpack-typescript": "7.8.1", + "@electron-forge/tracer": "7.8.1", + "@electron/get": "^3.0.0", + "@electron/packager": "^18.3.5", + "@electron/rebuild": "^3.7.0", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.3.1", + "fast-glob": "^3.2.7", + "filenamify": "^4.1.0", + "find-up": "^5.0.0", + "fs-extra": "^10.0.0", + "global-dirs": "^3.0.0", + "got": "^11.8.5", + "interpret": "^3.1.1", + "jiti": "^2.4.2", + "listr2": "^7.0.2", + "lodash": "^4.17.20", + "log-symbols": "^4.0.0", + "node-fetch": "^2.6.7", + "rechoir": "^0.8.0", + "semver": "^7.2.1", + "source-map-support": "^0.5.13", + "sudo-prompt": "^9.1.1", + "username": "^5.1.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/core-utils": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/core-utils/-/core-utils-7.8.1.tgz", + "integrity": "sha512-mRoPLDNZgmjyOURE/K0D3Op53XGFmFRgfIvFC7c9S/BqsRpovVblrqI4XxPRdNmH9dvhd8On9gGz+XIYAKD3aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "@electron/rebuild": "^3.7.0", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.3.1", + "find-up": "^5.0.0", + "fs-extra": "^10.0.0", + "log-symbols": "^4.0.0", + "semver": "^7.2.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/maker-base": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-7.8.1.tgz", + "integrity": "sha512-GUZqschGuEBzSzE0bMeDip65IDds48DZXzldlRwQ+85SYVA6RMU2AwDDqx3YiYsvP2OuxKruuqIJZtOF5ps4FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "fs-extra": "^10.0.0", + "which": "^2.0.2" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/maker-deb": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-deb/-/maker-deb-7.8.1.tgz", + "integrity": "sha512-tjjeesQtCP5Xht1X7gl4+K9bwoETPmQfBkOVAY/FZIxPj40uQh/hOUtLX2tYENNGNVZ1ryDYRs8TuPi+I41Vfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + }, + "optionalDependencies": { + "electron-installer-debian": "^3.2.0" + } + }, + "node_modules/@electron-forge/maker-dmg": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-dmg/-/maker-dmg-7.8.1.tgz", + "integrity": "sha512-l449QvY2Teu+J9rHnjkTHEm/wOJ1LRfmrQ2QkGtFoTRcqvFWdUAEN8nK2/08w3j2h6tvOY3QSUjRzXrhJZRNRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + }, + "optionalDependencies": { + "electron-installer-dmg": "^5.0.1" + } + }, + "node_modules/@electron-forge/maker-rpm": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-rpm/-/maker-rpm-7.8.1.tgz", + "integrity": "sha512-TF6wylft3BHkw9zdHcxmjEPBZYgTIc0jE31skFnMEQ/aExbNRiNaCZvsXy+7ptTWZxhxUKRc9KHhLFRMCmOK8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + }, + "optionalDependencies": { + "electron-installer-redhat": "^3.2.0" + } + }, + "node_modules/@electron-forge/maker-squirrel": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-squirrel/-/maker-squirrel-7.8.1.tgz", + "integrity": "sha512-qT1PMvT7ALF0ONOkxlA0oc0PiFuKCAKgoMPoxYo9gGOqFvnAb+TBcnLxflQ4ashE/ZkrHpykr4LcDJxqythQTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + }, + "optionalDependencies": { + "electron-winstaller": "^5.3.0" + } + }, + "node_modules/@electron-forge/maker-zip": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-zip/-/maker-zip-7.8.1.tgz", + "integrity": "sha512-unIxEoV1lnK4BLVqCy3L2y897fTyg8nKY1WT4rrpv0MUKnQG4qmigDfST5zZNNHHaulEn/ElAic2GEiP7d6bhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/maker-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "cross-zip": "^4.0.0", + "fs-extra": "^10.0.0", + "got": "^11.8.5" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/plugin-auto-unpack-natives": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/plugin-auto-unpack-natives/-/plugin-auto-unpack-natives-7.8.1.tgz", + "integrity": "sha512-4URAgWX9qqqKe6Bfad0VmpFRrwINYMODfKGd2nFQrfHxmBtdpXnsWlLwVGE/wGssIQaTMI5bWQ6F2RNeXTgnhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/plugin-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/plugin-base": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/plugin-base/-/plugin-base-7.8.1.tgz", + "integrity": "sha512-iCZC2d7CbsZ9l6j5d+KPIiyQx0U1QBfWAbKnnQhWCSizjcrZ7A9V4sMFZeTO6+PVm48b/r9GFPm+slpgZtYQLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/plugin-fuses": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/plugin-fuses/-/plugin-fuses-7.8.1.tgz", + "integrity": "sha512-dYTwvbV1HcDOIQ0wTybpdtPq6YoBYXIWBTb7DJuvFu/c/thj1eoEdnbwr8mT9hEivjlu5p4ls46n16P5EtZ0oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/plugin-base": "7.8.1", + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + }, + "peerDependencies": { + "@electron/fuses": ">=1.0.0" + } + }, + "node_modules/@electron-forge/publisher-base": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/publisher-base/-/publisher-base-7.8.1.tgz", + "integrity": "sha512-z2C+C4pcFxyCXIFwXGDcxhU8qtVUPZa3sPL6tH5RuMxJi77768chLw2quDWk2/dfupcSELXcOMYCs7aLysCzeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/shared-types": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/shared-types/-/shared-types-7.8.1.tgz", + "integrity": "sha512-guLyGjIISKQQRWHX+ugmcjIOjn2q/BEzCo3ioJXFowxiFwmZw/oCZ2KlPig/t6dMqgUrHTH5W/F0WKu0EY4M+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/tracer": "7.8.1", + "@electron/packager": "^18.3.5", + "@electron/rebuild": "^3.7.0", + "listr2": "^7.0.2" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-base": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/template-base/-/template-base-7.8.1.tgz", + "integrity": "sha512-k8jEUr0zWFWb16ZGho+Es2OFeKkcbTgbC6mcH4eNyF/sumh/4XZMcwRtX1i7EiZAYiL9sVxyI6KVwGu254g+0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/core-utils": "7.8.1", + "@electron-forge/shared-types": "7.8.1", + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.3.1", + "fs-extra": "^10.0.0", + "username": "^5.1.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-vite": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/template-vite/-/template-vite-7.8.1.tgz", + "integrity": "sha512-qzSlJaBYYqQAbBdLk4DqAE3HCNz4yXbpkb+VC74ddL4JGwPdPU57DjCthr6YetKJ2FsOVy9ipovA8HX5UbXpAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "@electron-forge/template-base": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-vite-typescript": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/template-vite-typescript/-/template-vite-typescript-7.8.1.tgz", + "integrity": "sha512-CccQhwUjZcc6svzuOi3BtbDal591DzyX2J5GPa6mwVutDP8EMtqJL1VyOHdcWO/7XjI6GNAD0fiXySOJiUAECA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "@electron-forge/template-base": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-webpack": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-7.8.1.tgz", + "integrity": "sha512-DA77o9kTCHrq+W211pyNP49DyAt0d1mzMp2gisyNz7a+iKvlv2DsMAeRieLoCQ44akb/z8ZsL0YLteSjKLy4AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "@electron-forge/template-base": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-webpack-typescript": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-7.8.1.tgz", + "integrity": "sha512-h922E+6zWwym1RT6WKD79BLTc4H8YxEMJ7wPWkBX59kw/exsTB/KFdiJq6r82ON5jSJ+Q8sDGqSmDWdyCfo+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron-forge/shared-types": "7.8.1", + "@electron-forge/template-base": "7.8.1", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/tracer": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/@electron-forge/tracer/-/tracer-7.8.1.tgz", + "integrity": "sha512-r2i7aHVp2fylGQSPDw3aTcdNfVX9cpL1iL2MKHrCRNwgrfR+nryGYg434T745GGm1rNQIv5Egdkh5G9xf00oWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chrome-trace-event": "^1.0.3" + }, + "engines": { + "node": ">= 14.17.5" + } + }, + "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/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/@electron/fuses": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@electron/fuses/-/fuses-1.8.0.tgz", + "integrity": "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.1", + "fs-extra": "^9.0.1", + "minimist": "^1.2.5" + }, + "bin": { + "electron-fuses": "dist/bin.js" + } + }, + "node_modules/@electron/fuses/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/get": { + "version": "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/@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/@electron/get/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@electron/get/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@electron/node-gyp": { + "version": "10.2.0-electron.1", + "resolved": "git+ssh://git@github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "integrity": "sha512-CrYo6TntjpoMO1SHjl5Pa/JoUsECNqNdB7Kx49WLQpWzPw53eEITJ2Hs9fh/ryUYDn4pxZz11StaBYBrLFJdqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^8.1.0", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.2.1", + "nopt": "^6.0.0", + "proc-log": "^2.0.1", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@electron/node-gyp/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@electron/node-gyp/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@electron/node-gyp/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/notarize": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz", + "integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/notarize/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/osx-sign": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.3.tgz", + "integrity": "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@electron/packager": { + "version": "18.3.6", + "resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.3.6.tgz", + "integrity": "sha512-1eXHB5t+SQKvUiDpWGpvr90ZSSbXj+isrh3YbjCTjKT4bE4SQrKSBfukEAaBvp67+GXHFtCHjQgN9qSTFIge+Q==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@electron/asar": "^3.2.13", + "@electron/get": "^3.0.0", + "@electron/notarize": "^2.1.0", + "@electron/osx-sign": "^1.0.5", + "@electron/universal": "^2.0.1", + "@electron/windows-sign": "^1.0.0", + "debug": "^4.0.1", + "extract-zip": "^2.0.0", + "filenamify": "^4.1.0", + "fs-extra": "^11.1.0", + "galactus": "^1.0.0", + "get-package-info": "^1.0.0", + "junk": "^3.1.0", + "parse-author": "^2.0.0", + "plist": "^3.0.0", + "resedit": "^2.0.0", + "resolve": "^1.1.6", + "semver": "^7.1.3", + "yargs-parser": "^21.1.1" + }, + "bin": { + "electron-packager": "bin/electron-packager.js" + }, + "engines": { + "node": ">= 16.13.0" + }, + "funding": { + "url": "https://github.com/electron/packager?sponsor=1" + } + }, + "node_modules/@electron/packager/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/rebuild": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.2.tgz", + "integrity": "sha512-19/KbIR/DAxbsCkiaGMXIdPnMCJLkcf8AvGnduJtWBs/CBwiAjY1apCqOLVxrXg+rtXFCngbXhBanWjxLUt1Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@electron/universal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.3.tgz", + "integrity": "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@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/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@electron/windows-sign": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz", + "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==", + "dev": true, + "license": "BSD-2-Clause", + "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.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz", + "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz", + "integrity": "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.6.tgz", + "integrity": "sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.6.tgz", + "integrity": "sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.6.tgz", + "integrity": "sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.6.tgz", + "integrity": "sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.6.tgz", + "integrity": "sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.6.tgz", + "integrity": "sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.6.tgz", + "integrity": "sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.6.tgz", + "integrity": "sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.6.tgz", + "integrity": "sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.6.tgz", + "integrity": "sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.6.tgz", + "integrity": "sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.6.tgz", + "integrity": "sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.6.tgz", + "integrity": "sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.6.tgz", + "integrity": "sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.6.tgz", + "integrity": "sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.6.tgz", + "integrity": "sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.6.tgz", + "integrity": "sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.6.tgz", + "integrity": "sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.6.tgz", + "integrity": "sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.6.tgz", + "integrity": "sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.6.tgz", + "integrity": "sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.6.tgz", + "integrity": "sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.6.tgz", + "integrity": "sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.6.tgz", + "integrity": "sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.6.tgz", + "integrity": "sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fastify/busboy": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz", + "integrity": "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==", + "license": "MIT" + }, + "node_modules/@firebase/ai": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-1.4.1.tgz", + "integrity": "sha512-bcusQfA/tHjUjBTnMx6jdoPMpDl3r8K15Z+snHz9wq0Foox0F/V+kNLXucEOHoTL2hTc9l+onZCyBJs2QoIC3g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/analytics": { + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.17.tgz", + "integrity": "sha512-n5vfBbvzduMou/2cqsnKrIes4auaBjdhg8QNA2ZQZ59QgtO2QiwBaXQZQE4O4sgB0Ds1tvLgUUkY+pwzu6/xEg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.23.tgz", + "integrity": "sha512-3AdO10RN18G5AzREPoFgYhW6vWXr3u+OYQv6pl3CX6Fky8QRk0AHurZlY3Q1xkXO0TDxIsdhO3y65HF7PBOJDw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/analytics": "0.10.17", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.2.tgz", + "integrity": "sha512-jwtMmJa1BXXDCiDx1vC6SFN/+HfYG53UkfJa6qeN5ogvOunzbFDO3wISZy5n9xgYFUrEP6M7e8EG++riHNTv9w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.10.1.tgz", + "integrity": "sha512-MgNdlms9Qb0oSny87pwpjKush9qUwCJhfmTJHDfrcKo4neLGiSeVE4qJkzP7EQTIUFKp84pbTxobSAXkiuQVYQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.26.tgz", + "integrity": "sha512-PkX+XJMLDea6nmnopzFKlr+s2LMQGqdyT2DHdbx1v1dPSqOol2YzgpgymmhC67vitXVpNvS3m/AiWQWWhhRRPQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check": "0.10.1", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-compat": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.4.2.tgz", + "integrity": "sha512-LssbyKHlwLeiV8GBATyOyjmHcMpX/tFjzRUCS1jnwGAew1VsBB4fJowyS5Ud5LdFbYpJeS+IQoC+RQxpK7eH3Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app": "0.13.2", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth": { + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", + "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.5.28", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.28.tgz", + "integrity": "sha512-HpMSo/cc6Y8IX7bkRIaPPqT//Jt83iWy5rmDWeThXQCAImstkdNo3giFLORJwrZw2ptiGkOij64EH1ztNJzc7Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth": "1.10.8", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-types": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.18.tgz", + "integrity": "sha512-n28kPCkE2dL2U28fSxZJjzPPVpKsQminJ6NrzcKXAI0E/lYC8YhfwpyllScqVEvAI3J2QgJZWYgrX+1qGI+SQQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/data-connect": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.10.tgz", + "integrity": "sha512-VMVk7zxIkgwlVQIWHOKFahmleIjiVFwFOjmakXPd/LDgaB/5vzwsB5DWIYo+3KhGxWpidQlR8geCIn39YflJIQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/database": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.20.tgz", + "integrity": "sha512-H9Rpj1pQ1yc9+4HQOotFGLxqAXwOzCHsRSRjcQFNOr8lhUt6LeYjf0NSRL04sc4X0dWe8DsCvYKxMYvFG/iOJw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.11.tgz", + "integrity": "sha512-itEsHARSsYS95+udF/TtIzNeQ0Uhx4uIna0sk4E0wQJBUnLc/G1X6D7oRljoOuwwCezRLGvWBRyNrugv/esOEw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/database": "1.0.20", + "@firebase/database-types": "1.0.15", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.15.tgz", + "integrity": "sha512-XWHJ0VUJ0k2E9HDMlKxlgy/ZuTa9EvHCGLjaKSUvrQnwhgZuRU5N3yX6SZ+ftf2hTzZmfRkv+b3QRvGg40bKNw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.12.1" + } + }, + "node_modules/@firebase/firestore": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.8.0.tgz", + "integrity": "sha512-QSRk+Q1/CaabKyqn3C32KSFiOdZpSqI9rpLK5BHPcooElumOBooPFa6YkDdiT+/KhJtel36LdAacha9BptMj2A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "@firebase/webchannel-wrapper": "1.0.3", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.3.53", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.53.tgz", + "integrity": "sha512-qI3yZL8ljwAYWrTousWYbemay2YZa+udLWugjdjju2KODWtLG94DfO4NALJgPLv8CVGcDHNFXoyQexdRA0Cz8Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/firestore": "4.8.0", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.12.9", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.9.tgz", + "integrity": "sha512-FG95w6vjbUXN84Ehezc2SDjGmGq225UYbHrb/ptkRT7OTuCiQRErOQuyt1jI1tvcDekdNog+anIObihNFz79Lg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.26.tgz", + "integrity": "sha512-A798/6ff5LcG2LTWqaGazbFYnjBW8zc65YfID/en83ALmkhu2b0G8ykvQnLtakbV9ajrMYPn7Yc/XcYsZIUsjA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/functions": "0.12.9", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/installations": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.18.tgz", + "integrity": "sha512-NQ86uGAcvO8nBRwVltRL9QQ4Reidc/3whdAasgeWCPIcrhOKDuNpAALa6eCVryLnK14ua2DqekCOX5uC9XbU/A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.18.tgz", + "integrity": "sha512-aLFohRpJO5kKBL/XYL4tN+GdwEB/Q6Vo9eZOM/6Kic7asSUgmSfGPpGUZO1OAaSRGwF4Lqnvi1f/f9VZnKzChw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.12.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.22.tgz", + "integrity": "sha512-GJcrPLc+Hu7nk+XQ70Okt3M1u1eRr2ZvpMbzbc54oTPJZySHcX9ccZGVFcsZbSZ6o1uqumm8Oc7OFkD3Rn1/og==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.22.tgz", + "integrity": "sha512-5ZHtRnj6YO6f/QPa/KU6gryjmX4Kg33Kn4gRpNU6M1K47Gm8kcQwPkX7erRUYEH1mIWptfvjvXMHWoZaWjkU7A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/messaging": "0.12.22", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/performance": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.7.tgz", + "integrity": "sha512-JTlTQNZKAd4+Q5sodpw6CN+6NmwbY72av3Lb6wUKTsL7rb3cuBIhQSrslWbVz0SwK3x0ZNcqX24qtRbwKiv+6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.20", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.20.tgz", + "integrity": "sha512-XkFK5NmOKCBuqOKWeRgBUFZZGz9SzdTZp4OqeUg+5nyjapTiZ4XoiiUL8z7mB2q+63rPmBl7msv682J3rcDXIQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/performance": "0.7.7", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/remote-config": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.5.tgz", + "integrity": "sha512-fU0c8HY0vrVHwC+zQ/fpXSqHyDMuuuglV94VF6Yonhz8Fg2J+KOowPGANM0SZkLvVOYpTeWp3ZmM+F6NjwWLnw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.18.tgz", + "integrity": "sha512-YiETpldhDy7zUrnS8e+3l7cNs0sL7+tVAxvVYU0lu7O+qLHbmdtAxmgY+wJqWdW2c9nDvBFec7QiF58pEUu0qQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/remote-config": "0.6.5", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/storage": { + "version": "0.13.14", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.14.tgz", + "integrity": "sha512-xTq5ixxORzx+bfqCpsh+o3fxOsGoDjC1nO0Mq2+KsOcny3l7beyBhP/y1u5T6mgsFQwI1j6oAkbT5cWdDBx87g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.24.tgz", + "integrity": "sha512-XHn2tLniiP7BFKJaPZ0P8YQXKiVJX+bMyE2j2YWjYfaddqiJnROJYqSomwW6L3Y+gZAga35ONXUJQju6MB6SOQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/storage": "0.13.14", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.1.tgz", + "integrity": "sha512-zGlBn/9Dnya5ta9bX/fgEoNC3Cp8s6h+uYPYaDieZsFOAdHP/ExzQ/eaDgxD3GOROdPkLKpvKY0iIzr9adle0w==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", + "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==", + "license": "Apache-2.0" + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@google-cloud/firestore": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.2.tgz", + "integrity": "sha512-BQCSbjWJndCZ6bj8BSGhi4EM1TDFs9HgZXXsJ7d2kEPo+x64fB3OnQE8ffmn3vWADqeAmYBPaMPF/k6PHETXKA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@opentelemetry/api": "^1.3.0", + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^4.3.3", + "protobufjs": "^7.2.6" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", + "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.16.0.tgz", + "integrity": "sha512-7/5LRgykyOfQENcm6hDKP8SX/u9XxE5YOiWOkgkwcoO+cG8xT/cyOvp9wwN3IxfdYgpHs8CE7Nq2PKX2lNaEXw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "<4.1.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "duplexify": "^4.1.3", + "fast-xml-parser": "^4.4.1", + "gaxios": "^6.0.2", + "google-auth-library": "^9.6.3", + "html-entities": "^2.5.2", + "mime": "^3.0.0", + "p-limit": "^3.0.1", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@google-cloud/storage/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@google/genai": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.8.0.tgz", + "integrity": "sha512-n3KiMFesQCy2R9iSdBIuJ0JWYQ1HZBJJkmt4PPZMGZKvlgHhBAGw1kUMyX+vsAIzprN3lK45DI755lm70wPOOg==", + "license": "Apache-2.0", + "dependencies": { + "google-auth-library": "^9.14.2", + "ws": "^8.18.0", + "zod": "^3.22.4", + "zod-to-json-schema": "^3.22.4" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.11.0" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@google/generative-ai": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz", + "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz", + "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz", + "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", + "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", + "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", + "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", + "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", + "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", + "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", + "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", + "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", + "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.2.tgz", + "integrity": "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.2.tgz", + "integrity": "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.2.tgz", + "integrity": "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.2.tgz", + "integrity": "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.2.tgz", + "integrity": "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.2.tgz", + "integrity": "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.2.tgz", + "integrity": "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.4.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.2.tgz", + "integrity": "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.2.tgz", + "integrity": "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.2.tgz", + "integrity": "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "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/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "license": "BSD-3-Clause" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/appdmg": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@types/appdmg/-/appdmg-0.5.5.tgz", + "integrity": "sha512-G+n6DgZTZFOteITE30LnWj+HRVIGr7wMlAiLWOO02uJFWVEitaPU9JVXm9wJokkgshBawb2O1OykdcsmkkZfgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.10", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", + "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", + "license": "MIT", + "dependencies": { + "@types/ms": "*", + "@types/node": "*" + } + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.4.tgz", + "integrity": "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.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/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/request/node_modules/form-data": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.3.tgz", + "integrity": "sha512-XHIrMD0NpDrNM/Ckf7XJiBbLl57KEhT3+i3yY+eWm+cqYZJQTZrKo8Y8AWKnuV5GT4scfuUGt9LzNoIx3dU1nQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.35", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/verror": { + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", + "integrity": "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "dev": true, + "license": "MIT", + "engines": { + "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": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "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": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "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-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/app-builder-bin": { + "version": "5.0.0-alpha.12", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz", + "integrity": "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/app-builder-lib": { + "version": "26.0.12", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.0.12.tgz", + "integrity": "sha512-+/CEPH1fVKf6HowBUs6LcAIoRcjeqgvAeoSE+cl7Y7LndyQ9ViGPYibNk7wmhMHzNgHIuIbw4nWADPO+4mjgWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@develar/schema-utils": "~2.6.5", + "@electron/asar": "3.2.18", + "@electron/fuses": "^1.8.0", + "@electron/notarize": "2.5.0", + "@electron/osx-sign": "1.3.1", + "@electron/rebuild": "3.7.0", + "@electron/universal": "2.0.1", + "@malept/flatpak-bundler": "^0.4.0", + "@types/fs-extra": "9.0.13", + "async-exit-hook": "^2.0.1", + "builder-util": "26.0.11", + "builder-util-runtime": "9.3.1", + "chromium-pickle-js": "^0.2.0", + "config-file-ts": "0.2.8-rc1", + "debug": "^4.3.4", + "dotenv": "^16.4.5", + "dotenv-expand": "^11.0.6", + "ejs": "^3.1.8", + "electron-publish": "26.0.11", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", + "is-ci": "^3.0.0", + "isbinaryfile": "^5.0.0", + "js-yaml": "^4.1.0", + "json5": "^2.2.3", + "lazy-val": "^1.0.5", + "minimatch": "^10.0.0", + "plist": "3.1.0", + "resedit": "^1.7.0", + "semver": "^7.3.8", + "tar": "^6.1.12", + "temp-file": "^3.4.0", + "tiny-async-pool": "1.3.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "dmg-builder": "26.0.12", + "electron-builder-squirrel-windows": "26.0.12" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/asar": { + "version": "3.2.18", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.18.tgz", + "integrity": "sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/asar/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/osx-sign": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.1.tgz", + "integrity": "sha512-BAfviURMHpmb1Yb50YbCxnOY0wfwaLXH5KJ4+80zS0gUkzDX3ec23naTlEqKsN+PwYn+a1cCzM7BJ4Wcd3sGzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "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/app-builder-lib/node_modules/@electron/osx-sign/node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/rebuild": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.0.tgz", + "integrity": "sha512-VW++CNSlZwMYP7MyXEbrKjpzEwhB5kDNbzGtiPEjwYysqyTCF+YbNJ210Dj3AjWsGSV4iEEwNkmJN9yGZmVvmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/universal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz", + "integrity": "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/asar": "^3.2.7", + "@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/app-builder-lib/node_modules/@electron/universal/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/app-builder-lib/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/app-builder-lib/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/app-builder-lib/node_modules/isbinaryfile": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.4.tgz", + "integrity": "sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/app-builder-lib/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/app-builder-lib/node_modules/pe-library": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz", + "integrity": "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/app-builder-lib/node_modules/resedit": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/resedit/-/resedit-1.7.2.tgz", + "integrity": "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pe-library": "^0.4.1" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/appdmg": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/appdmg/-/appdmg-0.6.6.tgz", + "integrity": "sha512-GRmFKlCG+PWbcYF4LUNonTYmy0GjguDy6Jh9WP8mpd0T6j80XIJyXBiWlD0U+MLNhqV9Nhx49Gl9GpVToulpLg==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "async": "^1.4.2", + "ds-store": "^0.1.5", + "execa": "^1.0.0", + "fs-temp": "^1.0.0", + "fs-xattr": "^0.3.0", + "image-size": "^0.7.4", + "is-my-json-valid": "^2.20.0", + "minimist": "^1.1.3", + "parse-color": "^1.0.0", + "path-exists": "^4.0.0", + "repeat-string": "^1.5.4" + }, + "bin": { + "appdmg": "bin/appdmg.js" + }, + "engines": { + "node": ">=8.5" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "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": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "license": "MIT", + "optional": true, + "dependencies": { + "retry": "0.13.1" + } + }, + "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": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", + "license": "MIT", + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/author-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", + "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/axios": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base32-encode": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/base32-encode/-/base32-encode-1.2.0.tgz", + "integrity": "sha512-cHFU8XeRyx0GgmoWi5qHMCVRiqU6J3MHWxVgun7jggCBUpVzm1Ir7M9dYr2whjSNc3tFeXfQ/oZjQu/4u55h9A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "to-data-view": "^1.1.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/better-sqlite3": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.6.0.tgz", + "integrity": "sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + } + }, + "node_modules/bignumber.js": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.0.tgz", + "integrity": "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/bplist-creator": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", + "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "stream-buffers": "~2.2.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/builder-util": { + "version": "26.0.11", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.0.11.tgz", + "integrity": "sha512-xNjXfsldUEe153h1DraD0XvDOpqGR0L5eKFkdReB7eFW5HqysDZFfly4rckda6y9dF39N3pkPlOblcfHKGw+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/debug": "^4.1.6", + "7zip-bin": "~5.2.0", + "app-builder-bin": "5.0.0-alpha.12", + "builder-util-runtime": "9.3.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", + "is-ci": "^3.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.3.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.3.1.tgz", + "integrity": "sha512-2/egrNDDnRaxVwK3A+cJq6UOlqOdedGA7JPqCeJjN2Zjk1/QB/6QUi3b714ScIGS7HafFXTyzJEOr5b44I3kvQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "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": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", + "license": "MIT", + "dependencies": { + "ajv": "^8.6.3", + "ajv-formats": "^2.1.1", + "atomically": "^1.7.0", + "debounce-fn": "^4.0.0", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", + "json-schema-typed": "^7.0.3", + "onetime": "^5.1.2", + "pkg-up": "^3.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conf/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "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/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/config-file-ts": { + "version": "0.2.8-rc1", + "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.8-rc1.tgz", + "integrity": "sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^10.3.12", + "typescript": "^5.4.3" + } + }, + "node_modules/config-file-ts/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/config-file-ts/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/config-file-ts/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/config-file-ts/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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" + }, + "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-zip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-4.0.1.tgz", + "integrity": "sha512-n63i0lZ0rvQ6FXiGQ+/JFCKAUyPFhLQYJIqKaa+tSJtfKeULF/IDNDAbdnSIxgS4NTuw2b0+lj8LzfITuq+ZxQ==", + "dev": true, + "funding": [ + { + "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", + "engines": { + "node": ">=12.10" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/date-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", + "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "time-zone": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/debounce-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/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-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/dir-compare": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz", + "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5", + "p-limit": "^3.1.0 " + } + }, + "node_modules/dmg-builder": { + "version": "26.0.12", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.0.12.tgz", + "integrity": "sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "26.0.12", + "builder-util": "26.0.11", + "builder-util-runtime": "9.3.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-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/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotenv": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.0.1.tgz", + "integrity": "sha512-GLjkduuAL7IMJg/ZnOPm9AnWKJ82mSE2tzXLaJ/6hD6DhwGfZaXG77oB8qbReyiczNxnbxQKyh0OE5mXq0bAHA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "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/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/ds-store": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ds-store/-/ds-store-0.1.6.tgz", + "integrity": "sha512-kY21M6Lz+76OS3bnCzjdsJSF7LBpLYGCVfavW8TgQD2XkcqIZ86W0y9qUDZu6fp7SIZzqosMDW2zi7zVFfv4hw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bplist-creator": "~0.0.3", + "macos-alias": "~0.2.5", + "tn1150": "^0.1.0" + } + }, + "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/duplexify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-30.5.1.tgz", + "integrity": "sha512-AhL7+mZ8Lg14iaNfoYTkXQ2qee8mmsQyllKdqxlpv/zrKgfxz6jNVtcRRbQtLxtF8yzcImWdfTQROpYiPumdbw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, + "node_modules/electron-builder": { + "version": "26.0.12", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.0.12.tgz", + "integrity": "sha512-cD1kz5g2sgPTMFHjLxfMjUK5JABq3//J4jPswi93tOPFz6btzXYtK5NrDt717NRbukCUDOrrvmYVOWERlqoiXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "26.0.12", + "builder-util": "26.0.11", + "builder-util-runtime": "9.3.1", + "chalk": "^4.1.2", + "dmg-builder": "26.0.12", + "fs-extra": "^10.1.0", + "is-ci": "^3.0.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.0.12", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.0.12.tgz", + "integrity": "sha512-kpwXM7c/ayRUbYVErQbsZ0nQZX4aLHQrPEG9C4h9vuJCXylwFH8a7Jgi2VpKIObzCXO7LKHiCw4KdioFLFOgqA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "app-builder-lib": "26.0.12", + "builder-util": "26.0.11", + "electron-winstaller": "5.4.0" + } + }, + "node_modules/electron-installer-common": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/electron-installer-common/-/electron-installer-common-0.10.4.tgz", + "integrity": "sha512-8gMNPXfAqUE5CfXg8RL0vXpLE9HAaPkgLXVoHE3BMUzogMWenf4LmwQ27BdCUrEhkjrKl+igs2IHJibclR3z3Q==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@electron/asar": "^3.2.5", + "@malept/cross-spawn-promise": "^1.0.0", + "debug": "^4.1.1", + "fs-extra": "^9.0.0", + "glob": "^7.1.4", + "lodash": "^4.17.15", + "parse-author": "^2.0.0", + "semver": "^7.1.1", + "tmp-promise": "^3.0.2" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "url": "https://github.com/electron-userland/electron-installer-common?sponsor=1" + }, + "optionalDependencies": { + "@types/fs-extra": "^9.0.1" + } + }, + "node_modules/electron-installer-common/node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "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", + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/electron-installer-common/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "optional": true, + "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-installer-debian": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/electron-installer-debian/-/electron-installer-debian-3.2.0.tgz", + "integrity": "sha512-58ZrlJ1HQY80VucsEIG9tQ//HrTlG6sfofA3nRGr6TmkX661uJyu4cMPPh6kXW+aHdq/7+q25KyQhDrXvRL7jw==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin", + "linux" + ], + "dependencies": { + "@malept/cross-spawn-promise": "^1.0.0", + "debug": "^4.1.1", + "electron-installer-common": "^0.10.2", + "fs-extra": "^9.0.0", + "get-folder-size": "^2.0.1", + "lodash": "^4.17.4", + "word-wrap": "^1.2.3", + "yargs": "^16.0.2" + }, + "bin": { + "electron-installer-debian": "src/cli.js" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-installer-debian/node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "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", + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/electron-installer-debian/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-installer-debian/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/electron-installer-debian/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "optional": true, + "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-installer-debian/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-installer-debian/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "optional": true, + "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/electron-installer-debian/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-installer-debian/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-installer-dmg": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/electron-installer-dmg/-/electron-installer-dmg-5.0.1.tgz", + "integrity": "sha512-qOa1aAQdX57C+vzhDk3549dd/PRlNL4F8y736MTD1a43qptD+PvHY97Bo9gSf+OZ8iUWE7BrYSpk/FgLUe40EA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@types/appdmg": "^0.5.5", + "debug": "^4.3.2", + "minimist": "^1.2.7" + }, + "bin": { + "electron-installer-dmg": "dist/electron-installer-dmg-bin.js" + }, + "engines": { + "node": ">= 16" + }, + "optionalDependencies": { + "appdmg": "^0.6.4" + } + }, + "node_modules/electron-installer-redhat": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/electron-installer-redhat/-/electron-installer-redhat-3.4.0.tgz", + "integrity": "sha512-gEISr3U32Sgtj+fjxUAlSDo3wyGGq6OBx7rF5UdpIgbnpUvMN4W5uYb0ThpnAZ42VEJh/3aODQXHbFS4f5J3Iw==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin", + "linux" + ], + "dependencies": { + "@malept/cross-spawn-promise": "^1.0.0", + "debug": "^4.1.1", + "electron-installer-common": "^0.10.2", + "fs-extra": "^9.0.0", + "lodash": "^4.17.15", + "word-wrap": "^1.2.3", + "yargs": "^16.0.2" + }, + "bin": { + "electron-installer-redhat": "src/cli.js" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-installer-redhat/node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "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", + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/electron-installer-redhat/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-installer-redhat/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/electron-installer-redhat/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "optional": true, + "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-installer-redhat/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-installer-redhat/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "optional": true, + "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/electron-installer-redhat/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-installer-redhat/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-is-dev": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz", + "integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-liquid-glass": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/electron-liquid-glass/-/electron-liquid-glass-1.0.1.tgz", + "integrity": "sha512-XznNF0uDOmwvIQFGfgZM6PiQbrpXJiG4GYN6VnLzUrZwcOsQUGy51cJ5mPZCfwH+ST/ahorhLzwFEr+hsKRHXw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "node-addon-api": "^8.4.0" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "node-gyp-build": "^4" + } + }, + "node_modules/electron-publish": { + "version": "26.0.11", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.0.11.tgz", + "integrity": "sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^9.0.11", + "builder-util": "26.0.11", + "builder-util-runtime": "9.3.1", + "chalk": "^4.1.2", + "form-data": "^4.0.0", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "mime": "^2.5.2" + } + }, + "node_modules/electron-reloader": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/electron-reloader/-/electron-reloader-1.2.3.tgz", + "integrity": "sha512-aDnACAzNg0QvQhzw7LYOx/nVS10mEtbuG6M0QQvNQcLnJEwFs6is+EGRCnM+KQlQ4KcTbdwnt07nd7ZjHpY4iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "chokidar": "^3.5.0", + "date-time": "^3.1.0", + "electron-is-dev": "^1.2.0", + "find-up": "^5.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-squirrel-startup": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/electron-squirrel-startup/-/electron-squirrel-startup-1.0.1.tgz", + "integrity": "sha512-sTfFIHGku+7PsHLJ7v0dRcZNkALrV+YEozINTW8X1nM//e5O3L+rfYuvSW00lmGHnYmUjARZulD8F2V8ISI9RA==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^2.2.0" + } + }, + "node_modules/electron-squirrel-startup/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/electron-squirrel-startup/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/electron-store": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.2.0.tgz", + "integrity": "sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw==", + "license": "MIT", + "dependencies": { + "conf": "^10.2.0", + "type-fest": "^2.17.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-updater": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.6.2.tgz", + "integrity": "sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw==", + "license": "MIT", + "dependencies": { + "builder-util-runtime": "9.3.1", + "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.6.3", + "tiny-typed-emitter": "^2.1.0" + } + }, + "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", + "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", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/electron-winstaller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-winstaller/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/electron/node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "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/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/electron/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/electron/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/encode-utf8": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "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/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/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "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-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/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/esbuild": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz", + "integrity": "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.6", + "@esbuild/android-arm": "0.25.6", + "@esbuild/android-arm64": "0.25.6", + "@esbuild/android-x64": "0.25.6", + "@esbuild/darwin-arm64": "0.25.6", + "@esbuild/darwin-x64": "0.25.6", + "@esbuild/freebsd-arm64": "0.25.6", + "@esbuild/freebsd-x64": "0.25.6", + "@esbuild/linux-arm": "0.25.6", + "@esbuild/linux-arm64": "0.25.6", + "@esbuild/linux-ia32": "0.25.6", + "@esbuild/linux-loong64": "0.25.6", + "@esbuild/linux-mips64el": "0.25.6", + "@esbuild/linux-ppc64": "0.25.6", + "@esbuild/linux-riscv64": "0.25.6", + "@esbuild/linux-s390x": "0.25.6", + "@esbuild/linux-x64": "0.25.6", + "@esbuild/netbsd-arm64": "0.25.6", + "@esbuild/netbsd-x64": "0.25.6", + "@esbuild/openbsd-arm64": "0.25.6", + "@esbuild/openbsd-x64": "0.25.6", + "@esbuild/openharmony-arm64": "0.25.6", + "@esbuild/sunos-x64": "0.25.6", + "@esbuild/win32-arm64": "0.25.6", + "@esbuild/win32-ia32": "0.25.6", + "@esbuild/win32-x64": "0.25.6" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", + "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/farmhash-modern": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", + "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-xml-parser": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "strnum": "^1.1.1" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/firebase": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.10.0.tgz", + "integrity": "sha512-nKBXoDzF0DrXTBQJlZa+sbC5By99ysYU1D6PkMRYknm0nCW7rJly47q492Ht7Ndz5MeYSBuboKuhS1e6mFC03w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/ai": "1.4.1", + "@firebase/analytics": "0.10.17", + "@firebase/analytics-compat": "0.2.23", + "@firebase/app": "0.13.2", + "@firebase/app-check": "0.10.1", + "@firebase/app-check-compat": "0.3.26", + "@firebase/app-compat": "0.4.2", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.10.8", + "@firebase/auth-compat": "0.5.28", + "@firebase/data-connect": "0.3.10", + "@firebase/database": "1.0.20", + "@firebase/database-compat": "2.0.11", + "@firebase/firestore": "4.8.0", + "@firebase/firestore-compat": "0.3.53", + "@firebase/functions": "0.12.9", + "@firebase/functions-compat": "0.3.26", + "@firebase/installations": "0.6.18", + "@firebase/installations-compat": "0.2.18", + "@firebase/messaging": "0.12.22", + "@firebase/messaging-compat": "0.2.22", + "@firebase/performance": "0.7.7", + "@firebase/performance-compat": "0.2.20", + "@firebase/remote-config": "0.6.5", + "@firebase/remote-config-compat": "0.2.18", + "@firebase/storage": "0.13.14", + "@firebase/storage-compat": "0.3.24", + "@firebase/util": "1.12.1" + } + }, + "node_modules/firebase-admin": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.4.0.tgz", + "integrity": "sha512-Y8DcyKK+4pl4B93ooiy1G8qvdyRMkcNFfBSh+8rbVcw4cW8dgG0VXCCTp5NUwub8sn9vSPsOwpb9tE2OuFmcfQ==", + "license": "Apache-2.0", + "dependencies": { + "@fastify/busboy": "^3.0.0", + "@firebase/database-compat": "^2.0.0", + "@firebase/database-types": "^1.0.6", + "@types/node": "^22.8.7", + "farmhash-modern": "^1.1.0", + "google-auth-library": "^9.14.2", + "jsonwebtoken": "^9.0.0", + "jwks-rsa": "^3.1.0", + "node-forge": "^1.3.1", + "uuid": "^11.0.2" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^7.11.0", + "@google-cloud/storage": "^7.14.0" + } + }, + "node_modules/firebase-admin/node_modules/@types/node": { + "version": "22.16.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.0.tgz", + "integrity": "sha512-B2egV9wALML1JCpv3VQoQ+yesQKAmNMBIAY7OteVrikcOcAkWm+dGL6qpeCktPjAv6N1JLnhbNiqS35UpFyBsQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/flora-colossus": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-2.0.0.tgz", + "integrity": "sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/fmix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", + "integrity": "sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "imul": "^1.0.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "license": "MIT" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "license": "MIT", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-temp": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-1.2.1.tgz", + "integrity": "sha512-okTwLB7/Qsq82G6iN5zZJFsOfZtx2/pqrA7Hk/9fvy+c+eJS9CvgGXT2uNxwnI14BDY9L/jQPkaBgSvlKfSW9w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "random-path": "^0.1.0" + } + }, + "node_modules/fs-xattr": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/fs-xattr/-/fs-xattr-0.3.1.tgz", + "integrity": "sha512-UVqkrEW0GfDabw4C3HOrFlxKfx0eeigfRne69FxSBdHIP8Qt5Sq6Pu3RM9KmMlkygtC4pPKkj5CiPO5USnj2GA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "!win32" + ], + "engines": { + "node": ">=8.6.0" + } + }, + "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/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "license": "MIT", + "optional": true + }, + "node_modules/galactus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/galactus/-/galactus-1.0.0.tgz", + "integrity": "sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "flora-colossus": "^2.0.0", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/gar": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/gar/-/gar-1.0.4.tgz", + "integrity": "sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gaxios/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-property": "^1.0.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==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-folder-size": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-2.0.1.tgz", + "integrity": "sha512-+CEb+GDCM7tkOS2wdMKTn9vU7DgnKUTuDlehkNJKNSovdCOVxs14OfKCk4cvSaR3za4gj+OBdl9opPN9xrJ0zA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "gar": "^1.0.4", + "tiny-each-async": "2.0.3" + }, + "bin": { + "get-folder-size": "bin/get-folder-size" + } + }, + "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-package-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", + "integrity": "sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.1.1", + "debug": "^2.2.0", + "lodash.get": "^4.0.0", + "read-pkg-up": "^2.0.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/get-package-info/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/get-package-info/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "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": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "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-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/goober": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", + "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", + "license": "MIT", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, + "node_modules/google-auth-library": { + "version": "9.15.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", + "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.6.1.tgz", + "integrity": "sha512-V6eky/xz2mcKfAd1Ioxyd6nmA61gao3n01C+YeuIwu3vzM9EDR6wcVzMSIbLMDXWeoi9SHYctXuKYC5uJUT3eQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "^1.10.9", + "@grpc/proto-loader": "^0.7.13", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.3.0", + "node-fetch": "^2.7.0", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.2", + "protobufjs": "^7.3.2", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax/node_modules/@grpc/grpc-js": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.4.tgz", + "integrity": "sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/google-gax/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "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.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/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/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "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-corefoundation/node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/image-size": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz", + "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/imul": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", + "integrity": "sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true, + "license": "ISC" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-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-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-my-ip-valid": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz", + "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/is-my-json-valid": { + "version": "2.20.6", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", + "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^5.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==", + "license": "BSD-2-Clause" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", + "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", + "license": "MIT", + "dependencies": { + "@types/express": "^4.17.20", + "@types/jsonwebtoken": "^9.0.4", + "debug": "^4.3.4", + "jose": "^4.15.4", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lazy-val": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", + "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", + "license": "MIT" + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "node_modules/listr2": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz", + "integrity": "sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^5.0.1", + "rfdc": "^1.3.0", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "license": "MIT" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", + "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^5.0.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^5.0.0", + "strip-ansi": "^7.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", + "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", + "license": "MIT", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "6.0.0" + } + }, + "node_modules/macos-alias": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/macos-alias/-/macos-alias-0.2.12.tgz", + "integrity": "sha512-yiLHa7cfJcGRFq4FrR4tMlpNHb4Vy4mWnpajlSSIFM5k4Lv8/7BbbDLzCAVogWNl0LlLhizRp1drXv0hK9h0Yw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "nan": "^2.4.0" + } + }, + "node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "license": "MIT", + "optional": true, + "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/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mem/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "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-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/murmur-32": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/murmur-32/-/murmur-32-0.2.0.tgz", + "integrity": "sha512-ZkcWZudylwF+ir3Ld1n7gL6bI2mQAzXvSobPwVtu8aYi2sbXeipeSkdcanRLzIofLcM5F53lGaKm2dk7orBi7Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "encode-utf8": "^1.0.3", + "fmix": "^0.1.0", + "imul": "^1.0.0" + } + }, + "node_modules/nan": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", + "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-abi": { + "version": "3.75.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", + "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz", + "integrity": "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^18 || ^20 || >= 21" + } + }, + "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-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/openai": { + "version": "4.104.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz", + "integrity": "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.23.8" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/openai/node_modules/@types/node": { + "version": "18.19.115", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.115.tgz", + "integrity": "sha512-kNrFiTgG4a9JAn1LMQeLOv3MvXIPokzXziohMrMsvpYgLpdEt/mMiVYc4sGKtDfyxM5gIDF4VgrPRyCw4fHOYg==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/openai/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "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/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-author": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", + "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "author-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-color": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", + "integrity": "sha512-fuDHYgFHJGbpGMgw9skY/bj3HL/Jrn4l/5rSspy00DoT4RyLnDcRvPxdZ+r6OFwIsgAuhDh4I09tAId4mI12bw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "~0.5.0" + } + }, + "node_modules/parse-color/node_modules/color-convert": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", + "integrity": "sha512-RwBeO/B/vZR3dfKL1ye/vx8MHZ40ugzpyfeVG5GsiuGnrlMWe2o8wxBbLCpw9CsxV+wHuzYlCiWnybrIA0ling==", + "dev": true, + "optional": true + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "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/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pe-library": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-1.0.1.tgz", + "integrity": "sha512-nh39Mo1eGWmZS7y+mK/dQIqg7S1lp38DpRxkyoHf0ZcUs/HDc+yyTjuOtTvSMZHmfSLuSQaX945u05Y2Q6UWZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14", + "npm": ">=7" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/postject": { + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", + "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", + "dev": true, + "license": "MIT", + "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", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proc-log": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", + "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/proto3-json-serializer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", + "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/protobufjs": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", + "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "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/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "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/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/random-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/random-path/-/random-path-0.1.2.tgz", + "integrity": "sha512-4jY0yoEaQ5v9StCl5kZbNIQlg1QheIDBrdkDn53EynpPb9FgO6//p3X/tgMnrC45XN6QZCzU1Xz/+pSSsJBpRw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "base32-encode": "^0.1.0 || ^1.0.0", + "murmur-32": "^0.1.0 || ^0.2.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/react-hot-toast": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.2.tgz", + "integrity": "sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.3", + "goober": "^2.1.16" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "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/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-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": "2.0.3", + "resolved": "https://registry.npmjs.org/resedit/-/resedit-2.0.3.tgz", + "integrity": "sha512-oTeemxwoMuxxTYxXUwjkrOPfngTQehlv0/HoYFNkB4uzsP1Un1A9nI8JQKGOFkxpqkC7qkMs0lUsGrvUlbLNUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pe-library": "^1.0.1" + }, + "engines": { + "node": ">=14", + "npm": ">=7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/request": "^2.48.8", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "dev": true, + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT", + "peer": true + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", + "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.4", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.2", + "@img/sharp-darwin-x64": "0.34.2", + "@img/sharp-libvips-darwin-arm64": "1.1.0", + "@img/sharp-libvips-darwin-x64": "1.1.0", + "@img/sharp-libvips-linux-arm": "1.1.0", + "@img/sharp-libvips-linux-arm64": "1.1.0", + "@img/sharp-libvips-linux-ppc64": "1.1.0", + "@img/sharp-libvips-linux-s390x": "1.1.0", + "@img/sharp-libvips-linux-x64": "1.1.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", + "@img/sharp-libvips-linuxmusl-x64": "1.1.0", + "@img/sharp-linux-arm": "0.34.2", + "@img/sharp-linux-arm64": "0.34.2", + "@img/sharp-linux-s390x": "0.34.2", + "@img/sharp-linux-x64": "0.34.2", + "@img/sharp-linuxmusl-arm64": "0.34.2", + "@img/sharp-linuxmusl-x64": "0.34.2", + "@img/sharp-wasm32": "0.34.2", + "@img/sharp-win32-arm64": "0.34.2", + "@img/sharp-win32-ia32": "0.34.2", + "@img/sharp-win32-x64": "0.34.2" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "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/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "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", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", + "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.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-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/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "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/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", + "dev": true, + "license": "Unlicense", + "optional": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "license": "MIT", + "optional": true, + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT", + "optional": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "license": "MIT", + "optional": true + }, + "node_modules/sudo-prompt": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", + "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT" + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "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/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", + "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/teeny-request": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.9", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/teeny-request/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/teeny-request/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/teeny-request/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/teeny-request/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "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/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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-each-async": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tiny-each-async/-/tiny-each-async-2.0.3.tgz", + "integrity": "sha512-5ROII7nElnAirvFn8g7H7MtpfV1daMcyfTGQwsn/x2VtyV+VPiO5CjReCJtWLvoKTDEDmZocf3cNPraiMnBXLA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/tiny-typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", + "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==", + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "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/tn1150": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tn1150/-/tn1150-0.1.0.tgz", + "integrity": "sha512-DbplOfQFkqG5IHcDyyrs/lkvSr3mPUVsFf/RbDppOshs22yTPnSJWEe6FkYd1txAwU/zcnR905ar2fi4kwF29w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "unorm": "^1.4.1" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/to-data-view": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", + "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.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/unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", + "dev": true, + "license": "MIT or GPL-2.0", + "optional": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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/username": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz", + "integrity": "sha512-PCKbdWw85JsYMvmCv5GH3kXmM66rCd9m1hBEDutPNv94b/pqCMT4NtcKyeWYvLFiE8b+ha1Jdl8XAaUdPn5QTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^1.0.0", + "mem": "^4.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validator": { + "version": "13.15.15", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz", + "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.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/wait-on": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.3.tgz", + "integrity": "sha512-nQFqAFzZDeRxsu7S3C7LbuxslHhk+gnJZHyethuGKAn2IVleIbTB9I3vJSQiSR+DifUqmdzfPMoMPJfLqMF2vw==", + "license": "MIT", + "dependencies": { + "axios": "^1.8.2", + "joi": "^17.13.3", + "lodash": "^4.17.21", + "minimist": "^1.2.8", + "rxjs": "^7.8.2" + }, + "bin": { + "wait-on": "bin/wait-on" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "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/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "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/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "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/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.75", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.75.tgz", + "integrity": "sha512-OhpzAmVzabPOL6C3A3gpAifqr9MqihV/Msx3gor2b2kviCgcb+HM9SEOpMWwwNp9MRunWnhtAKUoo0AHhjyPPg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.24.6", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", + "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } + } + } +} diff --git a/pickleglass_web/package-lock.json b/pickleglass_web/package-lock.json new file mode 100644 index 0000000..f1d6fa0 --- /dev/null +++ b/pickleglass_web/package-lock.json @@ -0,0 +1,6976 @@ +{ + "name": "pickleglass-frontend", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "pickleglass-frontend", + "version": "0.1.0", + "dependencies": { + "@headlessui/react": "^1.7.17", + "autoprefixer": "^10.4.16", + "axios": "^1.6.0", + "firebase": "^11.10.0", + "lucide-react": "^0.294.0", + "next": "^14.2.30", + "postcss": "^8.4.32", + "react": "^18", + "react-dom": "^18", + "react-hot-toast": "^2.5.2", + "tailwindcss": "^3.3.0" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "eslint": "^8", + "eslint-config-next": "14.0.4", + "typescript": "^5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emnapi/core": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.4.tgz", + "integrity": "sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz", + "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.3.tgz", + "integrity": "sha512-8K5IFFsQqF9wQNJptGbS6FNKgUTsSRYnTqNCG1vPP8jFdjSv18n2mQfJpkt2Oibo9iBEzcDnDxNwKTzC7svlJw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "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/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@firebase/ai": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-1.4.1.tgz", + "integrity": "sha512-bcusQfA/tHjUjBTnMx6jdoPMpDl3r8K15Z+snHz9wq0Foox0F/V+kNLXucEOHoTL2hTc9l+onZCyBJs2QoIC3g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/analytics": { + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.17.tgz", + "integrity": "sha512-n5vfBbvzduMou/2cqsnKrIes4auaBjdhg8QNA2ZQZ59QgtO2QiwBaXQZQE4O4sgB0Ds1tvLgUUkY+pwzu6/xEg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.23.tgz", + "integrity": "sha512-3AdO10RN18G5AzREPoFgYhW6vWXr3u+OYQv6pl3CX6Fky8QRk0AHurZlY3Q1xkXO0TDxIsdhO3y65HF7PBOJDw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/analytics": "0.10.17", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.2.tgz", + "integrity": "sha512-jwtMmJa1BXXDCiDx1vC6SFN/+HfYG53UkfJa6qeN5ogvOunzbFDO3wISZy5n9xgYFUrEP6M7e8EG++riHNTv9w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.10.1.tgz", + "integrity": "sha512-MgNdlms9Qb0oSny87pwpjKush9qUwCJhfmTJHDfrcKo4neLGiSeVE4qJkzP7EQTIUFKp84pbTxobSAXkiuQVYQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.26.tgz", + "integrity": "sha512-PkX+XJMLDea6nmnopzFKlr+s2LMQGqdyT2DHdbx1v1dPSqOol2YzgpgymmhC67vitXVpNvS3m/AiWQWWhhRRPQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check": "0.10.1", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-compat": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.4.2.tgz", + "integrity": "sha512-LssbyKHlwLeiV8GBATyOyjmHcMpX/tFjzRUCS1jnwGAew1VsBB4fJowyS5Ud5LdFbYpJeS+IQoC+RQxpK7eH3Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app": "0.13.2", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-compat": { + "version": "0.5.28", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.28.tgz", + "integrity": "sha512-HpMSo/cc6Y8IX7bkRIaPPqT//Jt83iWy5rmDWeThXQCAImstkdNo3giFLORJwrZw2ptiGkOij64EH1ztNJzc7Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth": "1.10.8", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/auth": { + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", + "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-types": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.18.tgz", + "integrity": "sha512-n28kPCkE2dL2U28fSxZJjzPPVpKsQminJ6NrzcKXAI0E/lYC8YhfwpyllScqVEvAI3J2QgJZWYgrX+1qGI+SQQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/data-connect": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.10.tgz", + "integrity": "sha512-VMVk7zxIkgwlVQIWHOKFahmleIjiVFwFOjmakXPd/LDgaB/5vzwsB5DWIYo+3KhGxWpidQlR8geCIn39YflJIQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/database": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.20.tgz", + "integrity": "sha512-H9Rpj1pQ1yc9+4HQOotFGLxqAXwOzCHsRSRjcQFNOr8lhUt6LeYjf0NSRL04sc4X0dWe8DsCvYKxMYvFG/iOJw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.11.tgz", + "integrity": "sha512-itEsHARSsYS95+udF/TtIzNeQ0Uhx4uIna0sk4E0wQJBUnLc/G1X6D7oRljoOuwwCezRLGvWBRyNrugv/esOEw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/database": "1.0.20", + "@firebase/database-types": "1.0.15", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.15.tgz", + "integrity": "sha512-XWHJ0VUJ0k2E9HDMlKxlgy/ZuTa9EvHCGLjaKSUvrQnwhgZuRU5N3yX6SZ+ftf2hTzZmfRkv+b3QRvGg40bKNw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.12.1" + } + }, + "node_modules/@firebase/firestore": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.8.0.tgz", + "integrity": "sha512-QSRk+Q1/CaabKyqn3C32KSFiOdZpSqI9rpLK5BHPcooElumOBooPFa6YkDdiT+/KhJtel36LdAacha9BptMj2A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "@firebase/webchannel-wrapper": "1.0.3", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.3.53", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.53.tgz", + "integrity": "sha512-qI3yZL8ljwAYWrTousWYbemay2YZa+udLWugjdjju2KODWtLG94DfO4NALJgPLv8CVGcDHNFXoyQexdRA0Cz8Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/firestore": "4.8.0", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.12.9", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.9.tgz", + "integrity": "sha512-FG95w6vjbUXN84Ehezc2SDjGmGq225UYbHrb/ptkRT7OTuCiQRErOQuyt1jI1tvcDekdNog+anIObihNFz79Lg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.18", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.26.tgz", + "integrity": "sha512-A798/6ff5LcG2LTWqaGazbFYnjBW8zc65YfID/en83ALmkhu2b0G8ykvQnLtakbV9ajrMYPn7Yc/XcYsZIUsjA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/functions": "0.12.9", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/installations": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.18.tgz", + "integrity": "sha512-NQ86uGAcvO8nBRwVltRL9QQ4Reidc/3whdAasgeWCPIcrhOKDuNpAALa6eCVryLnK14ua2DqekCOX5uC9XbU/A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.18.tgz", + "integrity": "sha512-aLFohRpJO5kKBL/XYL4tN+GdwEB/Q6Vo9eZOM/6Kic7asSUgmSfGPpGUZO1OAaSRGwF4Lqnvi1f/f9VZnKzChw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.12.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.22.tgz", + "integrity": "sha512-GJcrPLc+Hu7nk+XQ70Okt3M1u1eRr2ZvpMbzbc54oTPJZySHcX9ccZGVFcsZbSZ6o1uqumm8Oc7OFkD3Rn1/og==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.12.1", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.22.tgz", + "integrity": "sha512-5ZHtRnj6YO6f/QPa/KU6gryjmX4Kg33Kn4gRpNU6M1K47Gm8kcQwPkX7erRUYEH1mIWptfvjvXMHWoZaWjkU7A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/messaging": "0.12.22", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/performance": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.7.tgz", + "integrity": "sha512-JTlTQNZKAd4+Q5sodpw6CN+6NmwbY72av3Lb6wUKTsL7rb3cuBIhQSrslWbVz0SwK3x0ZNcqX24qtRbwKiv+6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.20", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.20.tgz", + "integrity": "sha512-XkFK5NmOKCBuqOKWeRgBUFZZGz9SzdTZp4OqeUg+5nyjapTiZ4XoiiUL8z7mB2q+63rPmBl7msv682J3rcDXIQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/performance": "0.7.7", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/remote-config": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.5.tgz", + "integrity": "sha512-fU0c8HY0vrVHwC+zQ/fpXSqHyDMuuuglV94VF6Yonhz8Fg2J+KOowPGANM0SZkLvVOYpTeWp3ZmM+F6NjwWLnw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.18.tgz", + "integrity": "sha512-YiETpldhDy7zUrnS8e+3l7cNs0sL7+tVAxvVYU0lu7O+qLHbmdtAxmgY+wJqWdW2c9nDvBFec7QiF58pEUu0qQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/remote-config": "0.6.5", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/storage": { + "version": "0.13.14", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.14.tgz", + "integrity": "sha512-xTq5ixxORzx+bfqCpsh+o3fxOsGoDjC1nO0Mq2+KsOcny3l7beyBhP/y1u5T6mgsFQwI1j6oAkbT5cWdDBx87g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.24.tgz", + "integrity": "sha512-XHn2tLniiP7BFKJaPZ0P8YQXKiVJX+bMyE2j2YWjYfaddqiJnROJYqSomwW6L3Y+gZAga35ONXUJQju6MB6SOQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/storage": "0.13.14", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.1.tgz", + "integrity": "sha512-zGlBn/9Dnya5ta9bX/fgEoNC3Cp8s6h+uYPYaDieZsFOAdHP/ExzQ/eaDgxD3GOROdPkLKpvKY0iIzr9adle0w==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", + "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==", + "license": "Apache-2.0" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@headlessui/react": { + "version": "1.7.19", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz", + "integrity": "sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==", + "license": "MIT", + "dependencies": { + "@tanstack/react-virtual": "^3.0.0-beta.60", + "client-only": "^0.0.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "react-dom": "^16 || ^17 || ^18" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.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/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz", + "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@next/env": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.30.tgz", + "integrity": "sha512-KBiBKrDY6kxTQWGzKjQB7QirL3PiiOkV7KW98leHFjtVRKtft76Ra5qSA/SL75xT44dp6hOcqiiJ6iievLOYug==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.0.4.tgz", + "integrity": "sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "7.1.7" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.30.tgz", + "integrity": "sha512-EAqfOTb3bTGh9+ewpO/jC59uACadRHM6TSA9DdxJB/6gxOpyV+zrbqeXiFTDy9uV6bmipFDkfpAskeaDcO+7/g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.30.tgz", + "integrity": "sha512-TyO7Wz1IKE2kGv8dwQ0bmPL3s44EKVencOqwIY69myoS3rdpO1NPg5xPM5ymKu7nfX4oYJrpMxv8G9iqLsnL4A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.30.tgz", + "integrity": "sha512-I5lg1fgPJ7I5dk6mr3qCH1hJYKJu1FsfKSiTKoYwcuUf53HWTrEkwmMI0t5ojFKeA6Vu+SfT2zVy5NS0QLXV4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.30.tgz", + "integrity": "sha512-8GkNA+sLclQyxgzCDs2/2GSwBc92QLMrmYAmoP2xehe5MUKBLB2cgo34Yu242L1siSkwQkiV4YLdCnjwc/Micw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.30.tgz", + "integrity": "sha512-8Ly7okjssLuBoe8qaRCcjGtcMsv79hwzn/63wNeIkzJVFVX06h5S737XNr7DZwlsbTBDOyI6qbL2BJB5n6TV/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.30.tgz", + "integrity": "sha512-dBmV1lLNeX4mR7uI7KNVHsGQU+OgTG5RGFPi3tBJpsKPvOPtg9poyav/BYWrB3GPQL4dW5YGGgalwZ79WukbKQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.30.tgz", + "integrity": "sha512-6MMHi2Qc1Gkq+4YLXAgbYslE1f9zMGBikKMdmQRHXjkGPot1JY3n5/Qrbg40Uvbi8//wYnydPnyvNhI1DMUW1g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.30.tgz", + "integrity": "sha512-pVZMnFok5qEX4RT59mK2hEVtJX+XFfak+/rjHpyFh7juiT52r177bfFKhnlafm0UOSldhXjj32b+LZIOdswGTg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.30.tgz", + "integrity": "sha512-4KCo8hMZXMjpTzs3HOqOGYYwAXymXIy7PEPAXNEcEOyKqkjiDlECumrWziy+JEF0Oi4ILHGxzgQ3YiMGG2t/Lg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.12.0.tgz", + "integrity": "sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.13.12", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.12.tgz", + "integrity": "sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.13.12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.13.12", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.12.tgz", + "integrity": "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.4.tgz", + "integrity": "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.23", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz", + "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.0.tgz", + "integrity": "sha512-LRw5BW29sYj9NsQC6QoqeLVQhEa+BwVINYyMlcve+6stwdBsSt5UB7zw4UZB4+4PNqIVilHoMaPWCb/KhABHQw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.0.tgz", + "integrity": "sha512-zYX8D2zcWCAHqghA8tPjbp7LwjVXbIZP++mpU/Mrf5jUVlk3BWIxkeB8yYzZi5GpFSlqMcRZQxQqbMI0c2lASQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.0.tgz", + "integrity": "sha512-YsYOT049hevAY/lTYD77GhRs885EXPeAfExG5KenqMJ417nYLS2N/kpRpYbABhFZBVQn+2uRPasTe4ypmYoo3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.0.tgz", + "integrity": "sha512-PSjvk3OZf1aZImdGY5xj9ClFG3bC4gnSSYWrt+id0UAv+GwwVldhpMFjAga8SpMo2T1GjV9UKwM+QCsQCQmtdA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.0.tgz", + "integrity": "sha512-KC/iFaEN/wsTVYnHClyHh5RSYA9PpuGfqkFua45r4sweXpC0KHZ+BYY7ikfcGPt5w1lMpR1gneFzuqWLQxsRKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.0.tgz", + "integrity": "sha512-CDh/0v8uot43cB4yKtDL9CVY8pbPnMV0dHyQCE4lFz6PW/+9tS0i9eqP5a91PAqEBVMqH1ycu+k8rP6wQU846w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.0.tgz", + "integrity": "sha512-+TE7epATDSnvwr3L/hNHX3wQ8KQYB+jSDTdywycg3qDqvavRP8/HX9qdq/rMcnaRDn4EOtallb3vL/5wCWGCkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.0.tgz", + "integrity": "sha512-VBAYGg3VahofpQ+L4k/ZO8TSICIbUKKTaMYOWHWfuYBFqPbSkArZZLezw3xd27fQkxX4BaLGb/RKnW0dH9Y/UA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.0.tgz", + "integrity": "sha512-9IgGFUUb02J1hqdRAHXpZHIeUHRrbnGo6vrRbz0fREH7g+rzQy53/IBSyadZ/LG5iqMxukriNPu4hEMUn+uWEg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.0.tgz", + "integrity": "sha512-LR4iQ/LPjMfivpL2bQ9kmm3UnTas3U+umcCnq/CV7HAkukVdHxrDD1wwx74MIWbbgzQTLPYY7Ur2MnnvkYJCBQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.0.tgz", + "integrity": "sha512-HCupFQwMrRhrOg7YHrobbB5ADg0Q8RNiuefqMHVsdhEy9lLyXm/CxsCXeLJdrg27NAPsCaMDtdlm8Z2X8x91Tg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.0.tgz", + "integrity": "sha512-Ckxy76A5xgjWa4FNrzcKul5qFMWgP5JSQ5YKd0XakmWOddPLSkQT+uAvUpQNnFGNbgKzv90DyQlxPDYPQ4nd6A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.0.tgz", + "integrity": "sha512-HfO0PUCCRte2pMJmVyxPI+eqT7KuV3Fnvn2RPvMe5mOzb2BJKf4/Vth8sSt9cerQboMaTVpbxyYjjLBWIuI5BQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.0.tgz", + "integrity": "sha512-9PZdjP7tLOEjpXHS6+B/RNqtfVUyDEmaViPOuSqcbomLdkJnalt5RKQ1tr2m16+qAufV0aDkfhXtoO7DQos/jg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.0.tgz", + "integrity": "sha512-qkE99ieiSKMnFJY/EfyGKVtNra52/k+lVF/PbO4EL5nU6AdvG4XhtJ+WHojAJP7ID9BNIra/yd75EHndewNRfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.0.tgz", + "integrity": "sha512-MjXek8UL9tIX34gymvQLecz2hMaQzOlaqYJJBomwm1gsvK2F7hF+YqJJ2tRyBDTv9EZJGMt4KlKkSD/gZWCOiw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.0.tgz", + "integrity": "sha512-9LT6zIGO7CHybiQSh7DnQGwFMZvVr0kUjah6qQfkH2ghucxPV6e71sUXJdSM4Ba0MaGE6DC/NwWf7mJmc3DAng==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.0.tgz", + "integrity": "sha512-HYchBYOZ7WN266VjoGm20xFv5EonG/ODURRgwl9EZT7Bq1nLEs6VKJddzfFdXEAho0wfFlt8L/xIiE29Pmy1RA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.0.tgz", + "integrity": "sha512-+oLKLHw3I1UQo4MeHfoLYF+e6YBa8p5vYUw3Rgt7IDzCs+57vIZqQlIo62NDpYM0VG6BjWOwnzBczMvbtH8hag==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "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/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "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/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "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-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "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/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "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/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/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/axe-core": { + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", + "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axios": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "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/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/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/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/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/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/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/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "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/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "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/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "license": "Apache-2.0" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.180", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.180.tgz", + "integrity": "sha512-ED+GEyEh3kYMwt2faNmgMB0b8O5qtATGgR4RmRsIp4T6p7B8vdMbIedYndnvZfsaXvSzegtpfqRMDNCjjiSduA==", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "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.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "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-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "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.4", + "safe-array-concat": "^1.1.3" + }, + "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/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.0.4.tgz", + "integrity": "sha512-9/xbOHEQOmQtqvQ1UsTQZpnA7SlDMBtuKJ//S4JnoyK3oGLhILKXdBgu/UO7lQo/2xOykQULS1qQ6p2+EpHgAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "14.0.4", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/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/eslint-plugin-import/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/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "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": "5.0.0-canary-7118f5dd7-20230705", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz", + "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/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/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/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/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "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/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/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/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/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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/firebase": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.10.0.tgz", + "integrity": "sha512-nKBXoDzF0DrXTBQJlZa+sbC5By99ysYU1D6PkMRYknm0nCW7rJly47q492Ht7Ndz5MeYSBuboKuhS1e6mFC03w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/ai": "1.4.1", + "@firebase/analytics": "0.10.17", + "@firebase/analytics-compat": "0.2.23", + "@firebase/app": "0.13.2", + "@firebase/app-check": "0.10.1", + "@firebase/app-check-compat": "0.3.26", + "@firebase/app-compat": "0.4.2", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.10.8", + "@firebase/auth-compat": "0.5.28", + "@firebase/data-connect": "0.3.10", + "@firebase/database": "1.0.20", + "@firebase/database-compat": "2.0.11", + "@firebase/firestore": "4.8.0", + "@firebase/firestore-compat": "0.3.53", + "@firebase/functions": "0.12.9", + "@firebase/functions-compat": "0.3.26", + "@firebase/installations": "0.6.18", + "@firebase/installations-compat": "0.2.18", + "@firebase/messaging": "0.12.22", + "@firebase/messaging-compat": "0.2.22", + "@firebase/performance": "0.7.7", + "@firebase/performance-compat": "0.2.20", + "@firebase/remote-config": "0.6.5", + "@firebase/remote-config-compat": "0.2.18", + "@firebase/storage": "0.13.14", + "@firebase/storage-compat": "0.3.24", + "@firebase/util": "1.12.1" + } + }, + "node_modules/firebase/node_modules/@firebase/auth": { + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", + "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.18", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.12.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "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/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "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": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/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==", + "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/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-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-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/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "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==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "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==", + "dev": 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/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/goober": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", + "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", + "license": "MIT", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": 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.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "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/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-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-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-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-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-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-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-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": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-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-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/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-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/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "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/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "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-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/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "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/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/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.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/lodash.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/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/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==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/lucide-react": { + "version": "0.294.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.294.0.tgz", + "integrity": "sha512-V7o0/VECSGbLHn3/1O67FUgBwWB+hmzshrgDVRJQhMh8uj5D3HBuIvhuAmQTtlupILSplwIZg5FTc4tTKMA2SA==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/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/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-postinstall": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.0.tgz", + "integrity": "sha512-M7NqKyhODKV1gRLdkwE7pDsZP2/SC2a2vHkOYh9MCpKMbWVfyVfUw5MaH83Fv6XMjxr5jryUp3IDDL9rlxsTeA==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "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/next": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.30.tgz", + "integrity": "sha512-+COdu6HQrHHFQ1S/8BBsCag61jZacmvbuL2avHvQFbWa2Ox7bE+d8FyNgxRLjXQ5wtPyQwEmk85js/AuaG2Sbg==", + "license": "MIT", + "dependencies": { + "@next/env": "14.2.30", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.30", + "@next/swc-darwin-x64": "14.2.30", + "@next/swc-linux-arm64-gnu": "14.2.30", + "@next/swc-linux-arm64-musl": "14.2.30", + "@next/swc-linux-x64-gnu": "14.2.30", + "@next/swc-linux-x64-musl": "14.2.30", + "@next/swc-win32-arm64-msvc": "14.2.30", + "@next/swc-win32-ia32-msvc": "14.2.30", + "@next/swc-win32-x64-msvc": "14.2.30" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "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.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "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==", + "dev": 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.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "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-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/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/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/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/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.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/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/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/protobufjs": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", + "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/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/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-hot-toast": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.2.tgz", + "integrity": "sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.3", + "goober": "^2.1.16" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "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/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/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/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-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/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/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.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stable-hash": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "dev": true, + "license": "MIT" + }, + "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/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/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": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "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.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "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-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/unrs-resolver": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.0.tgz", + "integrity": "sha512-uw3hCGO/RdAEAb4zgJ3C/v6KIAFFOtBoxR86b2Ejc5TnH7HrhTWJR2o0A9ullC3eWMegKQCw/arQ/JivywQzkg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.0", + "@unrs/resolver-binding-android-arm64": "1.11.0", + "@unrs/resolver-binding-darwin-arm64": "1.11.0", + "@unrs/resolver-binding-darwin-x64": "1.11.0", + "@unrs/resolver-binding-freebsd-x64": "1.11.0", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.0", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.0", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.0", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.0", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.0", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-x64-musl": "1.11.0", + "@unrs/resolver-binding-wasm32-wasi": "1.11.0", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.0", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.0", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/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/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/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.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "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==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/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" + } + } + } +} From 3f116b43bfa416a8980831aaf57a38b8cb527aed Mon Sep 17 00:00:00 2001 From: samtiz Date: Tue, 8 Jul 2025 11:57:53 +0900 Subject: [PATCH 38/52] release v0.2.2 --- .github/workflows/build.yml | 12 +++++++++++- README.md | 2 -- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b8ae04a..8689597 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,4 +31,14 @@ jobs: - name: 🖥️ Build Electron app # Run Electron build script from root directory - run: npm run build \ No newline at end of file + run: npm run build + + - name: 🚨 Send failure notification to Slack + if: failure() + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_CHANNEL: general + SLACK_TITLE: "🚨 Build Failed" + SLACK_MESSAGE: "😭 Build failed for `${{ github.repository }}` repo on main branch." + SLACK_COLOR: 'danger' + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} \ No newline at end of file diff --git a/README.md b/README.md index 8397aec..e166914 100644 --- a/README.md +++ b/README.md @@ -117,12 +117,10 @@ We have a list of [help wanted](https://github.com/pickle-com/glass/issues?q=is% | Status | Issue | Description | |--------|--------------------------------|---------------------------------------------------| -| 🚧 WIP | Code Refactoring | Refactoring the entire codebase for better maintainability. | | 🚧 WIP | Windows Build | Make Glass buildable & runnable in Windows | | 🚧 WIP | Local LLM Support | Supporting Local LLM to power AI answers | | 🚧 WIP | AEC Improvement | Transcription is not working occasionally | | 🚧 WIP | Firebase Data Storage Issue | Session & ask should be saved in firebase for signup users | -| 🚧 WIP | Login Issue | Currently breaking when switching between local and sign-in mode | | 🚧 WIP | Liquid Glass | Liquid Glass UI for MacOS 26 | ### Changelog From da6602ef66a05f299957e367a374e816254ea5d3 Mon Sep 17 00:00:00 2001 From: samtiz Date: Tue, 8 Jul 2025 11:58:26 +0900 Subject: [PATCH 39/52] implementing aec --- aec | 1 + package.json | 5 +- src/assets/aec.js | 20 ++++++++ src/assets/aec.wasm | Bin 0 -> 113342 bytes src/features/listen/renderer/listenCapture.js | 46 ++++++++++++++++++ 5 files changed, 69 insertions(+), 3 deletions(-) create mode 160000 aec create mode 100644 src/assets/aec.js create mode 100755 src/assets/aec.wasm diff --git a/aec b/aec new file mode 160000 index 0000000..66c447b --- /dev/null +++ b/aec @@ -0,0 +1 @@ +Subproject commit 66c447ba544dfe8e3bb4091fda2961a11066910b diff --git a/package.json b/package.json index 52d6fab..e69f01e 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "package": "npm run build:renderer && electron-forge package", "make": "npm run build:renderer && electron-forge make", "build": "npm run build:all && electron-builder --config electron-builder.yml --publish never", - "build:win": "npm run build:all && electron-builder --win --x64 --publish never", + "build:win": "npm run build:all && electron-builder --win --x64 --publish never", "publish": "npm run build:all && electron-builder --config electron-builder.yml --publish always", "lint": "eslint --ext .ts,.tsx,.js .", "postinstall": "electron-builder install-app-deps", @@ -39,7 +39,6 @@ "better-sqlite3": "^9.4.3", "cors": "^2.8.5", "dotenv": "^17.0.0", - "electron-squirrel-startup": "^1.0.1", "electron-store": "^8.2.0", "electron-updater": "^6.6.2", @@ -74,4 +73,4 @@ "optionalDependencies": { "electron-liquid-glass": "^1.0.1" } -} \ No newline at end of file +} diff --git a/src/assets/aec.js b/src/assets/aec.js new file mode 100644 index 0000000..332ffea --- /dev/null +++ b/src/assets/aec.js @@ -0,0 +1,20 @@ +var createAecModule = (() => { + var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined; + return ( +async function(moduleArg = {}) { + var moduleRtn; + +var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.initialized)FS.init();TTY.init();wasmExports["v"]();FS.ignorePermissions=false}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("aec.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["u"];updateMemoryViews();wasmTable=wasmExports["H"];assignWasmExports(wasmExports);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod,inst))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var exceptionLast=0;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var setTempRet0=val=>__emscripten_tempret_set(val);var findMatchingCatch=args=>{var thrown=exceptionLast;if(!thrown){setTempRet0(0);return 0}var info=new ExceptionInfo(thrown);info.set_adjusted_ptr(thrown);var thrownType=info.get_type();if(!thrownType){setTempRet0(0);return thrown}for(var caughtType of args){if(caughtType===0||caughtType===thrownType){break}var adjusted_ptr_addr=info.ptr+16;if(___cxa_can_catch(caughtType,thrownType,adjusted_ptr_addr)){setTempRet0(caughtType);return thrown}}setTempRet0(thrownType);return thrown};var ___cxa_find_matching_catch_2=()=>findMatchingCatch([]);var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var ___resumeException=ptr=>{if(!exceptionLast){exceptionLast=ptr}throw exceptionLast};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);function ___syscall_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd)+1;if(sizeabort("");var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.language||"C").replace("-","_")+".UTF-8";var env={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:lang,_:getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;var envp=0;for(var string of getEnvStrings()){var ptr=environ_buf+bufSize;HEAPU32[__environ+envp>>2]=ptr;bufSize+=stringToUTF8(string,ptr,Infinity)+1;envp+=4}return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;for(var string of strings){bufSize+=lengthBytesUTF8(string)+1}HEAPU32[penviron_buf_size>>2]=bufSize;return 0};var runtimeKeepaliveCounter=0;var keepRuntimeAlive=()=>noExitRuntime||runtimeKeepaliveCounter>0;var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){Module["onExit"]?.(code);ABORT=true}quit_(code,new ExitStatus(code))};var exitJS=(status,implicit)=>{EXITSTATUS=status;_proc_exit(status)};var _exit=exitJS;var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.slice(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.slice(0,-1)}return root+dir},basename:path=>path&&path.match(/([^\/]+|\/)\/*$/)[1],join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>view=>crypto.getRandomValues(view);var randomFill=view=>{(randomFill=initRandomFill())(view)};var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).slice(1);to=PATH_FS.resolve(to).slice(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var FS_stdin_getChar_buffer=[];var intArrayFromString=(stringy,dontAddNull,length)=>{var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array};var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output?.length>0){err(UTF8ArrayToString(tty.output));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16895,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.atime=node.mtime=node.ctime=Date.now();if(parent){parent.contents[name]=node;parent.atime=parent.mtime=parent.ctime=node.atime}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.atime);attr.mtime=new Date(node.mtime);attr.ctime=new Date(node.ctime);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){for(const key of["mode","atime","mtime","ctime"]){if(attr[key]!=null){node[key]=attr[key]}}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw MEMFS.doesNotExistError},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){if(FS.isDir(old_node.mode)){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}FS.hashRemoveNode(new_node)}delete old_node.parent.contents[old_node.name];new_dir.contents[new_name]=old_node;old_node.name=new_name;new_dir.ctime=new_dir.mtime=old_node.parent.ctime=old_node.parent.mtime=Date.now()},unlink(parent,name){delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},readdir(node){return[".","..",...Object.keys(node.contents)]},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var arrayBuffer=await readAsync(url);return new Uint8Array(arrayBuffer)};var FS_createDataFile=(...args)=>FS.createDataFile(...args);var getUniqueRunDependency=id=>id;var preloadPlugins=[];var FS_handledByPreloadPlugin=(byteArray,fullname,finish,onerror)=>{if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach(plugin=>{if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}});return handled};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}onload?.();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,()=>{onerror?.();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url).then(processData,onerror)}else{processData(url)}};var FS_modeStringToFlags=str=>{var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,filesystems:null,syncFSRequests:0,readFiles:{},ErrnoError:class{name="ErrnoError";constructor(errno){this.errno=errno}},FSStream:class{shared={};get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{node_ops={};stream_ops={};readMode=292|73;writeMode=146;mounted=null;constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.rdev=rdev;this.atime=this.mtime=this.ctime=Date.now()}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){if(!path){throw new FS.ErrnoError(44)}opts.follow_mount??=true;if(!PATH.isAbs(path)){path=FS.cwd()+"/"+path}linkloop:for(var nlinks=0;nlinks<40;nlinks++){var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){if(!FS.isDir(dir.mode)){return 54}try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&(512|64)){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},checkOpExists(op,err){if(!op){throw new FS.ErrnoError(err)}return op},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},doSetAttr(stream,node,attr){var setattr=stream?.stream_ops.setattr;var arg=setattr?stream:node;setattr??=node.node_ops.setattr;FS.checkOpExists(setattr,63);setattr(arg,attr)},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type,opts,mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name){throw new FS.ErrnoError(28)}if(name==="."||name===".."){throw new FS.ErrnoError(20)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},statfs(path){return FS.statfsNode(FS.lookupPath(path,{follow:true}).node)},statfsStream(stream){return FS.statfsNode(stream.node)},statfsNode(node){var rtn={bsize:4096,frsize:4096,blocks:1e6,bfree:5e5,bavail:5e5,files:FS.nextInode,ffree:FS.nextInode-1,fsid:42,flags:2,namelen:255};if(node.node_ops.statfs){Object.assign(rtn,node.node_ops.statfs(node.mount.opts.root))}return rtn},create(path,mode=438){mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode=511){mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var dir of dirs){if(!dir)continue;if(d||PATH.isAbs(path))d+="/";d+=dir;try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev(path,mode,dev){if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name);old_node.parent=new_dir}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var readdir=FS.checkOpExists(node.node_ops.readdir,54);return readdir(node)},unlink(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return link.node_ops.readlink(link)},stat(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;var getattr=FS.checkOpExists(node.node_ops.getattr,63);return getattr(node)},fstat(fd){var stream=FS.getStreamChecked(fd);var node=stream.node;var getattr=stream.stream_ops.getattr;var arg=getattr?stream:node;getattr??=node.node_ops.getattr;FS.checkOpExists(getattr,63);return getattr(arg)},lstat(path){return FS.stat(path,true)},doChmod(stream,node,mode,dontFollow){FS.doSetAttr(stream,node,{mode:mode&4095|node.mode&~4095,ctime:Date.now(),dontFollow})},chmod(path,mode,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChmod(null,node,mode,dontFollow)},lchmod(path,mode){FS.chmod(path,mode,true)},fchmod(fd,mode){var stream=FS.getStreamChecked(fd);FS.doChmod(stream,stream.node,mode,false)},doChown(stream,node,dontFollow){FS.doSetAttr(stream,node,{timestamp:Date.now(),dontFollow})},chown(path,uid,gid,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChown(null,node,dontFollow)},lchown(path,uid,gid){FS.chown(path,uid,gid,true)},fchown(fd,uid,gid){var stream=FS.getStreamChecked(fd);FS.doChown(stream,stream.node,false)},doTruncate(stream,node,len){if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}FS.doSetAttr(stream,node,{size:len,timestamp:Date.now()})},truncate(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}FS.doTruncate(null,node,len)},ftruncate(fd,len){var stream=FS.getStreamChecked(fd);if(len<0||(stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.doTruncate(stream,stream.node,len)},utime(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var setattr=FS.checkOpExists(node.node_ops.setattr,63);setattr(node,{atime,mtime})},open(path,flags,mode=438){if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;var isDirPath;if(typeof path=="object"){node=path}else{isDirPath=path.endsWith("/");var lookup=FS.lookupPath(path,{follow:!(flags&131072),noent_okay:true});node=lookup.node;path=lookup.path}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else if(isDirPath){throw new FS.ErrnoError(31)}else{node=FS.mknod(path,mode|511,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node,path:FS.getPath(node),flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(created){FS.chmod(node,mode&511)}if(Module["logReadFiles"]&&!(flags&1)){if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed(stream){return stream.fd===null},llseek(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},mmap(stream,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}if(!length){throw new FS.ErrnoError(28)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync(stream,buffer,offset,length,mmapFlags){if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){buf=UTF8ArrayToString(buf)}FS.close(stream);return buf},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){data=new Uint8Array(intArrayFromString(data,true))}if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length,llseek:()=>0});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomFill(randomBuffer);randomLeft=randomBuffer.byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16895,73);node.stream_ops={llseek:MEMFS.stream_ops.llseek};node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path},id:fd+1};ret.parent=ret;return ret},readdir(){return Array.from(FS.streams.entries()).filter(([k,v])=>v).map(([k,v])=>k.toString())}};return node}},{},"/proc/self/fd")},createStandardStreams(input,output,error){if(input){FS.createDevice("/dev","stdin",input)}else{FS.symlink("/dev/tty","/dev/stdin")}if(output){FS.createDevice("/dev","stdout",null,output)}else{FS.symlink("/dev/tty","/dev/stdout")}if(error){FS.createDevice("/dev","stderr",null,error)}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS}},init(input,output,error){FS.initialized=true;input??=Module["stdin"];output??=Module["stdout"];error??=Module["stderr"];FS.createStandardStreams(input,output,error)},quit(){FS.initialized=false;for(var stream of FS.streams){if(stream){FS.close(stream)}}},findObject(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath(parent,path,canRead,canWrite){parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){if(e.errno!=20)throw e}parent=current}return current},createFile(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile(parent,name,data,canRead,canWrite,canOwn){var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return dir+"/"+path},writeStat(buf,stat){HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAP32[buf+12>>2]=stat.uid;HEAP32[buf+16>>2]=stat.gid;HEAP32[buf+20>>2]=stat.rdev;HEAP64[buf+24>>3]=BigInt(stat.size);HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();HEAP64[buf+40>>3]=BigInt(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3*1e3;HEAP64[buf+56>>3]=BigInt(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3*1e3;HEAP64[buf+72>>3]=BigInt(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3*1e3;HEAP64[buf+88>>3]=BigInt(stat.ino);return 0},writeStatFs(buf,stats){HEAP32[buf+4>>2]=stats.bsize;HEAP32[buf+40>>2]=stats.bsize;HEAP32[buf+8>>2]=stats.blocks;HEAP32[buf+12>>2]=stats.bfree;HEAP32[buf+16>>2]=stats.bavail;HEAP32[buf+20>>2]=stats.files;HEAP32[buf+24>>2]=stats.ffree;HEAP32[buf+28>>2]=stats.fsid;HEAP32[buf+44>>2]=stats.flags;HEAP32[buf+36>>2]=stats.namelen},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>numINT53_MAX?NaN:Number(num);function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);HEAP64[newOffset>>3]=BigInt(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var wasmTableMirror=[];var wasmTable;var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();MEMFS.doesNotExistError=new FS.ErrnoError(44);MEMFS.doesNotExistError.stack="";{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["preloadPlugins"])preloadPlugins=Module["preloadPlugins"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}Module["ccall"]=ccall;Module["cwrap"]=cwrap;var _AecNew,_AecCancelEcho,_AecDestroy,_malloc,_free,_setThrew,__emscripten_tempret_set,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,___cxa_can_catch;function assignWasmExports(wasmExports){Module["_AecNew"]=_AecNew=wasmExports["w"];Module["_AecCancelEcho"]=_AecCancelEcho=wasmExports["x"];Module["_AecDestroy"]=_AecDestroy=wasmExports["y"];Module["_malloc"]=_malloc=wasmExports["z"];Module["_free"]=_free=wasmExports["A"];_setThrew=wasmExports["B"];__emscripten_tempret_set=wasmExports["C"];__emscripten_stack_restore=wasmExports["D"];__emscripten_stack_alloc=wasmExports["E"];_emscripten_stack_get_current=wasmExports["F"];___cxa_can_catch=wasmExports["G"]}var wasmImports={a:___cxa_find_matching_catch_2,q:___cxa_throw,b:___resumeException,p:___syscall_getcwd,r:__abort_js,t:_emscripten_resize_heap,n:_environ_get,o:_environ_sizes_get,k:_exit,s:_fd_close,l:_fd_seek,g:_fd_write,i:invoke_ii,f:invoke_iiii,m:invoke_iiiiii,c:invoke_vi,d:invoke_vii,e:invoke_viii,j:invoke_viiii,h:invoke_viiiii};var wasmExports=await createWasm();function invoke_vi(index,a1){var sp=stackSave();try{getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viii(index,a1,a2,a3){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_vii(index,a1,a2){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viiii(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iiii(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_ii(index,a1){var sp=stackSave();try{return getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iiiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})} + + + return moduleRtn; +} +); +})(); +if (typeof exports === 'object' && typeof module === 'object') { + module.exports = createAecModule; + // This default export looks redundant, but it allows TS to import this + // commonjs style module. + module.exports.default = createAecModule; +} else if (typeof define === 'function' && define['amd']) + define([], () => createAecModule); diff --git a/src/assets/aec.wasm b/src/assets/aec.wasm new file mode 100755 index 0000000000000000000000000000000000000000..9d5924ada9ef44f43f2dff9c1fbaedc03fabe345 GIT binary patch literal 113342 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 DCKAgt literal 0 HcmV?d00001 diff --git a/src/features/listen/renderer/listenCapture.js b/src/features/listen/renderer/listenCapture.js index 1c27f75..f8e1722 100644 --- a/src/features/listen/renderer/listenCapture.js +++ b/src/features/listen/renderer/listenCapture.js @@ -1,5 +1,33 @@ const { ipcRenderer } = require('electron'); +const createAecModule = require('../../../assets/aec.js'); // aec.js 위치 + +let aecWasm; // 전역 캐시 + +export async function initAec () { + if (aecWasm) return aecWasm; // 이미 초기화됐으면 그대로 + + // ⬇️ locateFile: aec.js 가 wasm 로드를 시도할 때 호출 + aecWasm = await createAecModule({ + locateFile (filename) { + // aec.js 는 ‘aec.wasm’ 한 개만 요청하므로, 주소를 직접 반환 + return '../../../assets/' + filename; // ← **브라우저 기준 URL** + // (Electron renderer 에서 file://…/dist/renderer/… 에서 접근) + } + }); + + // C → JS 래퍼 + aecWasm.newPtr = aecWasm.cwrap('AecNew', 'number', + ['number','number','number','number']); + aecWasm.cancel = aecWasm.cwrap('AecCancelEcho', null, + ['number','number','number','number','number']); + aecWasm.destroy = aecWasm.cwrap('AecDestroy', null, ['number']); + + return aecWasm; +} + +// 바로 로드-실패 로그를 보기 위해 +initAec().catch(console.error); // --------------------------- // Constants & Globals // --------------------------- @@ -80,6 +108,24 @@ function arrayBufferToBase64(buffer) { return btoa(binary); } +function int16PtrFromFloat32(mod, f32) { + const len = f32.length; + const bytes = len * 2; + const ptr = mod._malloc(bytes); + const i16 = new Int16Array(mod.HEAP16.buffer, ptr, len); + for (let i = 0; i < len; ++i) { + const s = Math.max(-1, Math.min(1, f32[i])); + i16[i] = s < 0 ? s * 0x8000 : s * 0x7fff; + } + return { ptr, view: i16 }; +} + +function float32FromInt16View(i16) { + const out = new Float32Array(i16.length); + for (let i = 0; i < i16.length; ++i) out[i] = i16[i] / 32768; + return out; +} + // --------------------------- // Complete SimpleAEC implementation (exact from renderer.js) // --------------------------- From e17668caba93336353f7cc5bf25e25657932676b Mon Sep 17 00:00:00 2001 From: samtiz Date: Tue, 8 Jul 2025 11:57:53 +0900 Subject: [PATCH 40/52] release v0.2.2 --- .github/workflows/build.yml | 12 +++++++++++- README.md | 2 -- package.json | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b8ae04a..8689597 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,4 +31,14 @@ jobs: - name: 🖥️ Build Electron app # Run Electron build script from root directory - run: npm run build \ No newline at end of file + run: npm run build + + - name: 🚨 Send failure notification to Slack + if: failure() + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_CHANNEL: general + SLACK_TITLE: "🚨 Build Failed" + SLACK_MESSAGE: "😭 Build failed for `${{ github.repository }}` repo on main branch." + SLACK_COLOR: 'danger' + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} \ No newline at end of file diff --git a/README.md b/README.md index 8397aec..e166914 100644 --- a/README.md +++ b/README.md @@ -117,12 +117,10 @@ We have a list of [help wanted](https://github.com/pickle-com/glass/issues?q=is% | Status | Issue | Description | |--------|--------------------------------|---------------------------------------------------| -| 🚧 WIP | Code Refactoring | Refactoring the entire codebase for better maintainability. | | 🚧 WIP | Windows Build | Make Glass buildable & runnable in Windows | | 🚧 WIP | Local LLM Support | Supporting Local LLM to power AI answers | | 🚧 WIP | AEC Improvement | Transcription is not working occasionally | | 🚧 WIP | Firebase Data Storage Issue | Session & ask should be saved in firebase for signup users | -| 🚧 WIP | Login Issue | Currently breaking when switching between local and sign-in mode | | 🚧 WIP | Liquid Glass | Liquid Glass UI for MacOS 26 | ### Changelog diff --git a/package.json b/package.json index 52d6fab..2269777 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pickle-glass", "productName": "Glass", - "version": "0.2.1", + "version": "0.2.2", "description": "Cl*ely for Free", "main": "src/index.js", "scripts": { From 2e259fcb8f7ddadd0d084e0988ed7573c39dbe8f Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Tue, 8 Jul 2025 15:47:04 +0900 Subject: [PATCH 41/52] summary fixed --- src/features/listen/summary/summaryService.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/listen/summary/summaryService.js b/src/features/listen/summary/summaryService.js index 9f3a811..53d3b79 100644 --- a/src/features/listen/summary/summaryService.js +++ b/src/features/listen/summary/summaryService.js @@ -115,7 +115,7 @@ Please build upon this context while analyzing the new conversation segments. await sessionRepository.touch(this.currentSessionId); } - const modelInfo = await getCurrentModelInfo('llm'); + const modelInfo = await getCurrentModelInfo(null, { type: 'llm' }); if (!modelInfo || !modelInfo.apiKey) { throw new Error('AI model or API key is not configured.'); } From e5d301cc9c9a2cf6879c197221a56b905134d2fa Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Tue, 8 Jul 2025 16:01:11 +0900 Subject: [PATCH 42/52] stt error fixed --- src/features/listen/stt/sttService.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/features/listen/stt/sttService.js b/src/features/listen/stt/sttService.js index 493c014..68d8ef2 100644 --- a/src/features/listen/stt/sttService.js +++ b/src/features/listen/stt/sttService.js @@ -320,14 +320,20 @@ class SttService { } async sendSystemAudioContent(data, mimeType) { - const provider = await this.getAiProvider(); - const isGemini = provider === 'gemini'; - if (!this.theirSttSession) { throw new Error('Their STT session not active'); } - const payload = isGemini + let modelInfo = this.modelInfo; + if (!modelInfo) { + console.warn('[SttService] modelInfo not found, fetching on-the-fly as a fallback...'); + modelInfo = await getCurrentModelInfo(null, { type: 'stt' }); + } + if (!modelInfo) { + throw new Error('STT model info could not be retrieved.'); + } + + const payload = modelInfo.provider === 'gemini' ? { audio: { data, mimeType: mimeType || 'audio/pcm;rate=24000' } } : data; From 013a033051dfe225483a811e9b1bb78cd3f338b5 Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Tue, 8 Jul 2025 16:06:46 +0900 Subject: [PATCH 43/52] stt error fixed --- src/features/listen/stt/sttService.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/features/listen/stt/sttService.js b/src/features/listen/stt/sttService.js index 68d8ef2..e11d579 100644 --- a/src/features/listen/stt/sttService.js +++ b/src/features/listen/stt/sttService.js @@ -74,7 +74,7 @@ class SttService { } flushMyCompletion() { - if (!this.myCompletionBuffer.trim()) return; + if (!this.modelInfo || !this.myCompletionBuffer.trim()) return; const finalText = this.myCompletionBuffer.trim(); @@ -102,7 +102,7 @@ class SttService { } flushTheirCompletion() { - if (!this.theirCompletionBuffer.trim()) return; + if (!this.modelInfo || !this.theirCompletionBuffer.trim()) return; const finalText = this.theirCompletionBuffer.trim(); @@ -176,6 +176,11 @@ class SttService { // console.log(`[SttService] Initializing STT for provider: ${modelInfo.provider}`); const handleMyMessage = message => { + if (!this.modelInfo) { + console.log('[SttService] Ignoring message - session already closed'); + return; + } + if (this.modelInfo.provider === 'gemini') { const text = message.serverContent?.inputTranscription?.text || ''; if (text && text.trim()) { @@ -217,6 +222,11 @@ class SttService { }; const handleTheirMessage = message => { + if (!this.modelInfo) { + console.log('[SttService] Ignoring message - session already closed'); + return; + } + if (this.modelInfo.provider === 'gemini') { const text = message.serverContent?.inputTranscription?.text || ''; if (text && text.trim()) { From 733ea7a0f673c1836e64c6ac972e317d0e763d72 Mon Sep 17 00:00:00 2001 From: samtiz Date: Tue, 8 Jul 2025 19:22:53 +0900 Subject: [PATCH 44/52] implemented AEC + guard stt error --- src/assets/aec.js | 2 +- src/assets/aec.wasm | Bin 113342 -> 0 bytes src/common/ai/providers/gemini.js | 9 +- src/common/ai/providers/openai.js | 16 +- src/features/listen/listenService.js | 16 +- src/features/listen/renderer/listenCapture.js | 249 ++++++------------ src/features/listen/stt/sttService.js | 2 + 7 files changed, 118 insertions(+), 176 deletions(-) delete mode 100755 src/assets/aec.wasm diff --git a/src/assets/aec.js b/src/assets/aec.js index 332ffea..bbeec18 100644 --- a/src/assets/aec.js +++ b/src/assets/aec.js @@ -4,7 +4,7 @@ var createAecModule = (() => { async function(moduleArg = {}) { var moduleRtn; -var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.initialized)FS.init();TTY.init();wasmExports["v"]();FS.ignorePermissions=false}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("aec.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["u"];updateMemoryViews();wasmTable=wasmExports["H"];assignWasmExports(wasmExports);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod,inst))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var exceptionLast=0;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var setTempRet0=val=>__emscripten_tempret_set(val);var findMatchingCatch=args=>{var thrown=exceptionLast;if(!thrown){setTempRet0(0);return 0}var info=new ExceptionInfo(thrown);info.set_adjusted_ptr(thrown);var thrownType=info.get_type();if(!thrownType){setTempRet0(0);return thrown}for(var caughtType of args){if(caughtType===0||caughtType===thrownType){break}var adjusted_ptr_addr=info.ptr+16;if(___cxa_can_catch(caughtType,thrownType,adjusted_ptr_addr)){setTempRet0(caughtType);return thrown}}setTempRet0(thrownType);return thrown};var ___cxa_find_matching_catch_2=()=>findMatchingCatch([]);var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var ___resumeException=ptr=>{if(!exceptionLast){exceptionLast=ptr}throw exceptionLast};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);function ___syscall_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd)+1;if(sizeabort("");var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.language||"C").replace("-","_")+".UTF-8";var env={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:lang,_:getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;var envp=0;for(var string of getEnvStrings()){var ptr=environ_buf+bufSize;HEAPU32[__environ+envp>>2]=ptr;bufSize+=stringToUTF8(string,ptr,Infinity)+1;envp+=4}return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;for(var string of strings){bufSize+=lengthBytesUTF8(string)+1}HEAPU32[penviron_buf_size>>2]=bufSize;return 0};var runtimeKeepaliveCounter=0;var keepRuntimeAlive=()=>noExitRuntime||runtimeKeepaliveCounter>0;var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){Module["onExit"]?.(code);ABORT=true}quit_(code,new ExitStatus(code))};var exitJS=(status,implicit)=>{EXITSTATUS=status;_proc_exit(status)};var _exit=exitJS;var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.slice(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.slice(0,-1)}return root+dir},basename:path=>path&&path.match(/([^\/]+|\/)\/*$/)[1],join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>view=>crypto.getRandomValues(view);var randomFill=view=>{(randomFill=initRandomFill())(view)};var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).slice(1);to=PATH_FS.resolve(to).slice(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var FS_stdin_getChar_buffer=[];var intArrayFromString=(stringy,dontAddNull,length)=>{var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array};var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output?.length>0){err(UTF8ArrayToString(tty.output));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16895,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.atime=node.mtime=node.ctime=Date.now();if(parent){parent.contents[name]=node;parent.atime=parent.mtime=parent.ctime=node.atime}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.atime);attr.mtime=new Date(node.mtime);attr.ctime=new Date(node.ctime);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){for(const key of["mode","atime","mtime","ctime"]){if(attr[key]!=null){node[key]=attr[key]}}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw MEMFS.doesNotExistError},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){if(FS.isDir(old_node.mode)){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}FS.hashRemoveNode(new_node)}delete old_node.parent.contents[old_node.name];new_dir.contents[new_name]=old_node;old_node.name=new_name;new_dir.ctime=new_dir.mtime=old_node.parent.ctime=old_node.parent.mtime=Date.now()},unlink(parent,name){delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},readdir(node){return[".","..",...Object.keys(node.contents)]},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var arrayBuffer=await readAsync(url);return new Uint8Array(arrayBuffer)};var FS_createDataFile=(...args)=>FS.createDataFile(...args);var getUniqueRunDependency=id=>id;var preloadPlugins=[];var FS_handledByPreloadPlugin=(byteArray,fullname,finish,onerror)=>{if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach(plugin=>{if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}});return handled};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}onload?.();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,()=>{onerror?.();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url).then(processData,onerror)}else{processData(url)}};var FS_modeStringToFlags=str=>{var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,filesystems:null,syncFSRequests:0,readFiles:{},ErrnoError:class{name="ErrnoError";constructor(errno){this.errno=errno}},FSStream:class{shared={};get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{node_ops={};stream_ops={};readMode=292|73;writeMode=146;mounted=null;constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.rdev=rdev;this.atime=this.mtime=this.ctime=Date.now()}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){if(!path){throw new FS.ErrnoError(44)}opts.follow_mount??=true;if(!PATH.isAbs(path)){path=FS.cwd()+"/"+path}linkloop:for(var nlinks=0;nlinks<40;nlinks++){var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){if(!FS.isDir(dir.mode)){return 54}try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&(512|64)){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},checkOpExists(op,err){if(!op){throw new FS.ErrnoError(err)}return op},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},doSetAttr(stream,node,attr){var setattr=stream?.stream_ops.setattr;var arg=setattr?stream:node;setattr??=node.node_ops.setattr;FS.checkOpExists(setattr,63);setattr(arg,attr)},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type,opts,mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name){throw new FS.ErrnoError(28)}if(name==="."||name===".."){throw new FS.ErrnoError(20)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},statfs(path){return FS.statfsNode(FS.lookupPath(path,{follow:true}).node)},statfsStream(stream){return FS.statfsNode(stream.node)},statfsNode(node){var rtn={bsize:4096,frsize:4096,blocks:1e6,bfree:5e5,bavail:5e5,files:FS.nextInode,ffree:FS.nextInode-1,fsid:42,flags:2,namelen:255};if(node.node_ops.statfs){Object.assign(rtn,node.node_ops.statfs(node.mount.opts.root))}return rtn},create(path,mode=438){mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode=511){mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var dir of dirs){if(!dir)continue;if(d||PATH.isAbs(path))d+="/";d+=dir;try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev(path,mode,dev){if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name);old_node.parent=new_dir}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var readdir=FS.checkOpExists(node.node_ops.readdir,54);return readdir(node)},unlink(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return link.node_ops.readlink(link)},stat(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;var getattr=FS.checkOpExists(node.node_ops.getattr,63);return getattr(node)},fstat(fd){var stream=FS.getStreamChecked(fd);var node=stream.node;var getattr=stream.stream_ops.getattr;var arg=getattr?stream:node;getattr??=node.node_ops.getattr;FS.checkOpExists(getattr,63);return getattr(arg)},lstat(path){return FS.stat(path,true)},doChmod(stream,node,mode,dontFollow){FS.doSetAttr(stream,node,{mode:mode&4095|node.mode&~4095,ctime:Date.now(),dontFollow})},chmod(path,mode,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChmod(null,node,mode,dontFollow)},lchmod(path,mode){FS.chmod(path,mode,true)},fchmod(fd,mode){var stream=FS.getStreamChecked(fd);FS.doChmod(stream,stream.node,mode,false)},doChown(stream,node,dontFollow){FS.doSetAttr(stream,node,{timestamp:Date.now(),dontFollow})},chown(path,uid,gid,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChown(null,node,dontFollow)},lchown(path,uid,gid){FS.chown(path,uid,gid,true)},fchown(fd,uid,gid){var stream=FS.getStreamChecked(fd);FS.doChown(stream,stream.node,false)},doTruncate(stream,node,len){if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}FS.doSetAttr(stream,node,{size:len,timestamp:Date.now()})},truncate(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}FS.doTruncate(null,node,len)},ftruncate(fd,len){var stream=FS.getStreamChecked(fd);if(len<0||(stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.doTruncate(stream,stream.node,len)},utime(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var setattr=FS.checkOpExists(node.node_ops.setattr,63);setattr(node,{atime,mtime})},open(path,flags,mode=438){if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;var isDirPath;if(typeof path=="object"){node=path}else{isDirPath=path.endsWith("/");var lookup=FS.lookupPath(path,{follow:!(flags&131072),noent_okay:true});node=lookup.node;path=lookup.path}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else if(isDirPath){throw new FS.ErrnoError(31)}else{node=FS.mknod(path,mode|511,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node,path:FS.getPath(node),flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(created){FS.chmod(node,mode&511)}if(Module["logReadFiles"]&&!(flags&1)){if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed(stream){return stream.fd===null},llseek(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},mmap(stream,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}if(!length){throw new FS.ErrnoError(28)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync(stream,buffer,offset,length,mmapFlags){if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){buf=UTF8ArrayToString(buf)}FS.close(stream);return buf},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){data=new Uint8Array(intArrayFromString(data,true))}if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length,llseek:()=>0});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomFill(randomBuffer);randomLeft=randomBuffer.byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16895,73);node.stream_ops={llseek:MEMFS.stream_ops.llseek};node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path},id:fd+1};ret.parent=ret;return ret},readdir(){return Array.from(FS.streams.entries()).filter(([k,v])=>v).map(([k,v])=>k.toString())}};return node}},{},"/proc/self/fd")},createStandardStreams(input,output,error){if(input){FS.createDevice("/dev","stdin",input)}else{FS.symlink("/dev/tty","/dev/stdin")}if(output){FS.createDevice("/dev","stdout",null,output)}else{FS.symlink("/dev/tty","/dev/stdout")}if(error){FS.createDevice("/dev","stderr",null,error)}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS}},init(input,output,error){FS.initialized=true;input??=Module["stdin"];output??=Module["stdout"];error??=Module["stderr"];FS.createStandardStreams(input,output,error)},quit(){FS.initialized=false;for(var stream of FS.streams){if(stream){FS.close(stream)}}},findObject(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath(parent,path,canRead,canWrite){parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){if(e.errno!=20)throw e}parent=current}return current},createFile(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile(parent,name,data,canRead,canWrite,canOwn){var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return dir+"/"+path},writeStat(buf,stat){HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAP32[buf+12>>2]=stat.uid;HEAP32[buf+16>>2]=stat.gid;HEAP32[buf+20>>2]=stat.rdev;HEAP64[buf+24>>3]=BigInt(stat.size);HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();HEAP64[buf+40>>3]=BigInt(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3*1e3;HEAP64[buf+56>>3]=BigInt(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3*1e3;HEAP64[buf+72>>3]=BigInt(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3*1e3;HEAP64[buf+88>>3]=BigInt(stat.ino);return 0},writeStatFs(buf,stats){HEAP32[buf+4>>2]=stats.bsize;HEAP32[buf+40>>2]=stats.bsize;HEAP32[buf+8>>2]=stats.blocks;HEAP32[buf+12>>2]=stats.bfree;HEAP32[buf+16>>2]=stats.bavail;HEAP32[buf+20>>2]=stats.files;HEAP32[buf+24>>2]=stats.ffree;HEAP32[buf+28>>2]=stats.fsid;HEAP32[buf+44>>2]=stats.flags;HEAP32[buf+36>>2]=stats.namelen},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>numINT53_MAX?NaN:Number(num);function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);HEAP64[newOffset>>3]=BigInt(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var wasmTableMirror=[];var wasmTable;var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();MEMFS.doesNotExistError=new FS.ErrnoError(44);MEMFS.doesNotExistError.stack="";{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["preloadPlugins"])preloadPlugins=Module["preloadPlugins"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}Module["ccall"]=ccall;Module["cwrap"]=cwrap;var _AecNew,_AecCancelEcho,_AecDestroy,_malloc,_free,_setThrew,__emscripten_tempret_set,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,___cxa_can_catch;function assignWasmExports(wasmExports){Module["_AecNew"]=_AecNew=wasmExports["w"];Module["_AecCancelEcho"]=_AecCancelEcho=wasmExports["x"];Module["_AecDestroy"]=_AecDestroy=wasmExports["y"];Module["_malloc"]=_malloc=wasmExports["z"];Module["_free"]=_free=wasmExports["A"];_setThrew=wasmExports["B"];__emscripten_tempret_set=wasmExports["C"];__emscripten_stack_restore=wasmExports["D"];__emscripten_stack_alloc=wasmExports["E"];_emscripten_stack_get_current=wasmExports["F"];___cxa_can_catch=wasmExports["G"]}var wasmImports={a:___cxa_find_matching_catch_2,q:___cxa_throw,b:___resumeException,p:___syscall_getcwd,r:__abort_js,t:_emscripten_resize_heap,n:_environ_get,o:_environ_sizes_get,k:_exit,s:_fd_close,l:_fd_seek,g:_fd_write,i:invoke_ii,f:invoke_iiii,m:invoke_iiiiii,c:invoke_vi,d:invoke_vii,e:invoke_viii,j:invoke_viiii,h:invoke_viiiii};var wasmExports=await createWasm();function invoke_vi(index,a1){var sp=stackSave();try{getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viii(index,a1,a2,a3){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_vii(index,a1,a2){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viiii(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iiii(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_ii(index,a1){var sp=stackSave();try{return getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iiiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})} +var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";var readAsync,readBinary;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.initialized)FS.init();TTY.init();wasmExports["v"]();FS.ignorePermissions=false}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return base64Decode("AGFzbQEAAAABhgETYAJ/fwF/YAN/f38Bf2ACf38AYAN/f38AYAF/AGAEf39/fwBgAX8Bf2AFf39/f38AYAAAYAZ/f39/f38AYAR/f39/AX9gBX9/f39/AX9gAAF/YAZ/f39/f38Bf2AHf39/f39/fwBgBH9+f38Bf2AHf39/f39/fwF/YAJ+fwF/YAN/fn8BfgJ5FAFhAWEADAFhAWIABAFhAWMAAgFhAWQAAwFhAWUABQFhAWYACgFhAWcACgFhAWgACQFhAWkAAAFhAWoABwFhAWsABAFhAWwADwFhAW0ADQFhAW4AAAFhAW8AAAFhAXAAAAFhAXEAAwFhAXIACAFhAXMABgFhAXQABgPKAcgBBAYCDQYHAQEACAMECAsDBwMGCAYDAwEBBAcEAwMDAgICBQAACwEAAQMDBAoEBAQABAIDARABBgAOAwADAAMHAAMCAwMGBAQEBgQAAw4HAgUDBgcLBAMAAgYFBAYECBEGAgQBBAAAAAUDBggIAwIAAwAFAAAAAAcABAIMBAcGCgQCAgUFAAACAgIAAgIDAgAFBQEBAwUFBQUFAAAEBAAAAQAAAgYEBxIEAAAAAAAAAQAAAAAAAAAAAAYCAgYCAQkJBwcFBQEBBAgEBQFwAX9/BQYBAYICggIGCAF/AUHg+QQLB0MOAXUCAAF2ANsBAXcAkgEBeACQAQF5AI8BAXoAGAFBABQBQgCNAQFDAIwBAUQA2gEBRQCRAQFGAI4BAUcA0QEBSAEACdQBAQBBAQt+zAHCAboBS05oiQFQiwGGAYQBOYgBhwGFASQ0gwFVggF+fURwcNkB0gHUAdcBRNMB1QHWAc8B0AFOd2+wAWmAAa8BGxatAVK5AUAZQJUBlAG3AT6KAS6TAXVtIUo2sgGiAWZAHqABowEfxgFLuwGhAcgBQbEBrgHKAcQBxwEfdsEBvgGmAcMBvwGlAcABvQFBswG0AbwBxQGYAbUByQHLAUGsAasBc2uqAakBpwGXAZYBc2ukAagBzQHOAZkBnAGbAZoBuAGdAZ8BngG2AVYMARwK54YGyAH9CwEIfwJAIABFDQAgAEEIayIDIABBBGsoAgAiAkF4cSIAaiEFAkAgAkEBcQ0AIAJBAnFFDQEgAyADKAIAIgRrIgNB1PMAKAIASQ0BIAAgBGohAAJAAkACQEHY8wAoAgAgA0cEQCADKAIMIQEgBEH/AU0EQCABIAMoAggiAkcNAkHE8wBBxPMAKAIAQX4gBEEDdndxNgIADAULIAMoAhghByABIANHBEAgAygCCCICIAE2AgwgASACNgIIDAQLIAMoAhQiAgR/IANBFGoFIAMoAhAiAkUNAyADQRBqCyEEA0AgBCEGIAIiAUEUaiEEIAEoAhQiAg0AIAFBEGohBCABKAIQIgINAAsgBkEANgIADAMLIAUoAgQiAkEDcUEDRw0DQczzACAANgIAIAUgAkF+cTYCBCADIABBAXI2AgQgBSAANgIADwsgAiABNgIMIAEgAjYCCAwCC0EAIQELIAdFDQACQCADKAIcIgRBAnRB9PUAaiICKAIAIANGBEAgAiABNgIAIAENAUHI8wBByPMAKAIAQX4gBHdxNgIADAILAkAgAyAHKAIQRgRAIAcgATYCEAwBCyAHIAE2AhQLIAFFDQELIAEgBzYCGCADKAIQIgIEQCABIAI2AhAgAiABNgIYCyADKAIUIgJFDQAgASACNgIUIAIgATYCGAsgAyAFTw0AIAUoAgQiBEEBcUUNAAJAAkACQAJAIARBAnFFBEBB3PMAKAIAIAVGBEBB3PMAIAM2AgBB0PMAQdDzACgCACAAaiIANgIAIAMgAEEBcjYCBCADQdjzACgCAEcNBkHM8wBBADYCAEHY8wBBADYCAA8LQdjzACgCACIHIAVGBEBB2PMAIAM2AgBBzPMAQczzACgCACAAaiIANgIAIAMgAEEBcjYCBCAAIANqIAA2AgAPCyAEQXhxIABqIQAgBSgCDCEBIARB/wFNBEAgBSgCCCICIAFGBEBBxPMAQcTzACgCAEF+IARBA3Z3cTYCAAwFCyACIAE2AgwgASACNgIIDAQLIAUoAhghCCABIAVHBEAgBSgCCCICIAE2AgwgASACNgIIDAMLIAUoAhQiAgR/IAVBFGoFIAUoAhAiAkUNAiAFQRBqCyEEA0AgBCEGIAIiAUEUaiEEIAEoAhQiAg0AIAFBEGohBCABKAIQIgINAAsgBkEANgIADAILIAUgBEF+cTYCBCADIABBAXI2AgQgACADaiAANgIADAMLQQAhAQsgCEUNAAJAIAUoAhwiBEECdEH09QBqIgIoAgAgBUYEQCACIAE2AgAgAQ0BQcjzAEHI8wAoAgBBfiAEd3E2AgAMAgsCQCAFIAgoAhBGBEAgCCABNgIQDAELIAggATYCFAsgAUUNAQsgASAINgIYIAUoAhAiAgRAIAEgAjYCECACIAE2AhgLIAUoAhQiAkUNACABIAI2AhQgAiABNgIYCyADIABBAXI2AgQgACADaiAANgIAIAMgB0cNAEHM8wAgADYCAA8LIABB/wFNBEAgAEF4cUHs8wBqIQICf0HE8wAoAgAiBEEBIABBA3Z0IgBxRQRAQcTzACAAIARyNgIAIAIMAQsgAigCCAshACACIAM2AgggACADNgIMIAMgAjYCDCADIAA2AggPC0EfIQEgAEH///8HTQRAIABBJiAAQQh2ZyICa3ZBAXEgAkEBdGtBPmohAQsgAyABNgIcIANCADcCECABQQJ0QfT1AGohBAJ/AkACf0HI8wAoAgAiBkEBIAF0IgJxRQRAQcjzACACIAZyNgIAIAQgAzYCAEEYIQFBCAwBCyAAQRkgAUEBdmtBACABQR9HG3QhASAEKAIAIQQDQCAEIgIoAgRBeHEgAEYNAiABQR12IQQgAUEBdCEBIAIgBEEEcWoiBigCECIEDQALIAYgAzYCEEEYIQEgAiEEQQgLIQAgAyICDAELIAIoAggiBCADNgIMIAIgAzYCCEEYIQBBCCEBQQALIQYgASADaiAENgIAIAMgAjYCDCAAIANqIAY2AgBB5PMAQeTzACgCAEEBayIAQX8gABs2AgALC0wCAX8BfgJAAn9BACAARQ0AGiAArSICpyIBIABBAXJBgIAESQ0AGiABCyIBEBgiAEUNACAAQQRrLQAAQQNxRQ0AIABBACABEE8LIAALKgEBfyMAQRBrIgIkACACQQE7AQwgAiABNgIIIAIgADYCBCACQQRqEGgAC84FAgd/AX4CfyABRQRAIAAoAgghB0EtIQsgBUEBagwBC0ErQYCAxAAgACgCCCIHQYCAgAFxIgEbIQsgAUEVdiAFagshCQJAIAdBgICABHFFBEBBACECDAELAkAgA0EQTwRAIAIgAxBTIQEMAQsgA0UEQEEAIQEMAQsgA0EDcSEKAkAgA0EESQRAQQAhAQwBCyADQQxxIQxBACEBA0AgASACIAhqIgYsAABBv39KaiAGLAABQb9/SmogBiwAAkG/f0pqIAYsAANBv39KaiEBIAwgCEEEaiIIRw0ACwsgCkUNACACIAhqIQYDQCABIAYsAABBv39KaiEBIAZBAWohBiAKQQFrIgoNAAsLIAEgCWohCQsCQCAALwEMIgggCUsEQAJAAkAgB0GAgIAIcUUEQCAIIAlrIQhBACEBQQAhCQJAAkACQCAHQR12QQNxQQFrDgMAAQACCyAIIQkMAQsgCEH+/wNxQQF2IQkLIAdB////AHEhCiAAKAIEIQcgACgCACEAA0AgAUH//wNxIAlB//8DcU8NAkEBIQYgAUEBaiEBIAAgCiAHKAIQEQAARQ0ACwwECyAAIAApAggiDadBgICA/3lxQbCAgIACcjYCCEEBIQYgACgCACIHIAAoAgQiCiALIAIgAxA4DQNBACEBIAggCWtB//8DcSECA0AgAUH//wNxIAJPDQIgAUEBaiEBIAdBMCAKKAIQEQAARQ0ACwwDC0EBIQYgACAHIAsgAiADEDgNAiAAIAQgBSAHKAIMEQEADQJBACEBIAggCWtB//8DcSECA0AgAUH//wNxIgMgAkkhBiACIANNDQMgAUEBaiEBIAAgCiAHKAIQEQAARQ0ACwwCCyAHIAQgBSAKKAIMEQEADQEgACANNwIIQQAPC0EBIQYgACgCACIBIAAoAgQiACALIAIgAxA4DQAgASAEIAUgACgCDBEBACEGCyAGC9soAQt/IwBBEGsiCiQAAkACQAJAAkACQAJAAkACQAJAAkAgAEH0AU0EQEHE8wAoAgAiBEEQIABBC2pB+ANxIABBC0kbIgZBA3YiAHYiAUEDcQRAAkAgAUF/c0EBcSAAaiICQQN0IgFB7PMAaiIAIAFB9PMAaigCACIBKAIIIgVGBEBBxPMAIARBfiACd3E2AgAMAQsgBSAANgIMIAAgBTYCCAsgAUEIaiEAIAEgAkEDdCICQQNyNgIEIAEgAmoiASABKAIEQQFyNgIEDAsLIAZBzPMAKAIAIghNDQEgAQRAAkBBAiAAdCICQQAgAmtyIAEgAHRxaCIBQQN0IgBB7PMAaiICIABB9PMAaigCACIAKAIIIgVGBEBBxPMAIARBfiABd3EiBDYCAAwBCyAFIAI2AgwgAiAFNgIICyAAIAZBA3I2AgQgACAGaiIHIAFBA3QiASAGayIFQQFyNgIEIAAgAWogBTYCACAIBEAgCEF4cUHs8wBqIQFB2PMAKAIAIQICfyAEQQEgCEEDdnQiA3FFBEBBxPMAIAMgBHI2AgAgAQwBCyABKAIICyEDIAEgAjYCCCADIAI2AgwgAiABNgIMIAIgAzYCCAsgAEEIaiEAQdjzACAHNgIAQczzACAFNgIADAsLQcjzACgCACILRQ0BIAtoQQJ0QfT1AGooAgAiAigCBEF4cSAGayEDIAIhAQNAAkAgASgCECIARQRAIAEoAhQiAEUNAQsgACgCBEF4cSAGayIBIAMgASADSSIBGyEDIAAgAiABGyECIAAhAQwBCwsgAigCGCEJIAIgAigCDCIARwRAIAIoAggiASAANgIMIAAgATYCCAwKCyACKAIUIgEEfyACQRRqBSACKAIQIgFFDQMgAkEQagshBQNAIAUhByABIgBBFGohBSAAKAIUIgENACAAQRBqIQUgACgCECIBDQALIAdBADYCAAwJC0F/IQYgAEG/f0sNACAAQQtqIgFBeHEhBkHI8wAoAgAiB0UNAEEfIQhBACAGayEDIABB9P//B00EQCAGQSYgAUEIdmciAGt2QQFxIABBAXRrQT5qIQgLAkACQAJAIAhBAnRB9PUAaigCACIBRQRAQQAhAAwBC0EAIQAgBkEZIAhBAXZrQQAgCEEfRxt0IQIDQAJAIAEoAgRBeHEgBmsiBCADTw0AIAEhBSAEIgMNAEEAIQMgASEADAMLIAAgASgCFCIEIAQgASACQR12QQRxaigCECIBRhsgACAEGyEAIAJBAXQhAiABDQALCyAAIAVyRQRAQQAhBUECIAh0IgBBACAAa3IgB3EiAEUNAyAAaEECdEH09QBqKAIAIQALIABFDQELA0AgACgCBEF4cSAGayICIANJIQEgAiADIAEbIQMgACAFIAEbIQUgACgCECIBBH8gAQUgACgCFAsiAA0ACwsgBUUNACADQczzACgCACAGa08NACAFKAIYIQggBSAFKAIMIgBHBEAgBSgCCCIBIAA2AgwgACABNgIIDAgLIAUoAhQiAQR/IAVBFGoFIAUoAhAiAUUNAyAFQRBqCyECA0AgAiEEIAEiAEEUaiECIAAoAhQiAQ0AIABBEGohAiAAKAIQIgENAAsgBEEANgIADAcLIAZBzPMAKAIAIgVNBEBB2PMAKAIAIQACQCAFIAZrIgFBEE8EQCAAIAZqIgIgAUEBcjYCBCAAIAVqIAE2AgAgACAGQQNyNgIEDAELIAAgBUEDcjYCBCAAIAVqIgEgASgCBEEBcjYCBEEAIQJBACEBC0HM8wAgATYCAEHY8wAgAjYCACAAQQhqIQAMCQsgBkHQ8wAoAgAiAkkEQEHQ8wAgAiAGayIBNgIAQdzzAEHc8wAoAgAiACAGaiICNgIAIAIgAUEBcjYCBCAAIAZBA3I2AgQgAEEIaiEADAkLQQAhACAGQS9qIgMCf0Gc9wAoAgAEQEGk9wAoAgAMAQtBqPcAQn83AgBBoPcAQoCggICAgAQ3AgBBnPcAIApBDGpBcHFB2KrVqgVzNgIAQbD3AEEANgIAQYD3AEEANgIAQYAgCyIBaiIEQQAgAWsiB3EiASAGTQ0IQfz2ACgCACIFBEBB9PYAKAIAIgggAWoiCSAITQ0JIAUgCUkNCQsCQEGA9wAtAABBBHFFBEACQAJAAkACQEHc8wAoAgAiBQRAQYT3ACEAA0AgACgCACIIIAVNBEAgBSAIIAAoAgRqSQ0DCyAAKAIIIgANAAsLQQAQJyICQX9GDQMgASEEQaD3ACgCACIAQQFrIgUgAnEEQCABIAJrIAIgBWpBACAAa3FqIQQLIAQgBk0NA0H89gAoAgAiAARAQfT2ACgCACIFIARqIgcgBU0NBCAAIAdJDQQLIAQQJyIAIAJHDQEMBQsgBCACayAHcSIEECciAiAAKAIAIAAoAgRqRg0BIAIhAAsgAEF/Rg0BIAZBMGogBE0EQCAAIQIMBAtBpPcAKAIAIgIgAyAEa2pBACACa3EiAhAnQX9GDQEgAiAEaiEEIAAhAgwDCyACQX9HDQILQYD3AEGA9wAoAgBBBHI2AgALIAEQJyECQQAQJyEAIAJBf0YNBSAAQX9GDQUgACACTQ0FIAAgAmsiBCAGQShqTQ0FC0H09gBB9PYAKAIAIARqIgA2AgBB+PYAKAIAIABJBEBB+PYAIAA2AgALAkBB3PMAKAIAIgMEQEGE9wAhAANAIAIgACgCACIBIAAoAgQiBWpGDQIgACgCCCIADQALDAQLQdTzACgCACIAQQAgACACTRtFBEBB1PMAIAI2AgALQQAhAEGI9wAgBDYCAEGE9wAgAjYCAEHk8wBBfzYCAEHo8wBBnPcAKAIANgIAQZD3AEEANgIAA0AgAEEDdCIBQfTzAGogAUHs8wBqIgU2AgAgAUH48wBqIAU2AgAgAEEBaiIAQSBHDQALQdDzACAEQShrIgBBeCACa0EHcSIBayIFNgIAQdzzACABIAJqIgE2AgAgASAFQQFyNgIEIAAgAmpBKDYCBEHg8wBBrPcAKAIANgIADAQLIAIgA00NAiABIANLDQIgACgCDEEIcQ0CIAAgBCAFajYCBEHc8wAgA0F4IANrQQdxIgBqIgE2AgBB0PMAQdDzACgCACAEaiICIABrIgA2AgAgASAAQQFyNgIEIAIgA2pBKDYCBEHg8wBBrPcAKAIANgIADAMLQQAhAAwGC0EAIQAMBAtB1PMAKAIAIAJLBEBB1PMAIAI2AgALIAIgBGohBUGE9wAhAAJAA0AgBSAAKAIAIgFHBEAgACgCCCIADQEMAgsLIAAtAAxBCHFFDQMLQYT3ACEAA0ACQCAAKAIAIgEgA00EQCADIAEgACgCBGoiBUkNAQsgACgCCCEADAELC0HQ8wAgBEEoayIAQXggAmtBB3EiAWsiBzYCAEHc8wAgASACaiIBNgIAIAEgB0EBcjYCBCAAIAJqQSg2AgRB4PMAQaz3ACgCADYCACADIAVBJyAFa0EHcWpBL2siACAAIANBEGpJGyIBQRs2AgQgAUGM9wApAgA3AhAgAUGE9wApAgA3AghBjPcAIAFBCGo2AgBBiPcAIAQ2AgBBhPcAIAI2AgBBkPcAQQA2AgAgAUEYaiEAA0AgAEEHNgIEIABBCGogAEEEaiEAIAVJDQALIAEgA0YNACABIAEoAgRBfnE2AgQgAyABIANrIgJBAXI2AgQgASACNgIAAn8gAkH/AU0EQCACQXhxQezzAGohAAJ/QcTzACgCACIBQQEgAkEDdnQiAnFFBEBBxPMAIAEgAnI2AgAgAAwBCyAAKAIICyEBIAAgAzYCCCABIAM2AgxBDCECQQgMAQtBHyEAIAJB////B00EQCACQSYgAkEIdmciAGt2QQFxIABBAXRrQT5qIQALIAMgADYCHCADQgA3AhAgAEECdEH09QBqIQECQAJAQcjzACgCACIFQQEgAHQiBHFFBEBByPMAIAQgBXI2AgAgASADNgIADAELIAJBGSAAQQF2a0EAIABBH0cbdCEAIAEoAgAhBQNAIAUiASgCBEF4cSACRg0CIABBHXYhBSAAQQF0IQAgASAFQQRxaiIEKAIQIgUNAAsgBCADNgIQCyADIAE2AhhBCCECIAMiASEAQQwMAQsgASgCCCIAIAM2AgwgASADNgIIIAMgADYCCEEAIQBBGCECQQwLIANqIAE2AgAgAiADaiAANgIAC0HQ8wAoAgAiACAGTQ0AQdDzACAAIAZrIgE2AgBB3PMAQdzzACgCACIAIAZqIgI2AgAgAiABQQFyNgIEIAAgBkEDcjYCBCAAQQhqIQAMBAtBwPMAQTA2AgBBACEADAMLIAAgAjYCACAAIAAoAgQgBGo2AgQgAkF4IAJrQQdxaiIIIAZBA3I2AgQgAUF4IAFrQQdxaiIEIAYgCGoiA2shBwJAQdzzACgCACAERgRAQdzzACADNgIAQdDzAEHQ8wAoAgAgB2oiADYCACADIABBAXI2AgQMAQtB2PMAKAIAIARGBEBB2PMAIAM2AgBBzPMAQczzACgCACAHaiIANgIAIAMgAEEBcjYCBCAAIANqIAA2AgAMAQsgBCgCBCIAQQNxQQFGBEAgAEF4cSEJIAQoAgwhAgJAIABB/wFNBEAgBCgCCCIBIAJGBEBBxPMAQcTzACgCAEF+IABBA3Z3cTYCAAwCCyABIAI2AgwgAiABNgIIDAELIAQoAhghBgJAIAIgBEcEQCAEKAIIIgAgAjYCDCACIAA2AggMAQsCQCAEKAIUIgAEfyAEQRRqBSAEKAIQIgBFDQEgBEEQagshAQNAIAEhBSAAIgJBFGohASAAKAIUIgANACACQRBqIQEgAigCECIADQALIAVBADYCAAwBC0EAIQILIAZFDQACQCAEKAIcIgBBAnRB9PUAaiIBKAIAIARGBEAgASACNgIAIAINAUHI8wBByPMAKAIAQX4gAHdxNgIADAILAkAgBCAGKAIQRgRAIAYgAjYCEAwBCyAGIAI2AhQLIAJFDQELIAIgBjYCGCAEKAIQIgAEQCACIAA2AhAgACACNgIYCyAEKAIUIgBFDQAgAiAANgIUIAAgAjYCGAsgByAJaiEHIAQgCWoiBCgCBCEACyAEIABBfnE2AgQgAyAHQQFyNgIEIAMgB2ogBzYCACAHQf8BTQRAIAdBeHFB7PMAaiEAAn9BxPMAKAIAIgFBASAHQQN2dCICcUUEQEHE8wAgASACcjYCACAADAELIAAoAggLIQEgACADNgIIIAEgAzYCDCADIAA2AgwgAyABNgIIDAELQR8hAiAHQf///wdNBEAgB0EmIAdBCHZnIgBrdkEBcSAAQQF0a0E+aiECCyADIAI2AhwgA0IANwIQIAJBAnRB9PUAaiEAAkACQEHI8wAoAgAiAUEBIAJ0IgVxRQRAQcjzACABIAVyNgIAIAAgAzYCAAwBCyAHQRkgAkEBdmtBACACQR9HG3QhAiAAKAIAIQEDQCABIgAoAgRBeHEgB0YNAiACQR12IQEgAkEBdCECIAAgAUEEcWoiBSgCECIBDQALIAUgAzYCEAsgAyAANgIYIAMgAzYCDCADIAM2AggMAQsgACgCCCIBIAM2AgwgACADNgIIIANBADYCGCADIAA2AgwgAyABNgIICyAIQQhqIQAMAgsCQCAIRQ0AAkAgBSgCHCIBQQJ0QfT1AGoiAigCACAFRgRAIAIgADYCACAADQFByPMAIAdBfiABd3EiBzYCAAwCCwJAIAUgCCgCEEYEQCAIIAA2AhAMAQsgCCAANgIUCyAARQ0BCyAAIAg2AhggBSgCECIBBEAgACABNgIQIAEgADYCGAsgBSgCFCIBRQ0AIAAgATYCFCABIAA2AhgLAkAgA0EPTQRAIAUgAyAGaiIAQQNyNgIEIAAgBWoiACAAKAIEQQFyNgIEDAELIAUgBkEDcjYCBCAFIAZqIgQgA0EBcjYCBCADIARqIAM2AgAgA0H/AU0EQCADQXhxQezzAGohAAJ/QcTzACgCACIBQQEgA0EDdnQiAnFFBEBBxPMAIAEgAnI2AgAgAAwBCyAAKAIICyEBIAAgBDYCCCABIAQ2AgwgBCAANgIMIAQgATYCCAwBC0EfIQAgA0H///8HTQRAIANBJiADQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAAsgBCAANgIcIARCADcCECAAQQJ0QfT1AGohAQJAAkAgB0EBIAB0IgJxRQRAQcjzACACIAdyNgIAIAEgBDYCACAEIAE2AhgMAQsgA0EZIABBAXZrQQAgAEEfRxt0IQAgASgCACEBA0AgASICKAIEQXhxIANGDQIgAEEddiEBIABBAXQhACACIAFBBHFqIgcoAhAiAQ0ACyAHIAQ2AhAgBCACNgIYCyAEIAQ2AgwgBCAENgIIDAELIAIoAggiACAENgIMIAIgBDYCCCAEQQA2AhggBCACNgIMIAQgADYCCAsgBUEIaiEADAELAkAgCUUNAAJAIAIoAhwiAUECdEH09QBqIgUoAgAgAkYEQCAFIAA2AgAgAA0BQcjzACALQX4gAXdxNgIADAILAkAgAiAJKAIQRgRAIAkgADYCEAwBCyAJIAA2AhQLIABFDQELIAAgCTYCGCACKAIQIgEEQCAAIAE2AhAgASAANgIYCyACKAIUIgFFDQAgACABNgIUIAEgADYCGAsCQCADQQ9NBEAgAiADIAZqIgBBA3I2AgQgACACaiIAIAAoAgRBAXI2AgQMAQsgAiAGQQNyNgIEIAIgBmoiBSADQQFyNgIEIAMgBWogAzYCACAIBEAgCEF4cUHs8wBqIQBB2PMAKAIAIQECf0EBIAhBA3Z0IgcgBHFFBEBBxPMAIAQgB3I2AgAgAAwBCyAAKAIICyEEIAAgATYCCCAEIAE2AgwgASAANgIMIAEgBDYCCAtB2PMAIAU2AgBBzPMAIAM2AgALIAJBCGohAAsgCkEQaiQAIAAL+AECBH8BfiMAQSBrIgUkAAJAAkAgASABIAJqIgJLBEBBACEBDAELQQAhASADIARqQQFrQQAgA2txrSACIAAoAgAiB0EBdCIGIAIgBksbIgJBCEEEIARBAUYbIgYgAiAGSxsiBq1+IglCIIhCAFINACAJpyIIQYCAgIB4IANrSw0AQQAhAiAFIAcEfyAFIAQgB2w2AhwgBSAAKAIENgIUIAMFQQALNgIYIAVBCGogAyAIIAVBFGoQNSAFKAIIQQFHDQEgBSgCECECIAUoAgwhAQsgASACQbznABAkAAsgBSgCDCEBIAAgBjYCACAAIAE2AgQgBUEgaiQAC3QBAX8gAkUEQCAAKAIEIAEoAgRGDwsgACABRgRAQQEPCyABKAIEIgItAAAhAQJAIAAoAgQiAy0AACIARQ0AIAAgAUcNAANAIAItAAEhASADLQABIgBFDQEgAkEBaiECIANBAWohAyAAIAFGDQALCyAAIAFGC5wEAQh/IwBBEGsiAyQAIAMgATYCBCADIAA2AgAgA0KggICADjcCCAJ/AkACQAJAIAIoAhAiCQRAIAIoAhQiAA0BDAILIAIoAgwiAEUNASACKAIIIgEgAEEDdGohBCAAQQFrQf////8BcUEBaiEGIAIoAgAhAANAAkAgACgCBCIFRQ0AIAMoAgAgACgCACAFIAMoAgQoAgwRAQBFDQBBAQwFC0EBIAEoAgAgAyABKAIEEQAADQQaIABBCGohACAEIAFBCGoiAUcNAAsMAgsgAEEYbCEKIABBAWtB/////wFxQQFqIQYgAigCCCEEIAIoAgAhAANAAkAgACgCBCIBRQ0AIAMoAgAgACgCACABIAMoAgQoAgwRAQBFDQBBAQwEC0EAIQdBACEIAkACQAJAIAUgCWoiAS8BCEEBaw4CAQIACyABLwEKIQgMAQsgBCABKAIMQQN0ai8BBCEICwJAAkACQCABLwEAQQFrDgIBAgALIAEvAQIhBwwBCyAEIAEoAgRBA3RqLwEEIQcLIAMgBzsBDiADIAg7AQwgAyABKAIUNgIIQQEgBCABKAIQQQN0aiIBKAIAIAMgASgCBBEAAA0DGiAAQQhqIQAgBUEYaiIFIApHDQALDAELCwJAIAYgAigCBE8NACADKAIAIAIoAgAgBkEDdGoiACgCACAAKAIEIAMoAgQoAgwRAQBFDQBBAQwBC0EACyADQRBqJAALUgEBfyMAQRBrIgIkAAJ/IAFBCE0gACABT3FFBEAgAkEANgIMIAJBDGpBBCABIAFBBE0bIAAQRyEAQQAgAigCDCAAGwwBCyAAEBgLIAJBEGokAAsFABB/AAuVAwECfyMAQTBrIgMkAEH4+ABBADYCACADQQQ6AAggAyABNgIQQSsgA0EIakGE6AAgAhAFIQFB+PgAKAIAIQJB+PgAQQA2AgACQAJAIAJBAUYNAAJAAkAgAQRAIAMtAAhBBEcNAUH4+ABBADYCACADQQA2AiggA0IENwIgIANBuOoANgIYIANBATYCHEEsIANBGGpBwOoAEANB+PgAKAIAQfj4AEEANgIAQQFGDQMACyAAQQQ6AAAgAy0ACCIAQQRGDQEgAEEDRw0BIAMoAgwiAigCACEEAkAgAigCBCIBKAIAIgAEQEH4+ABBADYCACAAIAQQAkH4+AAoAgBB+PgAQQA2AgBBAUYNAQsgASgCBARAIAEoAggaIAQQFAsgAhAUDAILEAAhACABKAIEBEAgASgCCBogBBAUCyACEBQMAwsgACADKQMINwIACyADQTBqJAAPCxAAIQAgAy0ACEEERg0AQfj4AEEANgIAQSUgA0EIahACQfj4ACgCAEH4+ABBADYCAEEBRw0AEAAaECAACyAAEAEACxEAIAAtAABBBEcEQCAAEHcLC0YBAX8jAEEgayIAJAAgAEEANgIQIABBATYCBCAAQgQ3AgggAEEkNgIcIABBqxo2AhggACAAQRhqNgIAIABBAUHk4gAQTQALwQIBBH8jAEEgayIFJABBASEHAkAgAC0ABA0AIAAtAAUhCCAAKAIAIgYtAApBgAFxRQRAIAYoAgBBrBtBqRsgCEEBcSIIG0ECQQMgCBsgBigCBCgCDBEBAA0BIAYoAgAgASACIAYoAgQoAgwRAQANASAGKAIAQaMbQQIgBigCBCgCDBEBAA0BIAMgBiAEKAIMEQAAIQcMAQsgCEEBcUUEQCAGKAIAQa4bQQMgBigCBCgCDBEBAA0BCyAFQQE6AA8gBUHM4wA2AhQgBSAGKQIANwIAIAUgBikCCDcCGCAFIAVBD2o2AgggBSAFNgIQIAUgASACEDkNACAFQaMbQQIQOQ0AIAMgBUEQaiAEKAIMEQAADQAgBSgCEEGxG0ECIAUoAhQoAgwRAQAhBwsgAEEBOgAFIAAgBzoABCAFQSBqJAAgAAuzAgEEfyMAQRBrIgUkACAFIAI2AgwjAEHQAWsiAyQAIAMgAjYCzAEgA0GgAWoiAkEAQSj8CwAgAyADKALMATYCyAECQEEAIAEgA0HIAWogA0HQAGogAhBnQQBIDQAgACgCTEEASCAAIAAoAgAiBkFfcTYCAAJ/AkACQCAAKAIwRQRAIABB0AA2AjAgAEEANgIcIABCADcDECAAKAIsIQQgACADNgIsDAELIAAoAhANAQtBfyAAEGwNARoLIAAgASADQcgBaiADQdAAaiADQaABahBnCyEBIAQEfyAAQQBBACAAKAIkEQEAGiAAQQA2AjAgACAENgIsIABBADYCHCAAKAIUGiAAQgA3AxBBAAUgAQsaIAAgACgCACAGQSBxcjYCAA0ACyADQdABaiQAIAVBEGokAAtqAQF/IwBBgAJrIgUkAAJAIAIgA0wNACAEQYDABHENACAFIAEgAiADayIDQYACIANBgAJJIgEbEE8gAUUEQANAIAAgBUGAAhApIANBgAJrIgNB/wFLDQALCyAAIAUgAxApCyAFQYACaiQACz8AIAAEQCAAIAEQNAALIwBBIGsiACQAIABBADYCGCAAQQE2AgwgAEIENwIQIABB4OUANgIIIABBCGogAhAWAAt9AQN/AkACQCAAIgFBA3FFDQAgAS0AAEUEQEEADwsDQCABQQFqIgFBA3FFDQEgAS0AAA0ACwwBCwNAIAEiAkEEaiEBQYCChAggAigCACIDayADckGAgYKEeHFBgIGChHhGDQALA0AgAiIBQQFqIQIgAS0AAA0ACwsgASAAawtGAQF/IwBBIGsiACQAIABBADYCECAAQQE2AgQgAEIENwIIIABBJjYCHCAAQYUaNgIYIAAgAEEYajYCACAAQQBB1OIAEE0AC1IBAn9BuOEAKAIAIgEgAEEHakF4cSICaiEAAkAgAkEAIAAgAU0bRQRAIAA/AEEQdE0NASAAEBMNAQtBwPMAQTA2AgBBfw8LQbjhACAANgIAIAELhgoBEH8CQCAAKAIIIgdBAEwNACAHQQFHBEAgAUECaiEMIAdB/v///wdxIQoDQEEAIAwgBUEBdCIJai4BACIEayILIARBACABIAlqLgEAIglrIgggCSADwSIDIAMgCUgbIgMgAyAISBvBIgMgAyAESBsiAyADIAtIGyEDIAVBAmohBSAGQQJqIgYgCkcNAAsLIAdBAXEEQEEAIAEgBUEBdGouAQAiBWsiBiAFIAPBIgMgAyAFSBsiAyADIAZIGyEDC0EAIQZBACEFAkAgA8FBgP0ASg0AIANB//8DcUUNAANAIAVBAWohBSADQQF0wSIDQYD9AEoNASADDQALCyAHQQRPBEAgAUEGaiEJIAFBBGohDCABQQJqIQogB0H8////B3EhC0EAIQQDQCABIAZBAXQiA2oiCCAILwEAIAV0OwEAIAMgCmoiCCAILwEAIAV0OwEAIAMgDGoiCCAILwEAIAV0OwEAIAMgCWoiAyADLwEAIAV0OwEAIAZBBGohBiAEQQRqIgQgC0cNAAsLIAdBA3EiB0UNAEEAIQMDQCABIAZBAXRqIgQgBC8BACAFdDsBACAGQQFqIQYgA0EBaiIDIAdHDQALCwJAIAAoAgAiAygCACIHKAIERQRAIAcoAgAhBiAHIAEgAygCBBBfIAIgAygCBCIHLgECQf7/AWxBgIACakEQdSIEIAcuAQBB/v8BbEGAgAJqQRB1IglqOwEAIAIgBkECdGpBAmsgCSAEazsBACAGQQJOBEAgBkEBdiEJIAMoAgghDEEBIQMDQCACIANBAnQiBGoiCkECayAHIAYgA2tBAnQiC2oiCC4BACINIAQgB2oiDi4BACIPakENdEGAgAFqIhAgDyANa0EBdSINIAQgDGoiBC4BACIPbCAILgECIgggDi4BAiIOakEPdEGAgAJqQRB1IhEgBC4BAiIEbGtBAXUiEmpBD3Y7AQAgCiAOIAhrQQ10IgogDyARbCAEIA1sakEBdSIEakGAgAFqQQ92OwEAIAIgC2oiCyAEIAprQYCAAWpBD3Y7AQAgC0ECayAQIBJrQQ92OwEAIAMgCUcgA0EBaiEDDQALCwwBC0G1ARBdAAsCQCAAKAIIIgdBAEwNAEEBIAV0QQF1IQBBACEGQQAhAyAHQQRPBEAgAUEGaiEMIAFBBGohCiABQQJqIQsgB0H8////B3EhCEEAIQkDQCABIANBAXQiBGoiDSAAIA0uAQBqIAV1OwEAIAQgC2oiDSAAIA0uAQBqIAV1OwEAIAQgCmoiDSAAIA0uAQBqIAV1OwEAIAQgDGoiBCAAIAQuAQBqIAV1OwEAIANBBGohAyAJQQRqIgkgCEcNAAsLIAdBA3EiBARAA0AgASADQQF0aiIJIAAgCS4BAGogBXU7AQAgA0EBaiEDIAZBAWoiBiAERw0ACwtBACEEQQAhAyAHQQRPBEAgAkEGaiEJIAJBBGohDCACQQJqIQogB0H8////B3EhC0EAIQYDQCACIANBAXQiAWoiCCAAIAguAQBqIAV1OwEAIAEgCmoiCCAAIAguAQBqIAV1OwEAIAEgDGoiCCAAIAguAQBqIAV1OwEAIAEgCWoiASAAIAEuAQBqIAV1OwEAIANBBGohAyAGQQRqIgYgC0cNAAsLIAdBA3EiAUUNAANAIAIgA0EBdGoiBiAAIAYuAQBqIAV1OwEAIANBAWohAyAEQQFqIgQgAUcNAAsLC8EBAQN/IAAtAABBIHFFBEACQCAAKAIQIgMEfyADBSAAEGwNASAAKAIQCyAAKAIUIgRrIAJJBEAgACABIAIgACgCJBEBABoMAQsCQAJAIAAoAlBBAEgNACACRQ0AIAIhAwNAIAEgA2oiBUEBay0AAEEKRwRAIANBAWsiAw0BDAILCyAAIAEgAyAAKAIkEQEAIANJDQIgAiADayECIAAoAhQhBAwBCyABIQULIAQgBSACECsaIAAgACgCFCACajYCFAsLC5wCAQd/IwBBEGsiBiQAQQohAyAAIgVB6AdPBEAgBSEEA0AgBkEGaiADaiIHQQRrIAQgBEGQzgBuIgVBkM4AbGsiCEH//wNxQeQAbiIJQQF0Qb4bai8AADsAACAHQQJrIAggCUHkAGxrQf//A3FBAXRBvhtqLwAAOwAAIANBBGshAyAEQf+s4gRLIAUhBA0ACwsCQCAFQQlNBEAgBSEEDAELIANBAmsiAyAGQQZqaiAFIAVB//8DcUHkAG4iBEHkAGxrQf//A3FBAXRBvhtqLwAAOwAAC0EAIAAgBBtFBEAgA0EBayIDIAZBBmpqIARBAXRBHnFBvxtqLQAAOgAACyACIAFBAUEAIAZBBmogA2pBCiADaxAXIAZBEGokAAuJBAEDfyACQYAETwRAIAIEQCAAIAEgAvwKAAALIAAPCyAAIAJqIQMCQCAAIAFzQQNxRQRAAkAgAEEDcUUEQCAAIQIMAQsgAkUEQCAAIQIMAQsgACECA0AgAiABLQAAOgAAIAFBAWohASACQQFqIgJBA3FFDQEgAiADSQ0ACwsgA0F8cSEEAkAgA0HAAEkNACACIARBQGoiBUsNAANAIAIgASgCADYCACACIAEoAgQ2AgQgAiABKAIINgIIIAIgASgCDDYCDCACIAEoAhA2AhAgAiABKAIUNgIUIAIgASgCGDYCGCACIAEoAhw2AhwgAiABKAIgNgIgIAIgASgCJDYCJCACIAEoAig2AiggAiABKAIsNgIsIAIgASgCMDYCMCACIAEoAjQ2AjQgAiABKAI4NgI4IAIgASgCPDYCPCABQUBrIQEgAkFAayICIAVNDQALCyACIARPDQEDQCACIAEoAgA2AgAgAUEEaiEBIAJBBGoiAiAESQ0ACwwBCyADQQRJBEAgACECDAELIANBBGsiBCAASQRAIAAhAgwBCyAAIQIDQCACIAEtAAA6AAAgAiABLQABOgABIAIgAS0AAjoAAiACIAEtAAM6AAMgAUEEaiEBIAJBBGoiAiAETQ0ACwsgAiADSQRAA0AgAiABLQAAOgAAIAFBAWohASACQQFqIgIgA0cNAAsLIAALTQECfwJAIAAoAgAiACgCECIBRQ0AIAAoAhQgAUEAOgAARQ0AIAEQFAsCQCAAQX9GDQAgACAAKAIEIgFBAWs2AgQgAUEBRw0AIAAQFAsL+AcBBH8jAEHwAGsiBSQAIAUgAzYCDCAFIAI2AggCfyABQYECTwRAAn9BgAIgACwAgAJBv39KDQAaQf8BIAAsAP8BQb9/Sg0AGkH+AUH9ASAALAD+AUG/f0obCyIGIABqLAAAQb9/SgRAQQUhB0G8HwwCCyAAIAFBACAGIAQQLQALIAEhBkEBCyEIIAUgBjYCFCAFIAA2AhAgBSAHNgIcIAUgCDYCGAJAAkACQAJAAkAgASACSSIGDQAgASADSQ0AIAIgA0sNAQJAIAJFDQAgASACTQ0AIAVBDGogBUEIaiAAIAJqLAAAQb9/ShsoAgAhAwsgBSADNgIgIAMgASICSQRAIANBAWoiAiADQQNrIgZBACADIAZPGyIGSQ0DAn8gAiAGayIHQQFrIAAgA2osAABBv39KDQAaIAdBAmsgACACaiICQQJrLAAAQb9/Sg0AGiAHQQNrIAJBA2ssAABBv39KDQAaIAdBfEF7IAJBBGssAABBv39KG2oLIAZqIQILAkAgAkUNACABIAJNBEAgASACRg0BDAULIAAgAmosAABBv39MDQQLAn8CQAJAIAEgAkYNAAJAAkAgACACaiIBLAAAIgBBAEgEQCABLQABQT9xIQYgAEEfcSEDIABBX0sNASADQQZ0IAZyIQAMAgsgBSAAQf8BcTYCJEEBDAQLIAEtAAJBP3EgBkEGdHIhBiAAQXBJBEAgBiADQQx0ciEADAELIANBEnRBgIDwAHEgAS0AA0E/cSAGQQZ0cnIiAEGAgMQARg0BCyAFIAA2AiQgAEGAAU8NAUEBDAILIAQQLgALQQIgAEGAEEkNABpBA0EEIABBgIAESRsLIQAgBSACNgIoIAUgACACajYCLCAFQQU2AjQgBUGk5AA2AjAgBUIFNwI8IAUgBUEYaq1CgICAgNAAhDcDaCAFIAVBEGqtQoCAgIDQAIQ3A2AgBSAFQShqrUKAgICAkAGENwNYIAUgBUEkaq1CgICAgKABhDcDUCAFIAVBIGqtQoCAgICAAYQ3A0gMBAsgBSACIAMgBhs2AiggBUEDNgI0IAVBzOQANgIwIAVCAzcCPCAFIAVBGGqtQoCAgIDQAIQ3A1ggBSAFQRBqrUKAgICA0ACENwNQIAUgBUEoaq1CgICAgIABhDcDSAwDCyAFQQQ2AjQgBUIENwI8IAVBhOQANgIwIAUgBUEMaq1CgICAgIABhDcDUCAFIAVBCGqtQoCAgICAAYQ3A0ggBSAFQRhqrUKAgICA0ACENwNgIAUgBUEQaq1CgICAgNAAhDcDWAwCCyAGIAJB5OQAEFEACyAAIAEgAiABIAQQLQALIAUgBUHIAGo2AjggBUEwaiAEEBYACwwAQb0ZQSsgABBWAAtpAQF/IwBBMGsiAyQAIAMgATYCBCADIAA2AgAgA0ECNgIMIANBlOUANgIIIANCAjcCFCADIANBBGqtQoCAgICAAYQ3AyggAyADrUKAgICAgAGENwMgIAMgA0EgajYCECADQQhqIAIQFgAL0wMBBH8gAUUEQCAAQQA2AQAPCwJAIAJBgIACSARADAELIAJBEEEAIAJB//8DSyIEGyIDQQhyIAMgAkEQdiACIAQbIgRB/wFLIgMbIgVBBHIgBSAEQQh2IAQgAxsiBEEPSyIDGyIFQQJyIAUgBEEEdiAEIAMbIgRBA0siAxsgBEECdiAEIAMbQQFLaiIDQQ5rdiACQQ4gA2siBHQgA0EOSxshAgsgACAEQRBBACABIAFBH3UiBHMgBGsiBEH//wNLIgMbIgVBCHIgBSAEQRB2IAQgAxsiBEH/AUsiAxsiBUEEciAFIARBCHYgBCADGyIEQQ9LIgMbIgVBAnIgBSAEQQR2IAQgAxsiBEEDSyIDGyAEQQJ2IAQgAxtBAUtqQRBBACACQQFrIgRB//8DSyIDGyIFQQhyIAUgBEEQdiAEIAMbIgNB/wFLIgUbIgZBBHIgBiADQQh2IAMgBRsiA0EPSyIFGyIGQQJyIAYgA0EEdiADIAUbIgNBA0siBRsgA0ECdiADIAUbQQFLamsiA0Hy/wNqIANBD2siBSABIAV1IAFBDyADa3QgA0EPShsiASABQR91IgNzIANrIARBD3ROIgQbajsBAiAAIAEgBHUgAsFtOwEAC70CAQ9/AkAgACgCBCIAKAIAIgsoAgQEQCAAKAIEIgUgASALKAIAIgZBAnRqQQJrIgMvAQAgAS8BAGo7AQAgBSABLwEAIAMvAQBrOwECIAZBAk4EQCAGQQF2IQwgACgCCCENQQEhAANAIAUgAEECdCIDaiIHIAEgA2oiBC8BACIIIAEgBiAAa0ECdCIOaiIJLwEAIgprIg8gAyANaiIDLgECIhAgBEECay8BACIEIAlBAmsvAQAiCWvBIhFsIAMuAQAiAyAIIApqwSIIbGpBAXRBgIACakEQdiIKajsBAiAHIAQgCWoiByADIBFsIAggEGxrQQF0QYCAAmpBEHYiA2o7AQAgBSAOaiIEIAogD2s7AQIgBCAHIANrOwEAIAAgDEcgAEEBaiEADQALCyALIAUgAhBfDAELQYsCEF0ACws0AAJAIAFBAXENAEGk+QAoAgBB/////wdxRQ0AQcj5ACgCAEUNACAAQQE6AAQLIAAoAgAaC6gLAQd/IAAgAWohBQJAAkAgACgCBCICQQFxDQAgAkECcUUNASAAKAIAIgIgAWohAQJAAkACQCAAIAJrIgBB2PMAKAIARwRAIAAoAgwhAyACQf8BTQRAIAMgACgCCCIERw0CQcTzAEHE8wAoAgBBfiACQQN2d3E2AgAMBQsgACgCGCEGIAAgA0cEQCAAKAIIIgIgAzYCDCADIAI2AggMBAsgACgCFCIEBH8gAEEUagUgACgCECIERQ0DIABBEGoLIQIDQCACIQcgBCIDQRRqIQIgAygCFCIEDQAgA0EQaiECIAMoAhAiBA0ACyAHQQA2AgAMAwsgBSgCBCICQQNxQQNHDQNBzPMAIAE2AgAgBSACQX5xNgIEIAAgAUEBcjYCBCAFIAE2AgAPCyAEIAM2AgwgAyAENgIIDAILQQAhAwsgBkUNAAJAIAAoAhwiAkECdEH09QBqIgQoAgAgAEYEQCAEIAM2AgAgAw0BQcjzAEHI8wAoAgBBfiACd3E2AgAMAgsCQCAAIAYoAhBGBEAgBiADNgIQDAELIAYgAzYCFAsgA0UNAQsgAyAGNgIYIAAoAhAiAgRAIAMgAjYCECACIAM2AhgLIAAoAhQiAkUNACADIAI2AhQgAiADNgIYCwJAAkACQAJAIAUoAgQiAkECcUUEQEHc8wAoAgAgBUYEQEHc8wAgADYCAEHQ8wBB0PMAKAIAIAFqIgE2AgAgACABQQFyNgIEIABB2PMAKAIARw0GQczzAEEANgIAQdjzAEEANgIADwtB2PMAKAIAIgggBUYEQEHY8wAgADYCAEHM8wBBzPMAKAIAIAFqIgE2AgAgACABQQFyNgIEIAAgAWogATYCAA8LIAJBeHEgAWohASAFKAIMIQMgAkH/AU0EQCAFKAIIIgQgA0YEQEHE8wBBxPMAKAIAQX4gAkEDdndxNgIADAULIAQgAzYCDCADIAQ2AggMBAsgBSgCGCEGIAMgBUcEQCAFKAIIIgIgAzYCDCADIAI2AggMAwsgBSgCFCIEBH8gBUEUagUgBSgCECIERQ0CIAVBEGoLIQIDQCACIQcgBCIDQRRqIQIgAygCFCIEDQAgA0EQaiECIAMoAhAiBA0ACyAHQQA2AgAMAgsgBSACQX5xNgIEIAAgAUEBcjYCBCAAIAFqIAE2AgAMAwtBACEDCyAGRQ0AAkAgBSgCHCICQQJ0QfT1AGoiBCgCACAFRgRAIAQgAzYCACADDQFByPMAQcjzACgCAEF+IAJ3cTYCAAwCCwJAIAUgBigCEEYEQCAGIAM2AhAMAQsgBiADNgIUCyADRQ0BCyADIAY2AhggBSgCECICBEAgAyACNgIQIAIgAzYCGAsgBSgCFCICRQ0AIAMgAjYCFCACIAM2AhgLIAAgAUEBcjYCBCAAIAFqIAE2AgAgACAIRw0AQczzACABNgIADwsgAUH/AU0EQCABQXhxQezzAGohAgJ/QcTzACgCACIDQQEgAUEDdnQiAXFFBEBBxPMAIAEgA3I2AgAgAgwBCyACKAIICyEBIAIgADYCCCABIAA2AgwgACACNgIMIAAgATYCCA8LQR8hAyABQf///wdNBEAgAUEmIAFBCHZnIgJrdkEBcSACQQF0a0E+aiEDCyAAIAM2AhwgAEIANwIQIANBAnRB9PUAaiECAkACQEHI8wAoAgAiBEEBIAN0IgdxRQRAQcjzACAEIAdyNgIAIAIgADYCACAAIAI2AhgMAQsgAUEZIANBAXZrQQAgA0EfRxt0IQMgAigCACECA0AgAiIEKAIEQXhxIAFGDQIgA0EddiECIANBAXQhAyAEIAJBBHFqIgcoAhAiAg0ACyAHIAA2AhAgACAENgIYCyAAIAA2AgwgACAANgIIDwsgBCgCCCIBIAA2AgwgBCAANgIIIABBADYCGCAAIAQ2AgwgACABNgIICwsbACAAIAFBkPkAKAIAIgBBygAgABsRAgAQHQALhgEBAX8gAkEATgRAAn8gAygCBARAIAMoAggiBARAIAMoAgAgBCABIAIQPwwCCwsgASACRQ0AGkHZ+QAtAAAaIAIgARAcCyIDRQRAIAAgAjYCCCAAIAE2AgQgAEEBNgIADwsgACACNgIIIAAgAzYCBCAAQQA2AgAPCyAAQQA2AgQgAEEBNgIACyIBAX8gACgCACIAIABBH3UiAnMgAmsgAEF/c0EfdiABECoLawEDfyMAQYABayIEJAAgACgCACEAA0AgAiAEaiAAQQ9xIgNBMHIgA0E3aiADQQpJGzoAfyACQQFrIQIgAEEPSyAAQQR2IQANAAsgAUEBQbwbQQIgAiAEakGAAWpBACACaxAXIARBgAFqJAALOAACQCACQYCAxABGDQAgACACIAEoAhARAABFDQBBAQ8LIANFBEBBAA8LIAAgAyAEIAEoAgwRAQALjgQBDH8gAUEBayEOIAAoAgQhCiAAKAIAIQsgACgCCCEMAkADQCAFDQECfwJAIAIgBEkNAANAIAEgBGohBQJAAkACQCACIARrIgdBB00EQCACIARHDQEgAiEEDAULAkAgBUEDakF8cSIGIAVrIgMEQEEAIQADQCAAIAVqLQAAQQpGDQUgAyAAQQFqIgBHDQALIAMgB0EIayIATQ0BDAMLIAdBCGshAAsDQEGAgoQIIAYoAgAiCUGKlKjQAHNrIAlyQYCChAggBigCBCIJQYqUqNAAc2sgCXJxQYCBgoR4cUGAgYKEeEcNAiAGQQhqIQYgA0EIaiIDIABNDQALDAELQQAhAANAIAAgBWotAABBCkYNAiAHIABBAWoiAEcNAAsgAiEEDAMLIAMgB0YEQCACIQQMAwsDQCADIAVqLQAAQQpGBEAgAyEADAILIAcgA0EBaiIDRw0ACyACIQQMAgsgACAEaiIGQQFqIQQCQCACIAZNDQAgACAFai0AAEEKRw0AQQAhBSAEIgYMAwsgAiAETw0ACwsgAiAIRg0CQQEhBSAIIQYgAgshAAJAIAwtAAAEQCALQaUbQQQgCigCDBEBAA0BC0EAIQMgACAIRwRAIAAgDmotAABBCkYhAwsgACAIayEAIAEgCGohByAMIAM6AAAgBiEIIAsgByAAIAooAgwRAQBFDQELC0EBIQ0LIA0LbAEDfyMAQYABayIEJAAgACgCACEAA0AgAiAEaiAAQQ9xIgNBMHIgA0HXAGogA0EKSRs6AH8gAkEBayECIABBD0sgAEEEdiEADQALIAFBAUG8G0ECIAIgBGpBgAFqQQAgAmsQFyAEQYABaiQAC9YEAQZ/AkACQCAAKAIIIgdBgICAwAFxRQ0AAkACQAJAAkAgB0GAgICAAXEEQCAALwEOIgMNAUEAIQIMAgsgAkEQTwRAIAEgAhBTIQMMBAsgAkUEQEEAIQIMBAsgAkEDcSEGAkAgAkEESQRADAELIAJBDHEhCANAIAMgASAFaiIELAAAQb9/SmogBCwAAUG/f0pqIAQsAAJBv39KaiAELAADQb9/SmohAyAIIAVBBGoiBUcNAAsLIAZFDQMgASAFaiEEA0AgAyAELAAAQb9/SmohAyAEQQFqIQQgBkEBayIGDQALDAMLIAEgAmohCEEAIQIgAyEFIAEhBANAIAQiBiAIRg0CAn8gBkEBaiAGLAAAIgRBAE4NABogBkECaiAEQWBJDQAaIAZBA2ogBEFwSQ0AGiAGQQRqCyIEIAZrIAJqIQIgBUEBayIFDQALC0EAIQULIAMgBWshAwsgAyAALwEMIgRPDQAgBCADayEGQQAhA0EAIQUCQAJAAkAgB0EddkEDcUEBaw4CAAECCyAGIQUMAQsgBkH+/wNxQQF2IQULIAdB////AHEhCCAAKAIEIQcgACgCACEAA0AgA0H//wNxIAVB//8DcUkEQEEBIQQgA0EBaiEDIAAgCCAHKAIQEQAARQ0BDAMLC0EBIQQgACABIAIgBygCDBEBAA0BQQAhAyAGIAVrQf//A3EhAQNAIANB//8DcSICIAFJIQQgASACTQ0CIANBAWohAyAAIAggBygCEBEAAEUNAAsMAQsgACgCACABIAIgACgCBCgCDBEBACEECyAEC48BAQd/IAAoAhQiBEEASgRAIAAoAgwhBSAAKAIIIQYgACgCBCEHIAAoAgAhCEEAIQADQCACIABBAXQiA2ogAyAGai4BACABIAggAEECdCIJaigCAEEBdGouAQBsIAMgBWouAQAgASAHIAlqKAIAQQF0ai4BAGxqQYCAAWpBD3Y7AQAgAEEBaiIAIARHDQALCwv8AQEKfyAAKAIQQQBKBEADQCACIANBAnRqQQA2AgAgA0EBaiIDIAAoAhBIDQALCyAAKAIUQQBKBEAgACgCDCEGIAAoAgQhByAAKAIIIQggACgCACEJQQAhAwNAIAIgCSADQQJ0IgRqKAIAQQJ0aiIFIAUoAgAgCCADQQF0IgVqLgEAIgogASAEaiILKAIAIgxBD3VsaiAMQf//AXEgCmxBgIABakEPdWo2AgAgAiAEIAdqKAIAQQJ0aiIEIAQoAgAgBSAGai4BACIEIAsoAgAiBUEPdWxqIAVB//8BcSAEbEGAgAFqQQ91ajYCACADQQFqIgMgACgCFEgNAAsLC/sBAQJ/IwBBIGsiAiQAAkACQAJAAkAgACgCDCIBBEAgASABKAIAIgFBAWo2AgAgAUEASA0EIABBAToAECAAKAIMIgAoAmAgAEECNgJgIAIgADYCBA4DAgICAQtB/O8AEC4MAwtB+PgAQQA2AgAgAkEANgIYIAJCBDcCECACQcTwADYCCCACQQE2AgxBLCACQQhqQczwABADDAELIAAgACgCACIAQQFrNgIAIABBAUYEQCACQQRqECwLIAJBIGokAA8LQfj4ACgCAEH4+ABBADYCAEEBRw0AEAAgACAAKAIAIgBBAWs2AgAgAEEBRgRAIAJBBGoQLAsQAQALAAv/CAEKfyMAQRBrIgkkAAJAIAJBCE0gAiADTXFFBEAgCUEANgIMIAlBDGpBBCACIAJBBE0bIAMQRw0BIAkoAgwiAkUNASADIAEgASADSxsiAQRAIAIgACAB/AoAAAsgABAUIAIhBgwBCwJ/QQAhASAAIgpFBEAgAxAYDAELIANBQE8EQEHA8wBBMDYCAEEADAELAn9BECADQQtqQXhxIANBC0kbIQQgCkEIayIAKAIEIgdBeHEhAgJAIAdBA3FFBEAgBEGAAkkNASAEQQRqIAJNBEAgACEBIAIgBGtBpPcAKAIAQQF0TQ0CC0EADAILIAAgAmohBQJAIAIgBE8EQCACIARrIgFBEEkNASAAIAQgB0EBcXJBAnI2AgQgACAEaiICIAFBA3I2AgQgBSAFKAIEQQFyNgIEIAIgARAzDAELQdzzACgCACAFRgRAQdDzACgCACACaiICIARNDQIgACAEIAdBAXFyQQJyNgIEIAAgBGoiASACIARrIgJBAXI2AgRB0PMAIAI2AgBB3PMAIAE2AgAMAQtB2PMAKAIAIAVGBEBBzPMAKAIAIAJqIgIgBEkNAgJAIAIgBGsiAUEQTwRAIAAgBCAHQQFxckECcjYCBCAAIARqIgYgAUEBcjYCBCAAIAJqIgIgATYCACACIAIoAgRBfnE2AgQMAQsgACAHQQFxIAJyQQJyNgIEIAAgAmoiASABKAIEQQFyNgIEQQAhAQtB2PMAIAY2AgBBzPMAIAE2AgAMAQsgBSgCBCIGQQJxDQEgBkF4cSACaiILIARJDQEgCyAEayEMIAUoAgwhAgJAIAZB/wFNBEAgBSgCCCIBIAJGBEBBxPMAQcTzACgCAEF+IAZBA3Z3cTYCAAwCCyABIAI2AgwgAiABNgIIDAELIAUoAhghCAJAIAIgBUcEQCAFKAIIIgEgAjYCDCACIAE2AggMAQsCQCAFKAIUIgEEfyAFQRRqBSAFKAIQIgFFDQEgBUEQagshBgNAIAYhDSABIgJBFGohBiACKAIUIgENACACQRBqIQYgAigCECIBDQALIA1BADYCAAwBC0EAIQILIAhFDQACQCAFKAIcIgFBAnRB9PUAaiIGKAIAIAVGBEAgBiACNgIAIAINAUHI8wBByPMAKAIAQX4gAXdxNgIADAILAkAgBSAIKAIQRgRAIAggAjYCEAwBCyAIIAI2AhQLIAJFDQELIAIgCDYCGCAFKAIQIgEEQCACIAE2AhAgASACNgIYCyAFKAIUIgFFDQAgAiABNgIUIAEgAjYCGAsgDEEPTQRAIAAgB0EBcSALckECcjYCBCAAIAtqIgEgASgCBEEBcjYCBAwBCyAAIAQgB0EBcXJBAnI2AgQgACAEaiIBIAxBA3I2AgQgACALaiICIAIoAgRBAXI2AgQgASAMEDMLIAAhAQsgAQsiAARAIABBCGoMAQtBACADEBgiAEUNABogACAKQXxBeCAKQQRrKAIAIgFBA3EbIAFBeHFqIgEgAyABIANJGxArGiAKEBQgAAshBgsgCUEQaiQAIAYLGQAjAEEgayIAJAAgAEEANgIEIABBIGokAAsRACAAKAIABEAgACgCBBAUCwtRAQF/IAAoAgAiACgCCCIBBEAgARAUCyAAQQA2AgggACgCEARAIAAoAhQQFAsCQCAAQX9GDQAgACAAKAIEIgFBAWs2AgQgAUEBRw0AIAAQFAsLVQEBfyMAQRBrIgIkACACIAE2AgwgAiAANgIIQQIgAkEIakEBIAJBBGoQBiIABH9BwPMAIAA2AgBBfwVBAAshACACKAIEIQEgAkEQaiQAQX8gASAAGwsGACAAEBQLlAEBA38gASgCAEGAgICAeEcEQCAAIAEpAgA3AgAgACABKAIINgIIDwsCQCABKAIIIgJBAEgNACABKAIEIQMCQCACRQRAQQEhAQwBC0HZ+QAtAAAaQQEhBCACQQEQHCIBRQ0BCyACBEAgASADIAL8CgAACyAAIAI2AgggACABNgIEIAAgAjYCAA8LIAQgAkG45gAQJAAL8gUBBH8jAEEwayIDJAAgAyACNgIIIAMgATYCBCADQSBqIANBBGoQVQJAAkACQCADKAIgIgYEQCADKAIkIQEgAygCLEUEQCAAIAE2AgggACAGNgIEIABBgICAgHg2AgAMAwsgAkEASA0BAkAgAkUEQEEBIQUMAQtB2fkALQAAGkEBIQQgAkEBEBwiBUUNAgtBACEEIANBADYCFCADIAU2AhAgAyACNgIMIAEgAksEQEH4+ABBADYCAEESIANBDGpBACABEARB+PgAKAIAQfj4AEEANgIAQQFGDQQgAygCECEFIAMoAhQhBCADKAIMIQILIAEEQCAEIAVqIAYgAfwKAAALIAMgASAEaiIBNgIUIAIgAWtBAk0EQEH4+ABBADYCAEESIANBDGogAUEDEARB+PgAKAIAQfj4AEEANgIAQQFGDQQgAygCECEFIAMoAhQhAQsgASAFaiICQb4vLwAAOwAAIAJBwC8tAAA6AAIgAyABQQNqIgI2AhQgAyADKQIENwIYA0BB+PgAQQA2AgBBEyADQSBqIANBGGoQA0H4+AAoAgBB+PgAQQA2AgBBAUYNBCADKAIgIgUEQCADKAIsIAMoAiQiASADKAIMIAJrSwRAQfj4AEEANgIAQRIgA0EMaiACIAEQBEH4+AAoAgBB+PgAQQA2AgBBAUYNBiADKAIUIQILIAMoAhAhBCABBEAgAiAEaiAFIAH8CgAACyADIAEgAmoiAjYCFEUNASADKAIMIAJrQQJNBEBB+PgAQQA2AgBBEiADQQxqIAJBAxAEQfj4ACgCAEH4+ABBADYCAEEBRg0GIAMoAhAhBCADKAIUIQILIAIgBGoiAUG+Ly8AADsAACABQcAvLQAAOgACIAMgAkEDaiICNgIUDAELCyAAIAMpAgw3AgAgACADKAIUNgIIDAILIABBADYCCCAAQoCAgIAYNwIADAELIAQgAkH45QAQJAALIANBMGokAA8LEAAgAygCDARAIAMoAhAQFAsQAQALgwQBBX8CQAJ/IAFBCEYEQCACEBgMAQtBHCEEIAFBBEkNASABQQNxDQEgAUECdiIDIANBAWtxDQFBQCABayACSQRAQTAPCwJ/QRAhAwJAQRBBECABIAFBEE0bIgEgAUEQTRsiBCAEQQFrcUUEQCAEIQEMAQsDQCADIgFBAXQhAyABIARJDQALC0FAIAFrIAJNBEBBwPMAQTA2AgBBAAwBC0EAQRAgAkELakF4cSACQQtJGyIEIAFqQQxqEBgiA0UNABogA0EIayECAkAgAUEBayADcUUEQCACIQEMAQsgA0EEayIGKAIAIgdBeHEgASADakEBa0EAIAFrcUEIayIDIAFBACADIAJrQQ9NG2oiASACayIDayEFIAdBA3FFBEAgAigCACECIAEgBTYCBCABIAIgA2o2AgAMAQsgASAFIAEoAgRBAXFyQQJyNgIEIAEgBWoiBSAFKAIEQQFyNgIEIAYgAyAGKAIAQQFxckECcjYCACACIANqIgUgBSgCBEEBcjYCBCACIAMQMwsCQCABKAIEIgJBA3FFDQAgAkF4cSIDIARBEGpNDQAgASAEIAJBAXFyQQJyNgIEIAEgBGoiAiADIARrIgRBA3I2AgQgASADaiIDIAMoAgRBAXI2AgQgAiAEEDMLIAFBCGoLCyIBRQRAQTAPCyAAIAE2AgBBACEECyAEC8QCAQZ/IAEgAkEBdGohCSAAQYD+A3FBCHYhCiAAQf8BcSEMAkACQAJAAkADQCABQQJqIQsgByABLQABIgJqIQggCiABLQAAIgFHBEAgASAKSw0EIAghByALIgEgCUcNAQwECyAHIAhLDQEgBCAISQ0CIAMgB2ohAQNAIAJFBEAgCCEHIAsiASAJRw0CDAULIAJBAWshAiABLQAAIAFBAWohASAMRw0ACwtBACECDAMLIAcgCEGE5QAQUQALIAggBEGE5QAQVwALIABB//8DcSEHIAUgBmohA0EBIQIDQCAFQQFqIQACQCAFLAAAIgFBAE4EQCAAIQUMAQsgACADRwRAIAUtAAEgAUH/AHFBCHRyIQEgBUECaiEFDAELQfTkABAuAAsgByABayIHQQBIDQEgAkEBcyECIAMgBUcNAAsLIAJBAXEL4wYBD38jAEEQayIHJABBASEMAkAgAigCACIKQSIgAigCBCIOKAIQIg8RAAANAAJAIAFFBEBBACECDAELQQAgAWshECAAIQggASEGAkADQCAGIAhqIRFBACECAkADQCACIAhqIgUtAAAiCUH/AGtB/wFxQaEBSQ0BIAlBIkYNASAJQdwARg0BIAYgAkEBaiICRw0ACyAEIAZqIQQMAgsgBUEBaiEIIAIgBGohBgJAAn8CQCAFLAAAIglBAE4EQCAJQf8BcSEFDAELIAgtAABBP3EhCyAJQR9xIQ0gBUECaiEIIAlBX00EQCANQQZ0IAtyIQUMAQsgCC0AAEE/cSALQQZ0ciELIAVBA2ohCCAJQXBJBEAgCyANQQx0ciEFDAELIAgtAAAhCSAFQQRqIQggDUESdEGAgPAAcSAJQT9xIAtBBnRyciIFQYCAxABHDQAgBgwBCyAHQQRqIAVBgYAEEFQCQCAHLQAEQYABRg0AIActAA8gBy0ADmtB/wFxQQFGDQACQAJAIAMgBksNAAJAIANFDQAgASADTQRAIAEgA0cNAgwBCyAAIANqLAAAQb9/TA0BCwJAIAZFDQAgASAGTQRAIAYgEGpFDQEMAgsgACAEaiACaiwAAEFASA0BCyAKIAAgA2ogBCADayACaiAOKAIMIgMRAQBFDQEMBAsgACABIAMgAiAEakHk4wAQLQALAkAgBy0ABEGAAUYEQCAKIAcoAgggDxEAAA0EDAELIAogBy0ADiIGIAdBBGpqIActAA8gBmsgAxEBAA0DCwJ/QQEgBUGAAUkNABpBAiAFQYAQSQ0AGkEDQQQgBUGAgARJGwsgBGogAmohAwsCf0EBIAVBgAFJDQAaQQIgBUGAEEkNABpBA0EEIAVBgIAESRsLIARqIAJqCyEEIBEgCGsiBg0BDAILCwwCCwJAIAMgBEsNAEEAIQICQCADRQ0AIAEgA00EQCADIQIgASADRw0CDAELIAMhAiAAIANqLAAAQb9/TA0BCyAERQRAQQAhBAwCCyABIARNBEAgASAERg0CIAIhAwwBCyAAIARqLAAAQb9/Sg0BIAIhAwsgACABIAMgBEH04wAQLQALIAogACACaiAEIAJrIA4oAgwRAQANACAKQSIgDxEAACEMCyAHQRBqJAAgDAtqAQF/IAAtAAQhASAALQAFBEAgAAJ/QQEgAUEBcQ0AGiAAKAIAIgEtAApBgAFxRQRAIAEoAgBBtBtBAiABKAIEKAIMEQEADAELIAEoAgBBsxtBASABKAIEKAIMEQEACyIBOgAECyABQQFxCxQAIAAoAgAgASAAKAIEKAIMEQAAC7ACAQF/IwBB8ABrIgckACAHIAI2AgwgByABNgIIIAcgBDYCFCAHIAM2AhAgByAAQf8BcUECdCIAQfgtaigCADYCHCAHIABBxOUAaigCADYCGAJAIAUoAgAEQCAHIAUpAhA3AzAgByAFKQIINwMoIAcgBSkCADcDICAHQQQ2AlwgB0Gc4wA2AlggB0IENwJkIAcgB0EQaq1CgICAgMAAhDcDUCAHIAdBCGqtQoCAgIDAAIQ3A0ggByAHQSBqrUKAgICA8ACENwNADAELIAdBAzYCXCAHQgM3AmQgB0GE4wA2AlggByAHQRBqrUKAgICAwACENwNIIAcgB0EIaq1CgICAgMAAhDcDQAsgByAHQRhqrUKAgICA0ACENwM4IAcgB0E4ajYCYCAHQdgAaiAGEBYAC3gBAX8jAEEwayIDJAAgAyAAKQIQNwMYIAMgACkCCDcDEEH4+ABBADYCACADIAApAgA3AwggAyABOgAtIANBADoALCADIAI2AiggAyADQQhqNgIkQQYgA0EkahACQfj4ACgCAEH4+ABBADYCAEEBRgRAEAAaECYLAAsQACABIAAoAgAgACgCBBA7C/ACAgJ/AX4CQCACRQ0AIAAgAToAACAAIAJqIgNBAWsgAToAACACQQNJDQAgACABOgACIAAgAToAASADQQNrIAE6AAAgA0ECayABOgAAIAJBB0kNACAAIAE6AAMgA0EEayABOgAAIAJBCUkNACAAQQAgAGtBA3EiBGoiAyABQf8BcUGBgoQIbCIANgIAIAMgAiAEa0F8cSICaiIBQQRrIAA2AgAgAkEJSQ0AIAMgADYCCCADIAA2AgQgAUEIayAANgIAIAFBDGsgADYCACACQRlJDQAgAyAANgIYIAMgADYCFCADIAA2AhAgAyAANgIMIAFBEGsgADYCACABQRRrIAA2AgAgAUEYayAANgIAIAFBHGsgADYCACACIANBBHFBGHIiAWsiAkEgSQ0AIACtQoGAgIAQfiEFIAEgA2ohAQNAIAEgBTcDGCABIAU3AxAgASAFNwMIIAEgBTcDACABQSBqIQEgAkEgayICQR9LDQALCwsNACAAKAIAQQEgARAqC2kBAX8jAEEwayIDJAAgAyABNgIEIAMgADYCACADQQI2AgwgA0G05QA2AgggA0ICNwIUIAMgA0EEaq1CgICAgIABhDcDKCADIAOtQoCAgICAAYQ3AyAgAyADQSBqNgIQIANBCGogAhAWAAt6AQF/IwBBQGoiBSQAIAUgATYCDCAFIAA2AgggBSADNgIUIAUgAjYCECAFQQI2AhwgBUG84wA2AhggBUICNwIkIAUgBUEQaq1CgICAgMAAhDcDOCAFIAVBCGqtQoCAgIDQAIQ3AzAgBSAFQTBqNgIgIAVBGGogBBAWAAu0BgEIfwJAAkAgASAAQQNqQXxxIgMgAGsiCEkNACABIAhrIgZBBEkNACAGQQNxIQdBACEBAkAgACADRiIJDQACQCAAIANrIgVBfEsEQEEAIQMMAQtBACEDA0AgASAAIANqIgIsAABBv39KaiACLAABQb9/SmogAiwAAkG/f0pqIAIsAANBv39KaiEBIANBBGoiAw0ACwsgCQ0AIAAgA2ohAgNAIAEgAiwAAEG/f0pqIQEgAkEBaiECIAVBAWoiBQ0ACwsgACAIaiEAAkAgB0UNACAAIAZBfHFqIgMsAABBv39KIQQgB0EBRg0AIAQgAywAAUG/f0pqIQQgB0ECRg0AIAQgAywAAkG/f0pqIQQLIAZBAnYhBSABIARqIQQDQCAAIQMgBUUNAkHAASAFIAVBwAFPGyIGQQNxIQcgBkECdCEAQQAhAiAFQQRPBEAgAyAAQfAHcWohCCADIQEDQCACIAEoAgAiAkF/c0EHdiACQQZ2ckGBgoQIcWogASgCBCICQX9zQQd2IAJBBnZyQYGChAhxaiABKAIIIgJBf3NBB3YgAkEGdnJBgYKECHFqIAEoAgwiAkF/c0EHdiACQQZ2ckGBgoQIcWohAiABQRBqIgEgCEcNAAsLIAUgBmshBSAAIANqIQAgAkEIdkH/gfwHcSACQf+B/AdxakGBgARsQRB2IARqIQQgB0UNAAsCfyADIAZB/AFxQQJ0aiIAKAIAIgFBf3NBB3YgAUEGdnJBgYKECHEiASAHQQFGDQAaIAEgACgCBCIBQX9zQQd2IAFBBnZyQYGChAhxaiIBIAdBAkYNABogACgCCCIAQX9zQQd2IABBBnZyQYGChAhxIAFqCyIBQQh2Qf+BHHEgAUH/gfwHcWpBgYAEbEEQdiAEag8LIAFFBEBBAA8LIAFBA3EhAwJAIAFBBEkEQAwBCyABQXxxIQUDQCAEIAAgAmoiASwAAEG/f0pqIAEsAAFBv39KaiABLAACQb9/SmogASwAA0G/f0pqIQQgBSACQQRqIgJHDQALCyADRQ0AIAAgAmohAQNAIAQgASwAAEG/f0pqIQQgAUEBaiEBIANBAWsiAw0ACwsgBAu0CgEFfyMAQSBrIgQkAAJAAkACQAJAAkACQAJAAkACQAJAAkACQCABDigGAQEBAQEBAQECBAEBAwEBAQEBAQEBAQEBAQEBAQEBAQEBCAEBAQEHAAsgAUHcAEYNBAsgAkEBcUUNByABQf8FTQ0HQRFBACABQa+wBE8bIgIgAkEIciIDIAFBC3QiAiADQQJ0QfAsaigCAEELdEkbIgMgA0EEciIDIANBAnRB8CxqKAIAQQt0IAJLGyIDIANBAnIiAyADQQJ0QfAsaigCAEELdCACSxsiAyADQQFqIgMgA0ECdEHwLGooAgBBC3QgAksbIgMgA0EBaiIDIANBAnRB8CxqKAIAQQt0IAJLGyIDQQJ0QfAsaigCAEELdCIGIAJGIAIgBktqIANqIgZBAnRB8CxqIgcoAgBBFXYhA0HvBSECAkAgBkEgTQRAIAcoAgRBFXYhAiAGRQ0BCyAHQQRrKAIAQf///wBxIQULAkAgAiADQX9zakUNACABIAVrIQUgAkEBayEGQQAhAgNAIAIgA0G6E2otAABqIgIgBUsNASAGIANBAWoiA0cNAAsLIANBAXFFDQcgBEEAOgAKIARBADsBCCAEIAFBFHZBrBlqLQAAOgALIAQgAUEEdkEPcUGsGWotAAA6AA8gBCABQQh2QQ9xQawZai0AADoADiAEIAFBDHZBD3FBrBlqLQAAOgANIAQgAUEQdkEPcUGsGWotAAA6AAwgAUEBcmdBAnYiAiAEQQhqIgNqIgVB+wA6AAAgBUEBa0H1ADoAACADIAJBAmsiAmpB3AA6AAAgBCABQQ9xQawZai0AADoAECAAQQo6AAsgACACOgAKIAAgBCkCCDcCACAEQf0AOgARIAAgBC8BEDsBCAwJCyAAQYAEOwEKIABCADcBAiAAQdzoATsBAAwICyAAQYAEOwEKIABCADcBAiAAQdzkATsBAAwHCyAAQYAEOwEKIABCADcBAiAAQdzcATsBAAwGCyAAQYAEOwEKIABCADcBAiAAQdy4ATsBAAwFCyAAQYAEOwEKIABCADcBAiAAQdzgADsBAAwECyACQYACcUUNASAAQYAEOwEKIABCADcBAiAAQdzOADsBAAwDCyACQf///wdxQYCABE8NAQsCf0EAIAFBIEkNABpBASABQf8ASQ0AGiABQYCABE8EQCABQeD//wBxQeDNCkcgAUH+//8AcUGe8ApHcSABQcDuCmtBeklxIAFBsJ0La0FySXEgAUHw1wtrQXFJcSABQYDwC2tB3mxJcSABQYCADGtBnnRJcSABQdCmDGtBe0lxIAFBgII4a0GwxVRJcSABQfCDOElxIAFBgIAITw0BGiABQd4gQSxBtiFB0AFBhiNB5gMQSAwBCyABQewmQShBvCdBogJB3ilBqQIQSAtFBEAgBEEAOgAWIARBADsBFCAEIAFBFHZBrBlqLQAAOgAXIAQgAUEEdkEPcUGsGWotAAA6ABsgBCABQQh2QQ9xQawZai0AADoAGiAEIAFBDHZBD3FBrBlqLQAAOgAZIAQgAUEQdkEPcUGsGWotAAA6ABggAUEBcmdBAnYiAiAEQRRqIgNqIgVB+wA6AAAgBUEBa0H1ADoAACADIAJBAmsiAmpB3AA6AAAgBCABQQ9xQawZai0AADoAHCAAQQo6AAsgACACOgAKIAAgBCkCFDcCACAEQf0AOgAdIAAgBC8BHDsBCAwCCyAAIAE2AgQgAEGAAToAAAwBCyAAQYAEOwEKIABCADcBAiAAQdzEADsBAAsgBEEgaiQAC+0DAQd/IAEoAgQiBQRAIAEoAgAhBANAAkAgA0EBaiECAn8gAiADIARqLQAAIgfAIghBAE4NABoCQAJAAkACQAJAAkACQAJAAkACQAJAIAdBvB1qLQAAQQJrDgMAAQIMC0GnDyACIARqIAIgBU8bLAAAQUBODQsgA0ECagwKC0GnDyACIARqIAIgBU8bLAAAIQYgB0HgAWsODgEDAwMDAwMDAwMDAwMCAwtBpw8gAiAEaiACIAVPGywAACEGIAdB8AFrDgUEAwMDBQMLIAZBYHFBoH9HDQgMBgsgBkGff0oNBwwFCyAIQR9qQf8BcUEMTwRAIAhBfnFBbkcNByAGQUBODQcMBQsgBkFATg0GDAQLIAhBD2pB/wFxQQJLDQUgBkFATg0FDAILIAZB8ABqQf8BcUEwTw0EDAELIAZBj39KDQMLQacPIAQgA0ECaiICaiACIAVPGywAAEG/f0oNAkGnDyAEIANBA2oiAmogAiAFTxssAABBv39KDQIgA0EEagwBC0GnDyAEIANBAmoiAmogAiAFTxssAABBQE4NASADQQNqCyIDIgIgBUkNAQsLIAAgAzYCBCAAIAQ2AgAgASAFIAJrNgIEIAEgAiAEajYCACAAIAIgA2s2AgwgACADIARqNgIIDwsgAEEANgIAC0EBAX8jAEEgayIDJAAgA0EANgIQIANBATYCBCADQgQ3AgggAyABNgIcIAMgADYCGCADIANBGGo2AgAgAyACEBYAC2kBAX8jAEEwayIDJAAgAyABNgIEIAMgADYCACADQQI2AgwgA0Gk5QA2AgggA0ICNwIUIAMgA0EEaq1CgICAgIABhDcDKCADIAOtQoCAgICAAYQ3AyAgAyADQSBqNgIQIANBCGogAhAWAAupAgEDfyAAQQp1IgFBAEgEQEH//wEPCyABQRRPBEBBvK3CACAAQQ10QRB1bcFB//8Bag8LIAFBAXQiAUGQE2ouAQAgAEEFdEHg/wFxIgJB//8Bc2wgAiABQZITai4BAGxqQUBrQQd1IABBD3RBtzRyIgFBCEEAIABBAUsiAhsiA0EEciADIABBAXYgASACGyIAQf8BSyICGyIDQQJyIAMgAEEIdiAAIAIbIgBBD0siAhsgAEEEdiAAIAIbQQNLciIAQQF0IgJBDGt2IAFBDCACa3QgAEEGSxsiAcFBsIMBbEGAgMyKA2tBEHUgAUEQdEEOdSIBbEGAgNSVBWpBEHUgAWxBgIDI8QBqQRB1IgFBDSAAa3UgASAAQQ1rdCAAQQ1JG8FtQRB0QQl1C8wBAQF/IAAoAjwQFCAAKAJAEBQgACgCRBAUIAAoAkgQFCAAKAJMEBQgACgCUBAUIAAoAlQQFCAAKAJYEBQgACgCXBAUIAAoAmAQFCAAKAJkEBQgACgCaBAUIAAoAoABEBQgACgChAEQFCAAKAJsEBQgACgCcBAUIAAoAnQQFCAAKAJ4EBQgACgCfBAUIAAoAogBEBQgACgCjAEQFCAAKAKcARBbIAAoAhAiASgCABAUIAEoAgQQFCABKAIIEBQgASgCDBAUIAEQFCAAEBQL2AEAIAAoAqgBEFsgACgCOBAUIAAoAjwQFCAAKAJEEBQgACgCSBAUIAAoAkwQFCAAKAKIARAUIAAoAoQBEBQgACgCjAEQFCAAKAKUARAUIAAoApABEBQgACgCQBAUIAAoAlAQFCAAKAJUEBQgACgCXBAUIAAoAmAQFCAAKAJYEBQgACgCdBAUIAAoAngQFCAAKAKgARAUIAAoAqQBEBQgACgCfBAUIAAoAoABEBQgACgCrAEQFCAAKAKwARAUIAAoArQBEBQgACgCvAEQFCAAKALAARAUIAAQFAsUACAAKAIAEBQgACgCBBAUIAAQFAsrAQJ/QQwQFSIBIABBABBeNgIAIABBARBeIQIgASAANgIIIAEgAjYCBCABCzYBAX8jAEEQayIBJAAgAUHdDjYCCCABIAA2AgQgAUGkCzYCAEGACCgCAEGiDiABECJBARAKAAuEBgEIfyMAQRBrIgMkAAJAIABBAXEEQCADQYMPNgIAQYAIKAIAQZUOIAMQIgwBCyAAQQF1IgUgAUEAIANBDGoQYyADKAIMIgcgAEECdGpBDGoQFSIERQ0AIAQgBEEMaiIGNgIAIAQgBiAHaiICNgIEIAQgAiAFQQJ0ajYCCCAFIAEgBiADQQxqEGMgBUEASgRAIABBAnYhCCAEKAIIIQlBACEAA0AgCSAAQQJ0aiIGAn9BgIAIIAAgCGoiAkEAIAJrIAEbQRB0IAVtIgdB//8HcSICayACIAJBgIAESxsiAkH//wFxBEAgAkH//wFNBEBB//8BIAIgAmxBAXRBgIACakEQdiICIAJBjvv//wdsQYCAAWpBD3ZB1cAAakH//wNxbEEBdEGAgIrvAWtBEHUgAmxBgIABakEPdSACayICQYCAfnMgAkEAThsMAgtBgYB+QQAgAkEQdGsiAkEPdSACQRB1bEGAgAJqQRB1IgIgAkGO+///B2xBgIABakEPdkHVwABqQf//A3FsQQF0QYCAiu8Ba0EQdSACbEGAgAFqQQ91IAJrIgJB//8Bc0EBaiACQQBOGwwBC0EAIAJBgIACcQ0AGkGBgH5B//8BIAIbCzsBACAGAn9BgIAIIAdBgIAGakH//wdxIgJrIAIgAkGAgARLGyICQf//AXEEQCACQf//AU0EQEH//wEgAiACbEEBdEGAgAJqQRB2IgIgAkGO+///B2xBgIABakEPdkHVwABqQf//A3FsQQF0QYCAiu8Ba0EQdSACbEGAgAFqQQ91IAJrIgJBgIB+cyACQQBOGwwCC0GBgH5BACACQRB0ayICQQ91IAJBEHVsQYCAAmpBEHUiAiACQY77//8HbEGAgAFqQQ92QdXAAGpB//8DcWxBAXRBgICK7wFrQRB1IAJsQYCAAWpBD3UgAmsiAkH//wFzQQFqIAJBAE4bDAELQQAgAkGAgAJxDQAaQYGAfkH//wEgAhsLOwECIABBAWoiACAFRw0ACwsgBCECCyADQRBqJAAgAgs0ACABIAJGBEBBuglB/QMQYgALIAIgAUEBQQEgAEEIaiIBEGEgAkEBQQEgASAAQQFBARBgC+IgASx/IwBB0ABrIhwkACADKAIAIQkgAygCBCIKQQFHBEAgACABIAlsIAIgA0EIaiAEIAUgCWwgChBgCwJAAkACQAJAAkACQAJAIAlBAmsOBAMBAgAECyAFQQBMDQQgCkEATA0EIARBiAJqIgggASAKbEECdGohEyAIIAogAUEBdCISbEECdGohGyABQQJ0IRYgAUEDbCEXIApBA3QhGCAKQQxsIR0gCkEEdCEeIAQoAgQhHwNAIAAgBiAUbEECdGoiAyAKQQJ0aiECIBsuAQJBAXQhDiATLgECQQF0IQ0gGy4BAEEBdCEJIBMuAQBBAXQhESADIBhqIQcgAyAdaiELIAMgHmohDEEAIQQDQAJAIB8EQCAMLgECIQ8gDC4BACEQDAELIAMgAy4BAEGZM2xBgIABakEPdjsBACADIAMuAQJBmTNsQYCAAWpBD3Y7AQIgAiACLgEAQZkzbEGAgAFqQQ92OwEAIAIgAi4BAkGZM2xBgIABakEPdjsBAiAHIAcuAQBBmTNsQYCAAWpBD3Y7AQAgByAHLgECQZkzbEGAgAFqQQ92OwECIAsgCy4BAEGZM2xBgIABakEPdjsBACALIAsuAQJBmTNsQYCAAWpBD3Y7AQIgDCAMLgEAQZkzbEGAgAFqQQ92IhA7AQAgDCAMLgECQZkzbEGAgAFqQQ92Ig87AQILIAMgAy8BAiIZIAggBCAWbEECdGoiFS4BAiIaIBDBIhBsIBUuAQAiFSAPwSIPbGpBAXRBgIACakEQdSIgIAggASAEbEECdGoiIS4BAiIiIAIuAQAiI2wgAi4BAiIkICEuAQAiIWxqQQF0QYCAAmpBEHUiJWoiJiAIIAQgF2xBAnRqIicuAQIiKCALLgEAIilsIAsuAQIiKyAnLgEAIidsakEBdEGAgAJqQRB1IiwgCCAEIBJsQQJ0aiIqLgECIi0gBy4BACIubCAHLgECIi8gKi4BACIqbGpBAXRBgIACakEQdSIwaiIxamo7AQIgAyADLwEAIjIgECAVbCAPIBpsa0EBdEGAgAJqQRB1Ig8gISAjbCAiICRsa0EBdEGAgAJqQRB1IhBqIhUgJyApbCAoICtsa0EBdEGAgAJqQRB1IhogKiAubCAtIC9sa0EBdEGAgAJqQRB1IiFqIiJqajsBACACICLBIiIgCWwgMkEQdEGAgAJyIiMgFcEiFSARbGpBgIB8cWpBgIACakEQdSIkIDAgLGvBIicgDmwgJSAga8EiICANbEGAgAJqQYCAfHFqQYCAAmpBEHUiJWs7AQAgAiAxwSIoIAlsIBlBEHRBgIACciIZICbBIiYgEWxqQYCAfHFqQYCAAmpBEHUiKUEAICEgGmvBIhogDmwgECAPa8EiDyANbEGAgAJqQYCAfHFqQYCAAmpBgIB8cWtBEHUiEGs7AQIgDCAQIClqOwECIAwgJCAlajsBACAHIBEgKGwgCSAmbCAZakGAgHxxakGAgAJqQRB1IhAgDiAPbCANIBpsQYCAAmpBgIB8cWtBgIACakEQdSIPajsBAiAHIBEgImwgCSAVbCAjakGAgHxxakGAgAJqQRB1IhkgDSAnbCAOICBsQYCAAmpBgIB8cWtBgIACakEQdSIVajsBACALIBAgD2s7AQIgCyAZIBVrOwEAIAxBBGohDCALQQRqIQsgB0EEaiEHIAJBBGohAiADQQRqIQMgBEEBaiIEIApHDQALIBRBAWoiFCAFRw0ACwwECyAFQQBMDQMgBEGIAmoiAiABIApsQQJ0aiEUIAFBA3QhEyAKQQF0IQwgBCgCBCEbQQAhCQNAIBQuAQJBAXQhESAAIAYgCWxBAnRqIQMgAiIHIQsgCiEEA0ACQCAbBEAgAyAMQQJ0aiIILwECIQ4gCC8BACENDAELIAMgAy4BAEGq1QBsQYCAAWpBD3Y7AQAgAyADLgECQarVAGxBgIABakEPdjsBAiADIApBAnRqIgggCC4BAEGq1QBsQYCAAWpBD3Y7AQAgCCAILgECQarVAGxBgIABakEPdjsBAiADIAxBAnRqIgggCC4BAEGq1QBsQYCAAWpBD3YiDTsBACAIIAguAQJBqtUAbEGAgAFqQQ92Ig47AQILIAMgCkECdGoiCCADLwEAIAcuAQAiDyANwSINbCAHLgECIhAgDsEiDmxrQQF0QYCAAmpBEHUiEiALLgEAIhYgCC4BACIXbCALLgECIhggCC4BAiIdbGtBAXRBgIACakEQdSIeaiIfQRB0QRF1azsBACAIIAMvAQIgDSAQbCAOIA9sakEBdEGAgAJqQRB1Ig4gFyAYbCAWIB1sakEBdEGAgAJqQRB1Ig1qIg9BEHRBEXVrOwECIAMgAy8BACAfajsBACADIAMvAQIgD2o7AQIgAyAMQQJ0aiIPIA0gDmvBIBFsQYCAAmpBEHYiDiAILwEAajsBACAPIAgvAQIgHiASa8EgEWxBgIACakEQdiINazsBAiAIIAgvAQAgDms7AQAgCCAILwECIA1qOwECIANBBGohAyAHIBNqIQcgCyABQQJ0aiELIARBAWsiBA0ACyAJQQFqIgkgBUcNAAsMAwsgCkEDbCERIApBAXQhFCAEKAIEBEAgBUEATA0DIApBAEwNAyABQQxsIRsgAUEDdCEPIARBiAJqIQQDQCAAIAYgCGxBAnRqIQNBACENIAQiAiEHIAIhCwNAIAMvAQAhEyADIBRBAnRqIg4gAy8BAiIQIAcuAQIiEiAOLgEAIhZsIA4uAQIiFyAHLgEAIhhsakEBdEGAgAJqQRB2Ih1qIh4gCy4BAiIfIAMgEUECdGoiDC4BACIZbCAMLgECIhUgCy4BACIabGpBAXRBgIACakEQdSIgIAIuAQIiISADIApBAnRqIgkuAQAiImwgCS4BAiIjIAIuAQAiJGxqQQF0QYCAAmpBEHUiJWoiJms7AQIgDiATIBYgGGwgEiAXbGtBAXRBgIACakEQdiIOaiISIBkgGmwgFSAfbGtBAXRBgIACakEQdSIWICIgJGwgISAjbGtBAXRBgIACakEQdSIXaiIYazsBACADIB4gJmo7AQIgAyASIBhqOwEAIAkgECAdayIQIBcgFmsiEmo7AQIgCSATIA5rIg4gJSAgayIJazsBACAMIBAgEms7AQIgDCAJIA5qOwEAIANBBGohAyALIBtqIQsgByAPaiEHIAIgAUECdGohAiANQQFqIg0gCkcNAAsgCEEBaiIIIAVHDQALDAMLIAVBAEwNAiAKQQBMDQIgAUEMbCETIAFBA3QhGyAEQYgCaiEEA0AgACAGIAhsQQJ0aiEDQQAhDiAEIgIhByACIQsDQCADLgEAIQ8gAyAUQQJ0aiINIAMuAQJBAmpBAnYiECANLgECIhIgBy4BACIWbCAHLgECIhcgDS4BACIYbGpBgIAEakERdSIdaiIeIAMgEUECdGoiDC4BAiIfIAsuAQAiGWwgCy4BAiIVIAwuAQAiGmxqQYCABGpBEXUiICADIApBAnRqIgkuAQIiISACLgEAIiJsIAIuAQIiIyAJLgEAIiRsakGAgARqQRF1IiVqIiZrOwECIA0gD0ECakECdiINIBYgGGwgEiAXbGtBgIAEakERdSIPaiISIBkgGmwgFSAfbGtBgIAEakERdSIWICIgJGwgISAjbGtBgIAEakERdSIXaiIYazsBACADIB4gJmo7AQIgAyASIBhqOwEAIAkgECAdayIQIBcgFmsiEms7AQIgCSANIA9rIg0gJSAgayIJajsBACAMIBAgEmo7AQIgDCANIAlrOwEAIANBBGohAyALIBNqIQsgByAbaiEHIAIgAUECdGohAiAOQQFqIg4gCkcNAAsgCEEBaiIIIAVHDQALDAILIAQoAgQEQCAFQQBMDQIgCkEATA0CIARBiAJqIQQDQCAAIAYgCGxBAnRqIgMgCkECdGohAkEAIQsgBCEHA0AgAiADLwEAIg4gBy4BACINIAIuAQAiDGwgBy4BAiIJIAIuAQIiEWxrQQF0QYCAAmpBEHYiFGs7AQAgAiADLwECIhMgCSAMbCANIBFsakEBdEGAgAJqQRB2Ig1rOwECIAMgDSATajsBAiADIA4gFGo7AQAgA0EEaiEDIAJBBGohAiAHIAFBAnRqIQcgC0EBaiILIApHDQALIAhBAWoiCCAFRw0ACwwCCyAFQQBMDQEgCkEATA0BIARBiAJqIQQDQCAAIAYgCGxBAnRqIgMgCkECdGohAkEAIQsgBCEHA0AgAiADLgEAQQ50QYCAAWoiDiAHLgEAIg0gAi4BACIMbCAHLgECIgkgAi4BAiIRbGtBAXUiFGtBD3Y7AQAgAiADLgECQQ50IhMgCSAMbCANIBFsakEBdSINa0GAgAFqQQ92OwECIAMgDSATakGAgAFqQQ92OwECIAMgDiAUakEPdjsBACADQQRqIQMgAkEEaiECIAcgAUECdGohByALQQFqIgsgCkcNAAsgCEEBaiIIIAVHDQALDAELIAVBAEwNACAJQRJODQEgCkEATA0AIAlBAEwNACAJQQJOBEAgBEGIAmohEiAJQfz///8HcSEWIAlBA3EhEyAKIApqIhcgCmoiGCAKaiEdIAlBBEkhHgNAIAAgBiAUbEECdGohESAEKAIAIRtBACEIA0ACQCAEKAIEBEBBACELIAghA0EAIQJBACEMIB5FBEADQCAcIAJBAnRqIgcgESADQQJ0aigBADYCACAHIBEgAyAKakECdGooAQA2AgQgByARIAMgF2pBAnRqKAEANgIIIAcgESADIBhqQQJ0aigBADYCDCACQQRqIQIgAyAdaiEDIAxBBGoiDCAWRw0ACwsgE0UNAQNAIBwgAkECdGogESADQQJ0aigBADYCACACQQFqIQIgAyAKaiEDIAtBAWoiCyATRw0ACwwBC0H//wEgCW4hB0EAIQMgCCECA0AgHCADQQJ0aiILIBEgAkECdGooAQAiDkEQdSAHbEGAgAFqQQ92OwECIAsgDsEgB2xBgIABakEPdjsBACACIApqIQIgA0EBaiIDIAlHDQALCyAcKAIAIg5BEHYhDUEAIQ8gCCECA0AgESACQQJ0aiIQIA42AQAgASACbCEfQQEhAyANIQcgDiELQQAhDANAIBAgByASIAwgH2oiDCAbQQAgDCAbThtrIgxBAnRqIhkuAQIiFSAcIANBAnRqIhouAQAiIGwgGi4BAiIaIBkuAQAiGWxqQQF0QYCAAmpBEHZqIgc7AQIgECALIBkgIGwgFSAabGtBAXRBgIACakEQdmoiCzsBACADQQFqIgMgCUcNAAsgAiAKaiECIA9BAWoiDyAJRw0ACyAIQQFqIgggCkcNAAsgFEEBaiIUIAVHDQALDAELA0AgACAGIAxsQQJ0aiEBQQAhAwNAAkAgBCgCBARAIBwgASADQQJ0aigBACIHNgIADAELIBxB//8BIAluIgIgASADQQJ0aigBACIHQRB1bEGAgAFqQQ92OwECIBwgB8EgAmxBgIABakEPdjsBACAcKAIAIQcLIAEgA0ECdGogBzYBACADQQFqIgMgCkcNAAsgDEEBaiIMIAVHDQALCyAcQdAAaiQADwtB5QxBpgIQYgAL2QIBCH8gBCgCACEFAkAgBCgCBCIGQQFHBEAgBUEATA0BIARBCGohByACIAVsIQhBACEEIAIgA2xBAnQhAgNAIAAgASAIIAMgBxBhIAAgBkECdGohACABIAJqIQEgBEEBaiIEIAVHDQALDAELIAVBAEwNACAFQQNxIQYgAiADbCEHAkAgBUEESQRAQQAhBAwBCyAAQQxqIQkgAEEIaiEKIABBBGohCyAFQfz///8HcSEMQQAhBEEAIQUDQCAAIARBAnQiAmogASgBADYBACACIAtqIAEgB0ECdCIDaiIBKAEANgEAIAIgCmogASADaiIBKAEANgEAIAIgCWogASADaiIBKAEANgEAIAEgA2ohASAEQQRqIQQgBUEEaiIFIAxHDQALCyAGRQ0AA0AgACAEQQJ0aiABKAEANgEAIARBAWohBCABIAdBAnRqIQEgCEEBaiIIIAZHDQALCws1AQF/IwBBEGsiAiQAIAIgADYCCCACIAE2AgQgAkGICjYCAEGACCgCAEGiDiACECJBARAKAAupBgEEfyAAQQJ0QYgCaiEEAkAgA0UEQCAEEBUhAgwBCyACBH8gAkEAIAMoAgAgBE8bBUEACyECIAMgBDYCAAsgAgRAIAIgATYCBCACIAA2AgAgAEEASgRAIAJBiAJqIQVBACEDA0AgBSADQQJ0aiIGAn9BgIAIIANBACADayABG0ERdCAAbSIHQf//B3EiBGsgBCAEQYCABEsbIgRB//8BcQRAIARB//8BTQRAQf//ASAEIARsQQF0QYCAAmpBEHYiBCAEQY77//8HbEGAgAFqQQ92QdXAAGpB//8DcWxBAXRBgICK7wFrQRB1IARsQYCAAWpBD3UgBGsiBEGAgH5zIARBAE4bDAILQYGAfkEAIARBEHRrIgRBD3UgBEEQdWxBgIACakEQdSIEIARBjvv//wdsQYCAAWpBD3ZB1cAAakH//wNxbEEBdEGAgIrvAWtBEHUgBGxBgIABakEPdSAEayIEQf//AXNBAWogBEEAThsMAQtBACAEQYCAAnENABpBgYB+Qf//ASAEGws7AQAgBgJ/QYCACCAHQYCABmpB//8HcSIEayAEIARBgIAESxsiBEH//wFxBEAgBEH//wFNBEBB//8BIAQgBGxBAXRBgIACakEQdiIEIARBjvv//wdsQYCAAWpBD3ZB1cAAakH//wNxbEEBdEGAgIrvAWtBEHUgBGxBgIABakEPdSAEayIEQYCAfnMgBEEAThsMAgtBgYB+QQAgBEEQdGsiBEEPdSAEQRB1bEGAgAJqQRB1IgQgBEGO+///B2xBgIABakEPdkHVwABqQf//A3FsQQF0QYCAiu8Ba0EQdSAEbEGAgAFqQQ91IARrIgRB//8Bc0EBaiAEQQBOGwwBC0EAIARBgIACcQ0AGkGBgH5B//8BIAQbCzsBAiADQQFqIgMgAEcNAAsLQQQhAQNAIAAgAW8EQANAQQIhAwJAAkACQCABQQJrDgMAAQIBC0EDIQMMAQsgAUECaiEDCyAAIAAgACADIAMgA2wgAEobIANBgPoBShsiAW8NAAsLIAIgATYCCCACIAAgAW0iADYCDCACQQhqIQIgAEEBSg0ACwsLtAIAAkACQAJAAkACQAJAAkACQAJAAkACQCABQQlrDhIACAkKCAkBAgMECgkKCggJBQYHCyACIAIoAgAiAUEEajYCACAAIAEoAgA2AgAPCyACIAIoAgAiAUEEajYCACAAIAEyAQA3AwAPCyACIAIoAgAiAUEEajYCACAAIAEzAQA3AwAPCyACIAIoAgAiAUEEajYCACAAIAEwAAA3AwAPCyACIAIoAgAiAUEEajYCACAAIAExAAA3AwAPCyACIAIoAgBBB2pBeHEiAUEIajYCACAAIAErAwA5AwAPCwALDwsgAiACKAIAIgFBBGo2AgAgACABNAIANwMADwsgAiACKAIAIgFBBGo2AgAgACABNQIANwMADwsgAiACKAIAQQdqQXhxIgFBCGo2AgAgACABKQMANwMAC28BBX8gACgCACIDLAAAQTBrIgFBCUsEQEEADwsDQEF/IQQgAkHMmbPmAE0EQEF/IAEgAkEKbCIFaiABIAVB/////wdzSxshBAsgACADQQFqIgU2AgAgAywAASAEIQIgBSEDQTBrIgFBCkkNAAsgAgu/CQEDfyMAQfAAayIFJAAgBSABNgIoIAUgADYCJCAFIAI2AixBpPkAQaT5ACgCACICQQFqNgIAAkACQAJAAkACf0EAIAJBAEgNABpBAUHM+QAtAAANABpBzPkAQQE6AABByPkAQcj5ACgCAEEBajYCAEECC0H/AXEiAkECRwRAIAJBAXFFDQEgBUEYaiAAIAEoAhgRAgAgBSAFKAIcQQAgBSgCGCIAGzYCNCAFIABBASAAGzYCMCAFQQM2AlggBUHs7QA2AlQgBUICNwJgIAUgBUEwaq1CgICAgMAEhDcDSCAFIAVBLGqtQoCAgIDwCIQ3A0AgBSAFQUBrNgJcIAVBOGoiACAFQe8AaiAFQdQAahAeIAAQHwwEC0GU+QAoAgAhAQNAIAFBb0sNAiABQQFGDQIgAUECcQ0CQZT5ACABQQFyQRBqQZT5ACgCACIAIAAgAUYiAhs2AgAgACEBIAJFDQALDAILIAVBAzYCWCAFQdTtADYCVCAFQgI3AmAgBSAFQSRqrUKAgICAgAmENwNIIAUgBUEsaq1CgICAgPAIhDcDQCAFIAVBQGs2AlwgBUE4aiIAIAVB7wBqIAVB1ABqEB4gABAfDAILQZT5ABBuCyAFQZT5ADYCRCAFQZz5ADYCQAJAAkBBnPkAKAIABEBB+PgAQQA2AgAgBSgCLCEBIAUoAigiACgCFCAFQRBqIAUoAiQiAhADQfj4ACgCAEH4+ABBADYCAEEBRg0CIAUoAhQhBiAFKAIQIQdB+PgAQQA2AgAgBSAEOgBhIAUgAzoAYCAFIAE2AlwgBSAHNgJUIAUgBjYCWEGg+QAoAgAoAhRBnPkAKAIAIAVB1ABqEAMMAQtB+PgAQQA2AgAgBSgCLCEBIAUoAigiACgCFCAFQQhqIAUoAiQiAhADQfj4ACgCAEH4+ABBADYCAEEBRg0BIAUoAgwhBiAFKAIIIQdB+PgAQQA2AgAgBSAEOgBhIAUgAzoAYCAFIAE2AlwgBSAHNgJUIAUgBjYCWEHJACAFQdQAahACC0H4+AAoAgBB+PgAQQA2AgBBAUYNACAFQUBrIgEQdUHM+QBBADoAACADRQRAIAVBADYCZCAFQQE2AlggBUGE7gA2AlQgBUIENwJcIAEgBUHvAGogBUHUAGoQHiABEB8MAgsjAEFAaiIBJAAgAQJ/IwBBEGsiAyQAIANBCGogAiAAKAIQEQIAIAMoAgwhACADKAIIIQRB4AAQGEHQAGoiAkUEQAJAIAAoAgAiAgRAQfj4AEEANgIAIAIgBBACQfj4ACgCAEH4+ABBADYCAEEBRg0BCyAAKAIEBEAgACgCCBogBBAUCyADQRBqJABBAwwCCxAAIAAoAgQEQCAAKAIIGiAEEBQLEAEACyACIAA2AgwgAiAENgIIIAJBADoABCACQdzmADYCACACQdzmAEEiEBAACzYCDCABQQI2AhwgAUGM7gA2AhggAUIBNwIkIAEgAUEMaq1CgICAgIABhDcDMCABIAFBMGo2AiAgAUEQaiIAIAFBP2ogAUEYahAeIAAQHxAdAAsQAEH4+ABBADYCAEE6IAVBQGsQAkH4+AAoAgBB+PgAQQA2AgBBAUYEQBAAGhAgAAsQAQALEB0AC40VAhJ/A34jAEFAaiIGJAAgBiABNgI8IAZBJ2ohFSAGQShqIRECQAJAAkACQANAQQAhBQNAIAEhCyAFIAxB/////wdzSg0CIAUgDGohDAJAAkACQAJAIAEiBS0AACIJBEADQAJAAkAgCUH/AXEiAUUEQCAFIQEMAQsgAUElRw0BIAUhCQNAIAktAAFBJUcEQCAJIQEMAgsgBUEBaiEFIAktAAIgCUECaiIBIQlBJUYNAAsLIAUgC2siBSAMQf////8HcyIWSg0JIAAEQCAAIAsgBRApCyAFDQcgBiABNgI8IAFBAWohBUF/IRACQCABLAABQTBrIghBCUsNACABLQACQSRHDQAgAUEDaiEFQQEhEiAIIRALIAYgBTYCPEEAIQoCQCAFLAAAIglBIGsiAUEfSwRAIAUhCAwBCyAFIQhBASABdCIBQYnRBHFFDQADQCAGIAVBAWoiCDYCPCABIApyIQogBSwAASIJQSBrIgFBIE8NASAIIQVBASABdCIBQYnRBHENAAsLAkAgCUEqRgRAAn8CQCAILAABQTBrIgFBCUsNACAILQACQSRHDQACfyAARQRAIAQgAUECdGpBCjYCAEEADAELIAMgAUEDdGooAgALIQ8gCEEDaiEBQQEMAQsgEg0GIAhBAWohASAARQRAIAYgATYCPEEAIRJBACEPDAMLIAIgAigCACIFQQRqNgIAIAUoAgAhD0EACyESIAYgATYCPCAPQQBODQFBACAPayEPIApBgMAAciEKDAELIAZBPGoQZSIPQQBIDQogBigCPCEBC0EAIQVBfyEHAn9BACABLQAAQS5HDQAaIAEtAAFBKkYEQAJ/AkAgASwAAkEwayIIQQlLDQAgAS0AA0EkRw0AIAFBBGohAQJ/IABFBEAgBCAIQQJ0akEKNgIAQQAMAQsgAyAIQQN0aigCAAsMAQsgEg0GIAFBAmohAUEAIABFDQAaIAIgAigCACIIQQRqNgIAIAgoAgALIQcgBiABNgI8IAdBAE4MAQsgBiABQQFqNgI8IAZBPGoQZSEHIAYoAjwhAUEBCyETA0AgBSENQRwhCCABIg4sAAAiBUH7AGtBRkkNCyABQQFqIQEgBSANQTpsakHvDmotAAAiBUEBa0H/AXFBCEkNAAsgBiABNgI8AkAgBUEbRwRAIAVFDQwgEEEATgRAIABFBEAgBCAQQQJ0aiAFNgIADAwLIAYgAyAQQQN0aikDADcDMAwCCyAARQ0IIAZBMGogBSACEGQMAQsgEEEATg0LQQAhBSAARQ0ICyAALQAAQSBxDQsgCkH//3txIgkgCiAKQYDAAHEbIQpBACEQQZsIIRQgESEIAkACQAJ/AkACQAJAAkACQAJAAn8CQAJAAkACQAJAAkACQCAOLQAAIgXAIg5BU3EgDiAFQQ9xQQNGGyAOIA0bIgVB2ABrDiEEFhYWFhYWFhYQFgkGEBAQFgYWFhYWAgUDFhYKFgEWFgQACwJAIAVBwQBrDgcQFgsWEBAQAAsgBUHTAEYNCwwVCyAGKQMwIRhBmwgMBQtBACEFAkACQAJAAkACQAJAAkAgDQ4IAAECAwQcBQYcCyAGKAIwIAw2AgAMGwsgBigCMCAMNgIADBoLIAYoAjAgDKw3AwAMGQsgBigCMCAMOwEADBgLIAYoAjAgDDoAAAwXCyAGKAIwIAw2AgAMFgsgBigCMCAMrDcDAAwVC0EIIAcgB0EITRshByAKQQhyIQpB+AAhBQsgESEBIAYpAzAiGCIXQgBSBEAgBUEgcSEJA0AgAUEBayIBIBenQQ9xQYATai0AACAJcjoAACAXQg9WIBdCBIghFw0ACwsgASELIBhQDQMgCkEIcUUNAyAFQQR2QZsIaiEUQQIhEAwDCyARIQEgBikDMCIYIhdCAFIEQANAIAFBAWsiASAXp0EHcUEwcjoAACAXQgdWIBdCA4ghFw0ACwsgASELIApBCHFFDQIgByARIAFrIgFBAWogASAHSBshBwwCCyAGKQMwIhhCAFMEQCAGQgAgGH0iGDcDMEEBIRBBmwgMAQsgCkGAEHEEQEEBIRBBnAgMAQtBnQhBmwggCkEBcSIQGwshFCARIQECQCAYIhdCgICAgBBUBEAgFyEZDAELA0AgAUEBayIBIBcgF0IKgCIZQgp+fadBMHI6AAAgF0L/////nwFWIBkhFw0ACwsgGUIAUgRAIBmnIQUDQCABQQFrIgEgBSAFQQpuIgtBCmxrQTByOgAAIAVBCUsgCyEFDQALCyABIQsLIBMgB0EASHENESAKQf//e3EgCiATGyEKAkAgGEIAUg0AIAcNACARIQtBACEHDA4LIAcgGFAgESALa2oiASABIAdIGyEHDA0LIAYtADAhBQwLCwJ/Qf////8HIAcgB0H/////B08bIggiDkEARyEKAkACQAJAIAYoAjAiAUHnDSABGyILIgUiDUEDcUUNACAORQ0AA0AgDS0AAEUNAiAOQQFrIg5BAEchCiANQQFqIg1BA3FFDQEgDg0ACwsgCkUNAQJAIA0tAABFDQAgDkEESQ0AA0BBgIKECCANKAIAIgFrIAFyQYCBgoR4cUGAgYKEeEcNAiANQQRqIQ0gDkEEayIOQQNLDQALCyAORQ0BCwNAIA0gDS0AAEUNAhogDUEBaiENIA5BAWsiDg0ACwtBAAsiASAFayAIIAEbIgEgC2ohCCAHQQBOBEAgCSEKIAEhBwwMCyAJIQogASEHIAgtAAANDwwLCyAGKQMwIhdCAFINAUEAIQUMCQsgBwRAIAYoAjAMAgtBACEFIABBICAPQQAgChAjDAILIAZBADYCDCAGIBc+AgggBiAGQQhqIgU2AjBBfyEHIAULIQlBACEFA0ACQCAJKAIAIgtFDQAgBkEEaiALEGoiC0EASA0PIAsgByAFa0sNACAJQQRqIQkgBSALaiIFIAdJDQELC0E9IQggBUEASA0MIABBICAPIAUgChAjIAVFBEBBACEFDAELQQAhCCAGKAIwIQkDQCAJKAIAIgtFDQEgBkEEaiIHIAsQaiILIAhqIgggBUsNASAAIAcgCxApIAlBBGohCSAFIAhLDQALCyAAQSAgDyAFIApBgMAAcxAjIA8gBSAFIA9IGyEFDAgLIBMgB0EASHENCUE9IQggBisDMAALIAUtAAEhCSAFQQFqIQUMAAsACyAADQkgEkUNA0EBIQUDQCAEIAVBAnRqKAIAIgAEQCADIAVBA3RqIAAgAhBkQQEhDCAFQQFqIgVBCkcNAQwLCwsgBUEKTwRAQQEhDAwKCwNAIAQgBUECdGooAgANAUEBIQwgBUEBaiIFQQpHDQALDAkLQRwhCAwGCyAGIAU6ACdBASEHIBUhCyAJIQoLIAcgCCALayIJIAcgCUobIgEgEEH/////B3NKDQNBPSEIIA8gASAQaiIHIAcgD0gbIgUgFkoNBCAAQSAgBSAHIAoQIyAAIBQgEBApIABBMCAFIAcgCkGAgARzECMgAEEwIAEgCUEAECMgACALIAkQKSAAQSAgBSAHIApBgMAAcxAjIAYoAjwhAQwBCwsLQQAhDAwDC0E9IQgLQcDzACAINgIAC0F/IQwLIAZBQGskACAMC58CAgR/AX4jAEEQayIBJAAgACkCACEFIAEgADYCDCABIAU3AgQgAUEEaiEEIwBBEGsiACQAIAEoAgQiAigCDCEDAkACQAJAAkAgAigCBA4CAAECCyADDQFBASECQQAhAwwCCyADDQAgAigCACICKAIEIQMgAigCACECDAELQfj4AEEANgIAIABBgICAgHg2AgAgACAENgIMIAEoAgwiAi0ACSEDQcEAIABBuO0AIAEoAgggAi0ACCADEAdB+PgAKAIAQfj4AEEANgIAQQFHBEAACxAAIAAoAgBBgICAgHhyQYCAgIB4RwRAIAAoAgQQFAsQAQALIAAgAzYCBCAAIAI2AgAgAEGc7QAgASgCCCABKAIMIgAtAAggAC0ACRBmAAuJBQIFfwF+IwBBMGsiAyQAQYj5ACgCACIEBH8gBAVBiPkAEG8LGiADQaT5ACgCAEH/////B3EEf0HI+QAoAgAFQQALQQBHOgAMIANBiPkANgIIIAApAgAhCCADLQAMIQUgAygCCCEGIAMgAjYCJCADIAE2AiAgAyAINwIYAn8Cf0HU+QAoAgAiBEECTQRAQfTJAEEAQbj5ACkDACIIQaj5ACkDAFEbQQAgCEIAUhsMAQsgBCgCCCIHBEAgBCgCDEEBawwCC0H0yQBBACAEKQMAQbj5ACkDAFEbCyEHQQQLIQRB+PgAQQA2AgBBxAAgA0EYaiAHIAQQBEH4+AAoAgAhBEH4+ABBADYCAAJAAkAgBEEBRg0AAkACQAJAAkAgACgCCC0AAEEBaw4DAQAFAwtB+OwALQAAQfjsAEEAOgAADQEMBAtB+PgAQQA2AgBBxQAgA0EYaiIAIAEgAigCJEEBEAlB+PgAKAIAQfj4AEEANgIAQQFGDQJB+PgAQQA2AgBBxgAgABACQfj4ACgCAEH4+ABBADYCAEEBRw0DDAILQfj4AEEANgIAIANBADYCKCADQcDsADYCGCADQgQ3AiAgA0EBNgIcIAIoAiQgA0EQaiIAIAEgA0EYahAEQfj4ACgCAEH4+ABBADYCAEEBRg0BQfj4AEEANgIAQcYAIAAQAkH4+AAoAgBB+PgAQQA2AgBBAUcNAgwBC0H4+ABBADYCAEHFACADQRhqIgAgASACKAIkQQAQCUH4+AAoAgBB+PgAQQA2AgBBAUYNAEH4+ABBADYCAEHGACAAEAJB+PgAKAIAQfj4AEEANgIAQQFHDQELEAAgBiAFEDIQAQALIAYgBRAyIANBMGokAAuZAgAgAEUEQEEADwsCfwJAIAAEfyABQf8ATQ0BAkBB1PgAKAIAKAIARQRAIAFBgH9xQYC/A0YNAwwBCyABQf8PTQRAIAAgAUE/cUGAAXI6AAEgACABQQZ2QcABcjoAAEECDAQLIAFBgEBxQYDAA0cgAUGAsANPcUUEQCAAIAFBP3FBgAFyOgACIAAgAUEMdkHgAXI6AAAgACABQQZ2QT9xQYABcjoAAUEDDAQLIAFBgIAEa0H//z9NBEAgACABQT9xQYABcjoAAyAAIAFBEnZB8AFyOgAAIAAgAUEGdkE/cUGAAXI6AAIgACABQQx2QT9xQYABcjoAAUEEDAQLC0HA8wBBGTYCAEF/BUEBCwwBCyAAIAE6AABBAQsLCQAgAEEEOgAAC1kBAX8gACAAKAJIIgFBAWsgAXI2AkggACgCACIBQQhxBEAgACABQSByNgIAQX8PCyAAQgA3AgQgACAAKAIsIgE2AhwgACABNgIUIAAgASAAKAIwajYCEEEAC9EGAQd/IwBBEGsiByQAQcD5ACgCACEBAkADQAJAIAFBb0sNACABQQFGDQAgAUECcQ0AQcD5ACABQQFyQRBqQcD5ACgCACIDIAEgA0YiBBs2AgAgAyEBIARFDQEMAgsLQcD5ABBuCyAHQcD5ADYCDCAHQcX5ADYCCAJAAn8CQCACIgNBA3EEQANAIAMtAAAiAUUNAiABQT1GDQIgA0EBaiIDQQNxDQALCwJAAkBBgIKECCADKAIAIgRrIARyQYCBgoR4cUGAgYKEeEcNAANAQYCChAggBEG9+vTpA3MiAWsgAXJBgIGChHhxQYCBgoR4Rw0BIAMoAgQhBCADQQRqIgEhAyAEQYCChAggBGtyQYCBgoR4cUGAgYKEeEYNAAsMAQsgAyEBCwNAIAEiAy0AACIERQ0BIAFBAWohASAEQT1HDQALC0EAIAIgA0YNABoCQCACIAMgAmsiCWotAAANAEGA+QAoAgAiBUUNACAFKAIAIgNFDQADQAJAAn8gAiEBQQAgCSIERQ0AGiABLQAAIgYEfwJAA0AgBiADLQAAIgpHDQEgCkUNASAEQQFrIgRFDQEgA0EBaiEDIAEtAAEhBiABQQFqIQEgBg0AC0EAIQYLIAYFQQALIAMtAABrC0UEQCAFKAIAIAlqIgEtAABBPUYNAQsgBSgCBCEDIAVBBGohBSADDQEMAgsLIAFBAWohCAsgCAsiAUUEQCAAQYCAgIB4NgIADAELQQAhAgJAIAEQJSIEQQBOBEAgBEUEQEEBIQMMAgtB2fkALQAAGkEBIQIgBEEBEBwiAw0BC0H4+ABBADYCAEEQIAIgBEHk6AAQBEH4+AAoAgBB+PgAQQA2AgBBAUcEQAALEAAhAUH4+ABBADYCAEE6IAdBCGoQAkH4+AAoAgBB+PgAQQA2AgBBAUcEQCABEAEACxAAGhAgAAsgBARAIAMgASAE/AoAAAsgACAENgIIIAAgAzYCBCAAIAQ2AgALQcD5ACgCACEBAkADQAJAQcD5AAJ/IAFBAnFFBEAgAUERayIAQQFyQQAgABsMAQsgAUEIcUUNASABQXZxC0HA+QAoAgAiACAAIAFGIgIbNgIAIAAhASACRQ0BDAILC0HA+QAgARB0CyAHQRBqJAALygkBB38jAEHQAGsiAyQAIANCADcDECADQQA6ACAgA0IANwMYIANBADoAISAAKAIAIQIgA0EQakEMciEHAkADQEEAIQYDQAJAQfj4AEEANgIAQTQgA0EIaiACEANB+PgAKAIAIQFB+PgAQQA2AgACQAJAAkACQAJAIAFBAUYNAAJAIAMoAghBAXFFBEAgAkECcSIEDQEgBkEHTw0BIAZBAWohBiAAKAIAIQIMCAsgACADKAIMIAAoAgAiBCACIARGGzYCACACIARHDQUCQCADKAIcIgBFDQAgACAAKAIAIgBBAWs2AgAgAEEBRw0AIAcQLAsgA0HQAGokAA8LIAMoAhxFBEBB+PgAQQA2AgBBNSAHEAgaQfj4ACgCAEH4+ABBADYCAEEBRg0BCyADQQA2AhQgA0EAOgAgIAMgAkFwcTYCECADQRBqIgUgAkEJcXJBAnIhASAERQRAIAAgASAAKAIAIgQgAiAERiIBGzYCACADIAU2AhggAQ0CDAULIAAgAUEEaiIBIAAoAgAiBCACIARGGzYCACADQQA2AhggAiAERw0EIAJBBHENAQNAIAFBcHEiBSgCCCIERQRAIAUhAgNAIAIoAgAiBCACNgIEIAQiAigCCCIERQ0ACwsgBSAENgIIIAFBCXFBAUYEQCAAIAFBc3EgACgCACICIAEgAkYiBBs2AgAgAiEBIARFDQEMAwsCQAJAIAFBCHEiAkUEQCAELQARQQFxDQELQRFBACACGyEGDAELIAQoAgQiAkUEQEEAIQYMAQsgBSACNgIIIAAgAUFzcSAAKAIAIgIgASACRiIBGzYCACABRQRAIAUgBDYCCCACIQEMAgtB+PgAQQA2AgBBNiAEEAJB+PgAKAIAQfj4AEEANgIAQQFHDQMMBAsgACAGIAAoAgAiAiABIAJGGzYCACABIAJHIAIhAQ0ACwNAQfj4AEEANgIAIAQoAgRBNiAEEAJB+PgAKAIAQfj4AEEANgIAQQFGDQMiBA0ACwwBCxAAIQEgAygCHCIADQQMBwsgAy0AIEUEQANAAkAgAygCHCICBEAgAkEAIAIoAmAiASABQQJGIgEbNgJgIAENASACIAIoAmAiAUEBIAEbNgJgIAFFBEADQCACIAIoAmAiAUEAIAFBAkciARs2AmAgAQ0ACwwCCyABQQJHBEBB+PgAQQA2AgAgA0EANgJIIANBrPAANgI4IANCBDcCQCADQQE2AjxBLCADQThqQbTwABADQfj4ACgCAEH4+ABBADYCAEEBRw0GDAULIAIoAmAhASACQQA2AmAgAyABNgI0IAFBAkYNAUH4+ABBADYCACADQgA3AkQgA0KBgICAwAA3AjwgA0GU8AA2AjhBN0EAIANBNGpBxNwAIANBOGpBnPAAEAdB+PgAKAIAQfj4AEEANgIAQQFHDQUMBAtB+PgAQQA2AgBBOEHs7wAQAkH4+AAoAgBB+PgAQQA2AgBBAUcNBAwDCyADLQAgRQ0ACwsgACgCACECDAULEAAaQfj4AEEANgIAQTlB+PgAEAJB+PgAKAIAQfj4AEEANgIAQQFHDQAQABoQIAALAAsgBCECDAELCwsgACAAKAIAIgBBAWs2AgAgAEEBRw0AIAcQLCABEAEACyABEAEAC9YBAQN/IwBBIGsiAiQAIAJCADcDGCACQgA3AxAgAkIANwMIQdn5AC0AABoCQEEYQQQQHCIBRQRAQfj4AEEANgIAQRFBBEEYEANB+PgAKAIAQfj4AEEANgIAQQFHDQEQABABAAsgAUIANwIAIAFCADcCECABQgA3AghB+PgAQQA2AgBBMiABEAJB+PgAKAIAQfj4AEEANgIAQQFGBEAQACABEBQQAQALIAAgACgCACIAIAEgABs2AgACQCAARQRAIAEhAAwBCyABEBQLIAJBIGokACAADwsACwIACzcBAX8jAEEgayIAJAAgAEEANgIYIABBATYCDCAAQgQ3AhAgAEGU6QA2AgggAEEIakGc6QAQFgALvQYBBX8jAEEgayIFJAAgASgCACIGQYCAgIB4RwRAIwBBIGsiAiQAIAEoAgQhAwJAAkACQAJAAkACQCABKAIIIgFBB00EQCABRQ0BIAMtAABFDQJBASEEIAFBAUYNASADLQABRQ0CQQIhBCABQQJGDQEgAy0AAkUNAkEDIQQgAUEDRg0BIAMtAANFDQJBBCEEIAFBBEYNASADLQAERQ0CQQUhBCABQQVGDQEgAy0ABUUNAkEGIQQgAUEGRg0BIAMtAAZFDQIMAQtB+PgAQQA2AgBBDyACQQhqQQAgAyABEAlB+PgAKAIAQfj4AEEANgIAQQFHBEAgAigCCEEBcUUNASACKAIMIQQMAgsQACEBIAZFDQMgAxAUDAMLIAIgATYCGCACIAM2AhQgAiAGNgIQIAIgAkEQahCBASACKAIEIQEgAigCACEDDAELIAZBgICAgHhGDQBB+PgAQQA2AgAgAiAENgIcIAIgATYCGCACIAM2AhQgAiAGNgIQQS5BxckAQS8gAkEQakGM5wBBrOkAEAdB+PgAKAIAQfj4AEEANgIAQQFHDQIQACEBIAIoAhBFDQEgAigCFBAUDAELIAUgATYCFCAFIAM2AhAgAkEgaiQADAILIAEQAQsACyAFKAIUIQQgBSgCECEDC0H4+ABBADYCAEEpIAVBCGpBCEHgABAEQfj4ACgCACEBQfj4AEEANgIAAkACQAJAIAFBAUYNACAFKAIIIQIgBSgCDCIGBH9B2fkALQAAGiAGIAIQHAUgAgsiAUUEQEH4+ABBADYCAEERIAIgBhADQfj4ACgCAEH4+ABBADYCAEEBRg0BAAsgAUKBgICAEDcDACABIAQ2AhQgASADNgIQIAEgADcDCCAFIAE2AhwgAUEYaiICQQBBzAD8CwBB+PgAQQA2AgBBKiACEAJB+PgAKAIAQfj4AEEANgIAQQFHDQEQACECIAEgASgCACIBQQFrNgIAIAFBAUcNAgJAIAUoAhwiAUF/Rg0AIAEgASgCBCIDQQFrNgIEIANBAUcNACABEBQLDAILEAAhAiADRQ0BIANBADoAACAERQ0BIAMQFCACEAEACyAFQSBqJAAgAQ8LIAIQAQALBABBAQu2AwEDfyABQXBxIgMoAggiBEUEQCADIQIDQCACKAIAIgQgAjYCBCAEIgIoAggiBEUNAAsLIAMgBDYCCCAEIAQoAgAiAkEQazYCACACQRBGBEAgACEDA0ACQAJAIAFBBHFFBEAgAyABQX5xQQRqIgAgAygCACICIAEgAkYbNgIAIAEgAkcNAQNAIABBcHEiBCgCCCICRQRAIAQhAQNAIAEoAgAiAiABNgIEIAIiASgCCCICRQ0ACwsgBCACNgIIAkAgAEEJcUEBRwRAAkAgAEEIcSIBRQRAIAItABFBAXENAQtBEUEAIAEbIQEMAgsgAigCBCIBRQRAQQAhAQwCCyAEIAE2AgggAyAAQXNxIAMoAgAiASAAIAFGIgAbNgIAIABFBEAgBCACNgIIIAEhAAwDCyACED4MBQsgAyAAQXNxIAMoAgAiASAAIAFGIgIbNgIAIAEhACACRQ0BDAQLIAMgASADKAIAIgEgACABRhs2AgAgACABRyABIQANAAsDQCACKAIEIAIQPiICDQALDAILIAMgAUF+cSADKAIAIgIgASACRiIAGzYCACAADQELIAIhAQwBCwsLC2gBA38gACgCBCICKAIAIQACQANAAkAgAgJ/IABBAnFFBEAgAEERayIBQQFyQQAgARsMAQsgAEEIcUUNASAAQXZxCyACKAIAIgEgACABRiIDGzYCACABIQAgA0UNAQwCCwsgAiAAEHQLC5QCAgJ/AX4jAEEQayIDJAACf0EAIAJFDQAaA0ACQAJAAkBBAAJ/IAFB/////wcgAiACQf////8HTxsQQyIEQX9HBEAgAyAENgIMIANBBDoACEHI6QAgBEUNARogAiAESQ0CIAEgBGohASACIARrIQIMBAsgA0EAOgALIANBADsACSADQQA6AAggA0HA8wAoAgAiBDYCDCAEQRtGDQMgA0EIagspAwAiBUL/AYNCBFENBBogAC0AAEEERwRAQfj4AEEANgIAQSUgABACQfj4ACgCAEH4+ABBADYCAEEBRg0CCyAAIAU3AgBBAQwECyAEIAJBkOsAEC8ACxAAIAAgBTcCABABAAsgAg0AC0EACyADQRBqJAALgwEBA38CQCAALQAAQQNGBEAgACgCBCICKAIAIQMgAigCBCIAKAIAIgEEQEH4+ABBADYCACABIAMQAkH4+AAoAgBB+PgAQQA2AgBBAUYNAgsgACgCBARAIAAoAggaIAMQFAsgAhAUCw8LEAAgACgCBARAIAAoAggaIAMQFAsgAhAUEAEAC04BAX8gAEEAIABBmQFNG0EBdEGwwQBqLwEAQbUyaiIAECUiAkGAAU8EQCABIABB/wAQKxogAUEAOgB/QcQADwsgASAAIAJBAWoQKxpBAAtEAQF/IwBBEGsiAiQAQQIgACABIAJBDGoQBiIABH9BwPMAIAA2AgBBfwVBAAshACACKAIMIQEgAkEQaiQAQX8gASAAGwu6AQEEfyMAIgJBgCAhAyACQRBBgCAgABtrIgQkACAEIQICQAJAIABFDQAgACECIAEiAw0AQcDzAEEc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BDoAACADLQAIIgBBBEYNASAAQQNHDQEgAygCDCICKAIAIQQCQCACKAIEIgEoAgAiAARAQfj4AEEANgIAIAAgBBACQfj4ACgCAEH4+ABBADYCAEEBRg0BCyABKAIEBEAgASgCCBogBBAUCyACEBQMAgsQACEAIAEoAgQEQCABKAIIGiAEEBQLIAIQFAwDCyAAIAMpAwg3AgALIANBMGokAA8LEAAhACADLQAIQQRGDQBB+PgAQQA2AgBBJSADQQhqEAJB+PgAKAIAQfj4AEEANgIAQQFHDQAQABoQIAALIAAQAQALlgUBBn8jAEEgayIBJAACQAJAAkAgA0UNACACQQRqIQQgA0EDdCEFIANBAWtB/////wFxQQFqIQYCQANAIAQoAgANASAEQQhqIQQgB0EBaiEHIAVBCGsiBQ0ACyAGIQcLIAMgB08EQCADIAdGDQEgAyAHayEGIAIgB0EDdGohCAJAAkADQAJAIAhBgAggBiAGQYAITxsQeSIEQX9HBEAgASAENgIEIAFBBDoAACAERQRAQcjpACEEDAgLIAhBBGohByAGQQN0IQMgBkEBa0H/////AXFBAWpBACEFA0AgBCAHKAIAIglJDQIgB0EIaiEHIAVBAWohBSAEIAlrIQQgA0EIayIDDQALIQUMAQsgAUEAOgADIAFBADsAASABQQA6AAAgAUHA8wAoAgAiAjYCBCACQRtGDQEgASEEDAYLIAUgBksNASAFIAZGBEAgBEUNBSABQQA2AhggAUEBNgIMIAFCBDcCECABQeDqADYCCCABQQhqQejqABAWAAsgCCAFQQN0aiIIKAIEIgIgBEkNAiAGIAVrIQYgCCACIARrNgIEIAggCCgCACAEajYCACABLQAAIgJBBEYNACACQQNHDQAgASgCBCIDKAIAIQQCQCADKAIEIgIoAgAiBQRAQfj4AEEANgIAIAUgBBACQfj4ACgCAEH4+ABBADYCAEEBRg0BCyACKAIEBEAgAigCCBogBBAUCyADEBQMAQsLEAAgAigCBARAIAIoAggaIAQQFAsgAxAUEAEACyAFIAZB0OoAEC8ACyABQQA2AhggAUEBNgIMIAFCBDcCECABQfjqADYCCCABQQhqQYDrABAWAAsgByADQdDqABAvAAsgAEEEOgAADAELIAAgBCkDADcCAAsgAUEgaiQAC6kCAQV/IAME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IABBEGokAEHU+ABB3PcANgIAQaz4AEGAgAQ2AgBBqPgAQeD5BDYCAEGM+ABBKjYCAEGw+ABB0OIAKAIANgIACwu/aBwAQYAIC6cHwDAAAEF0dGVtcHRlZCB0byBkaXZpZGUgYnkALSsgICAwWDB4ACVzOiVkOiAlcwAvZW1zZGsvZW1zY3JpcHRlbi9zeXN0ZW0vbGliL2xpYmN4eGFiaS9zcmMvcHJpdmF0ZV90eXBlaW5mby5jcHAAdGVybWluYXRpbmcAVGhlIFZBRCBoYXMgYmVlbiByZXBsYWNlZCBieSBhIGhhY2sgcGVuZGluZyBhIGNvbXBsZXRlIHJld3JpdGUASW4tcGxhY2UgRkZUIG5vdCBzdXBwb3J0ZWQAdGVybWluYXRlX2hhbmRsZXIgdW5leHBlY3RlZGx5IHJldHVybmVkAHJ1c3RfcGFuaWMAL1VzZXJzL2hvamlueXUvcHJvamVjdHMvZW50cnkvdHdpbi9HbGFzcy9hZWMvdGFyZ2V0L3dhc20zMi11bmtub3duLWVtc2NyaXB0ZW4vcmVsZWFzZS9idWlsZC9hZWMtcnMtc3lzLTBiYWFiOTYzMzlhZjdlMDgvb3V0L3NwZWV4ZHNwL2xpYnNwZWV4ZHNwL2tpc3NfZmZ0LmMAL1VzZXJzL2hvamlueXUvcHJvamVjdHMvZW50cnkvdHdpbi9HbGFzcy9hZWMvdGFyZ2V0L3dhc20zMi11bmtub3duLWVtc2NyaXB0ZW4vcmVsZWFzZS9idWlsZC9hZWMtcnMtc3lzLTBiYWFiOTYzMzlhZjdlMDgvb3V0L3NwZWV4ZHNwL2xpYnNwZWV4ZHNwL2tpc3NfZmZ0ci5jAGNhdGNoaW5nIGEgY2xhc3Mgd2l0aG91dCBhbiBvYmplY3Q/AEtpc3NGRlQ6IG1heCByYWRpeCBzdXBwb3J0ZWQgaXMgMTcAVGhlIGVjaG8gY2FuY2VsbGVyIHN0YXJ0ZWQgYWN0aW5nIGZ1bm55IGFuZCBnb3Qgc2xhcHBlZCAocmVzZXQpLiBJdCBzd2VhcnMgaXQgd2lsbCBiZWhhdmUgbm93LgAobnVsbCkAVW5rbm93biBzcGVleF9wcmVwcm9jZXNzX2N0bCByZXF1ZXN0OiAAd2FybmluZzogJXMKAEZhdGFsIChpbnRlcm5hbCkgZXJyb3Ig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IHNsaWNlIG9mIGxlbmd0aCByYW5nZSBlbmQgaW5kZXggc2xpY2UgaW5kZXggc3RhcnRzIGF0ICBidXQgZW5kcyBhdCAAAAADAACDBCAAkQVgAF0ToAASFyAfDCBgH+8sICsqMKArb6ZgLAKo4Cwe++AtAP4gNp7/YDb9AeE2AQohNyQN4TerDmE5LxjhOTAc4UrzHuFOQDShUh5h4VPwamFUT2/hVJ28YVUAz2FWZdGhVgDaIVcA4KFYruIhWuzk4VvQ6GFcIADuXPABf10CAAAAAgAAAAcAAABjYWxsZWQgYFJlc3VsdDo6dW53cmFwKClgIG9uIGFuIGBFcnJgIHZhbHVlTGF5b3V0RXJyb3JjYXBhY2l0eSBvdmVyZmxvd2xpYnJhcnkvYWxsb2Mvc3JjL3Jhd192ZWMvbW9kLnJzbGlicmFyeS9hbGxvYy9zcmMvc3RyaW5nLnJzbGlicmFyeS9hbGxvYy9zcmMvZmZpL2Nfc3RyLnJzbGlicmFyeS9hbGxvYy9zcmMvc2xpY2UucnPvv71saWJyYXJ5L2FsbG9jL3NyYy9zeW5jLnJzAAC8GAAA5BcAAFN0OXR5cGVfaW5mbwAAAADkGAAAABgAANwXAABOMTBfX2N4eGFiaXYxMTZfX3NoaW1fdHlwZV9pbmZvRQAAAADkGAAAMBgAAPQXAABOMTBfX2N4eGFiaXYxMTdfX2NsYXNzX3R5cGVfaW5mb0UAAADkGAAAYBgAAPQXAABOMTBfX2N4eGFiaXYxMTdfX3BiYXNlX3R5cGVfaW5mb0UAAADkGAAAkBgAAFQYAABOMTBfX2N4eGFiaXYxMTlfX3BvaW50ZXJfdHlwZV9pbmZvRQAAAAAAJBgAABYAAAAXAAAAGAAAABkAAAAaAAAAGwAAABwAAAAdAAAAAAAAAAQZAAAWAAAAHgAAABgAAAAZAAAAGgAAAB8AAAAgAAAAIQAAAOQYAAAQGQAAJBgAAE4xMF9fY3h4YWJpdjEyMF9fc2lfY2xhc3NfdHlwZV9pbmZvRQBObyBlcnJvciBpbmZvcm1hdGlvbgBJbGxlZ2FsIGJ5dGUgc2VxdWVuY2UARG9tYWluIGVycm9yAFJlc3VsdCBub3QgcmVwcmVzZW50YWJsZQBOb3QgYSB0dHkAUGVybWlzc2lvbiBkZW5pZWQAT3BlcmF0aW9uIG5vdCBwZXJtaXR0ZWQATm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeQBObyBzdWNoIHByb2Nlc3MARmlsZSBleGlzdHMAVmFsdWUgdG9vIGxhcmdlIGZvciBkYXRhIHR5cGUATm8gc3BhY2UgbGVmdCBvbiBkZXZpY2UAT3V0IG9mIG1lbW9yeQBSZXNvdXJjZSBidXN5AEludGVycnVwdGVkIHN5c3RlbSBjYWxsAFJlc291cmNlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlAEludmFsaWQgc2VlawBDcm9zcy1kZXZpY2UgbGluawBSZWFkLW9ubHkgZmlsZSBzeXN0ZW0ARGlyZWN0b3J5IG5vdCBlbXB0eQBDb25uZWN0aW9uIHJlc2V0IGJ5IHBlZXIAT3BlcmF0aW9uIHRpbWVkIG91dABDb25uZWN0aW9uIHJlZnVzZWQASG9zdCBpcyBkb3duAEhvc3QgaXMgdW5yZWFjaGFibGUAQWRkcmVzcyBpbiB1c2UAQnJva2VuIHBpcGUASS9PIGVycm9yAE5vIHN1Y2ggZGV2aWNlIG9yIGFkZHJlc3MAQmxvY2sgZGV2aWNlIHJlcXVpcmVkAE5vIHN1Y2ggZGV2aWNlAE5vdCBhIGRpcmVjdG9yeQBJcyBhIGRpcmVjdG9yeQBUZXh0IGZpbGUgYnVzeQBFeGVjIGZvcm1hdCBlcnJvcgBJbnZhbGlkIGFyZ3VtZW50AEFyZ3VtZW50IGxpc3QgdG9vIGxvbmcAU3ltYm9saWMgbGluayBsb29wAEZpbGVuYW1lIHRvbyBsb25nAFRvbyBtYW55IG9wZW4gZmlsZXMgaW4gc3lzdGVtAE5vIGZpbGUgZGVzY3JpcHRvcnMgYXZhaWxhYmxlAEJhZCBmaWxlIGRlc2NyaXB0b3IATm8gY2hpbGQgcHJvY2VzcwBCYWQgYWRkcmVzcwBGaWxlIHRvbyBsYXJnZQBUb28gbWFueSBsaW5rcwBObyBsb2NrcyBhdmFpbGFibGUAUmVzb3VyY2UgZGVhZGxvY2sgd291bGQgb2NjdXIAU3RhdGUgbm90IHJlY292ZXJhYmxlAFByZXZpb3VzIG93bmVyIGRpZWQAT3BlcmF0aW9uIGNhbmNlbGVkAEZ1bmN0aW9uIG5vdCBpbXBsZW1lbnRlZABObyBtZXNzYWdlIG9mIGRlc2lyZWQgdHlwZQBJZGVudGlmaWVyIHJlbW92ZWQARGV2aWNlIG5vdCBhIHN0cmVhbQBObyBkYXRhIGF2YWlsYWJsZQBEZXZpY2UgdGltZW91dABPdXQgb2Ygc3RyZWFtcyByZXNvdXJjZXMATGluayBoYXMgYmVlbiBzZXZlcmVkAFByb3RvY29sIGVycm9yAEJhZCBtZXNzYWdlAEZpbGUgZGVzY3JpcHRvciBpbiBiYWQgc3RhdGUATm90IGEgc29ja2V0AERlc3RpbmF0aW9uIGFkZHJlc3MgcmVxdWlyZWQATWVzc2FnZSB0b28gbGFyZ2UAUHJvdG9jb2wgd3JvbmcgdHlwZSBmb3Igc29ja2V0AFByb3RvY29sIG5vdCBhdmFpbGFibGUAUHJvdG9jb2wgbm90IHN1cHBvcnRlZABTb2NrZXQgdHlwZSBub3Qgc3VwcG9ydGVkAE5vdCBzdXBwb3J0ZWQAUHJvdG9jb2wgZmFtaWx5IG5vdCBzdXBwb3J0ZWQAQWRkcmVzcyBmYW1pbHkgbm90IHN1cHBvcnRlZCBieSBwcm90b2NvbABBZGRyZXNzIG5vdCBhdmFpbGFibGUATmV0d29yayBpcyBkb3duAE5ldHdvcmsgdW5yZWFjaGFibGUAQ29ubmVjdGlvbiByZXNldCBieSBuZXR3b3JrAENvbm5lY3Rpb24gYWJvcnRlZABObyBidWZmZXIgc3BhY2UgYXZhaWxhYmxlAFNvY2tldCBpcyBjb25uZWN0ZWQAU29ja2V0IG5vdCBjb25uZWN0ZWQAQ2Fubm90IHNlbmQgYWZ0ZXIgc29ja2V0IHNodXRkb3duAE9wZXJhdGlvbiBhbHJlYWR5IGluIHByb2dyZXNzAE9wZXJhdGlvbiBpbiBwcm9ncmVzcwBTdGFsZSBmaWxlIGhhbmRsZQBSZW1vdGUgSS9PIGVycm9yAFF1b3RhIGV4Y2VlZGVkAE5vIG1lZGl1bSBmb3VuZABXcm9uZyBtZWRpdW0gdHlwZQBNdWx0aWhvcCBhdHRlbXB0ZWQAUmVxdWlyZWQga2V5IG5vdCBhdmFpbGFibGUAS2V5IGhhcyBleHBpcmVkAEtleSBoYXMgYmVlbiByZXZva2VkAEtleSB3YXMgcmVqZWN0ZWQgYnkgc2VydmljZQAAAAClAlsA8AG1BYwFJQGDBh0DlAT/AMcDMQMLBrwBjwF/A8oEKwDaBq8AQgNOA9wBDgQVAKEGDQGUAgsCOAZkArwC/wJdA+cECwfPAssF7wXbBeECHgZFAoUAggJsA28E8QDzAxgF2QDaA0wGVAJ7AZ0DvQQAAFEAFQK7ALMDbQD/AYUELwX5BDgAZQFGAZ8AtwaoAXMCUwEAQfjCAAsMIQQAAAAAAAAAAC8CAEGYwwALBjUERwRWBABBrsMACwKgBABBwsMAC/QdRgVgBW4FYQYAAM8BAAAAAAAAAADJBukG+QYeBzkHSQdeB2xpYnJhcnkvc3RkL3NyYy9wYW5pY2tpbmcucnNyZWVudHJhbnQgaW5pdC9ydXN0Yy82YjAwYmMzODgwMTk4NjAwMTMwZTFjZjYyYjhmOGE5MzQ5NDQ4OGNjL2xpYnJhcnkvY29yZS9zcmMvY2VsbC9vbmNlLnJzY2FsbGVkIGBSZXN1bHQ6OnVud3JhcCgpYCBvbiBhbiBgRXJyYCB2YWx1ZS9ydXN0Yy82YjAwYmMzODgwMTk4NjAwMTMwZTFjZjYyYjhmOGE5MzQ5NDQ4OGNjL2xpYnJhcnkvYWxsb2Mvc3JjL3Jhd192ZWMvbW9kLnJzTnVsRXJyb3I6L3J1c3RjLzZiMDBiYzM4ODAxOTg2MDAxMzBlMWNmNjJiOGY4YTkzNDk0NDg4Y2MvbGlicmFyeS9hbGxvYy9zcmMvc2xpY2UucnN1c2Ugb2Ygc3RkOjp0aHJlYWQ6OmN1cnJlbnQoKSBpcyBub3QgcG9zc2libGUgYWZ0ZXIgdGhlIHRocmVhZCdzIGxvY2FsIGRhdGEgaGFzIGJlZW4gZGVzdHJveWVkbGlicmFyeS9zdGQvc3JjL3RocmVhZC9jdXJyZW50LnJzZmF0YWwgcnVudGltZSBlcnJvcjogCkF0dGVtcHRlZCB0byBhY2Nlc3MgdGhyZWFkLWxvY2FsIGRhdGEgd2hpbGUgYWxsb2NhdGluZyBzYWlkIGRhdGEuCkRvIG5vdCBhY2Nlc3MgZnVuY3Rpb25zIHRoYXQgYWxsb2NhdGUgaW4gdGhlIGdsb2JhbCBhbGxvY2F0b3IhClRoaXMgaXMgYSBidWcgaW4gdGhlIGdsb2JhbCBhbGxvY2F0b3IuCiwgYWJvcnRpbmcKbGlicmFyeS9zdGQvc3JjL3RocmVhZC9tb2QucnNmYWlsZWQgdG8gZ2VuZXJhdGUgdW5pcXVlIHRocmVhZCBJRDogYml0c3BhY2UgZXhoYXVzdGVkdGhyZWFkIG5hbWUgbWF5IG5vdCBjb250YWluIGludGVyaW9yIG51bGwgYnl0ZXNtYWluUlVTVF9CQUNLVFJBQ0VXb3VsZEJsb2NrAQAAAAAAAABmYWlsZWQgdG8gd3JpdGUgd2hvbGUgYnVmZmVyZW50aXR5IG5vdCBmb3VuZHBlcm1pc3Npb24gZGVuaWVkY29ubmVjdGlvbiByZWZ1c2VkY29ubmVjdGlvbiByZXNldGhvc3QgdW5yZWFjaGFibGVuZXR3b3JrIHVucmVhY2hhYmxlY29ubmVjdGlvbiBhYm9ydGVkbm90IGNvbm5lY3RlZGFkZHJlc3MgaW4gdXNlYWRkcmVzcyBub3QgYXZhaWxhYmxlbmV0d29yayBkb3duYnJva2VuIHBpcGVlbnRpdHkgYWxyZWFkeSBleGlzdHNvcGVyYXRpb24gd291bGQgYmxvY2tub3QgYSBkaXJlY3RvcnlpcyBhIGRpcmVjdG9yeWRpcmVjdG9yeSBub3QgZW1wdHlyZWFkLW9ubHkgZmlsZXN5c3RlbSBvciBzdG9yYWdlIG1lZGl1bWZpbGVzeXN0ZW0gbG9vcCBvciBpbmRpcmVjdGlvbiBsaW1pdCAoZS5nLiBzeW1saW5rIGxvb3Apc3RhbGUgbmV0d29yayBmaWxlIGhhbmRsZWludmFsaWQgaW5wdXQgcGFyYW1ldGVyaW52YWxpZCBkYXRhdGltZWQgb3V0d3JpdGUgemVyb25vIHN0b3JhZ2Ugc3BhY2VzZWVrIG9uIHVuc2Vla2FibGUgZmlsZXF1b3RhIGV4Y2VlZGVkZmlsZSB0b28gbGFyZ2VyZXNvdXJjZSBidXN5ZXhlY3V0YWJsZSBmaWxlIGJ1c3lkZWFkbG9ja2Nyb3NzLWRldmljZSBsaW5rIG9yIHJlbmFtZXRvbyBtYW55IGxpbmtzaW52YWxpZCBmaWxlbmFtZWFyZ3VtZW50IGxpc3QgdG9vIGxvbmdvcGVyYXRpb24gaW50ZXJydXB0ZWR1bnN1cHBvcnRlZHVuZXhwZWN0ZWQgZW5kIG9mIGZpbGVvdXQgb2YgbWVtb3J5aW4gcHJvZ3Jlc3NvdGhlciBlcnJvcnVuY2F0ZWdvcml6ZWQgZXJyb3JPc2NvZGVraW5kbWVzc2FnZUtpbmRFcnJvckN1c3RvbWVycm9yIChvcyBlcnJvciApbGlicmFyeS9zdGQvc3JjL2lvL21vZC5yc2EgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB3aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBkaWQgbm90YWR2YW5jaW5nIGlvIHNsaWNlcyBiZXlvbmQgdGhlaXIgbGVuZ3RoYWR2YW5jaW5nIElvU2xpY2UgYmV5b25kIGl0cyBsZW5ndGhsaWJyYXJ5L3N0ZC9zcmMvc3lzL2lvL2lvX3NsaWNlL2lvdmVjLnJzcGFuaWNrZWQgYXQgOgpmaWxlIG5hbWUgY29udGFpbmVkIGFuIHVuZXhwZWN0ZWQgTlVMIGJ5dGVzdGFjayBiYWNrdHJhY2U6Cm5vdGU6IFNvbWUgZGV0YWlscyBhcmUgb21pdHRlZCwgcnVuIHdpdGggYFJVU1RfQkFDS1RSQUNFPWZ1bGxgIGZvciBhIHZlcmJvc2UgYmFja3RyYWNlLgptZW1vcnkgYWxsb2NhdGlvbiBvZiAgYnl0ZXMgZmFpbGVkCiBieXRlcyBmYWlsZWRsaWJyYXJ5L3N0ZC9zcmMvYWxsb2MucnNmYXRhbCBydW50aW1lIGVycm9yOiBSdXN0IHBhbmljcyBtdXN0IGJlIHJldGhyb3duLCBhYm9ydGluZwpub3RlOiBydW4gd2l0aCBgUlVTVF9CQUNLVFJBQ0U9MWAgZW52aXJvbm1lbnQgdmFyaWFibGUgdG8gZGlzcGxheSBhIGJhY2t0cmFjZQo8dW5uYW1lZD4KdGhyZWFkICcnIHBhbmlja2VkIGF0IApCb3g8ZHluIEFueT5hYm9ydGluZyBkdWUgdG8gcGFuaWMgYXQgCnRocmVhZCBwYW5pY2tlZCB3aGlsZSBwcm9jZXNzaW5nIHBhbmljLiBhYm9ydGluZy4KdGhyZWFkIGNhdXNlZCBub24tdW53aW5kaW5nIHBhbmljLiBhYm9ydGluZy4KZmF0YWwgcnVudGltZSBlcnJvcjogZmFpbGVkIHRvIGluaXRpYXRlIHBhbmljLCBlcnJvciAsIGFib3J0aW5nCk5vdEZvdW5kUGVybWlzc2lvbkRlbmllZENvbm5lY3Rpb25SZWZ1c2VkQ29ubmVjdGlvblJlc2V0SG9zdFVucmVhY2hhYmxlTmV0d29ya1VucmVhY2hhYmxlQ29ubmVjdGlvbkFib3J0ZWROb3RDb25uZWN0ZWRBZGRySW5Vc2VBZGRyTm90QXZhaWxhYmxlTmV0d29ya0Rvd25Ccm9rZW5QaXBlQWxyZWFkeUV4aXN0c05vdEFEaXJlY3RvcnlJc0FEaXJlY3RvcnlEaXJlY3RvcnlOb3RFbXB0eVJlYWRPbmx5RmlsZXN5c3RlbUZpbGVzeXN0ZW1Mb29wU3RhbGVOZXR3b3JrRmlsZUhhbmRsZUludmFsaWRJbnB1dEludmFsaWREYXRhVGltZWRPdXRXcml0ZVplcm9TdG9yYWdlRnVsbE5vdFNlZWthYmxlUXVvdGFFeGNlZWRlZEZpbGVUb29MYXJnZVJlc291cmNlQnVzeUV4ZWN1dGFibGVGaWxlQnVzeURlYWRsb2NrQ3Jvc3Nlc0RldmljZXNUb29NYW55TGlua3NJbnZhbGlkRmlsZW5hbWVBcmd1bWVudExpc3RUb29Mb25nSW50ZXJydXB0ZWRVbnN1cHBvcnRlZFVuZXhwZWN0ZWRFb2ZPdXRPZk1lbW9yeUluUHJvZ3Jlc3NPdGhlclVuY2F0ZWdvcml6ZWRzdHJlcnJvcl9yIGZhaWx1cmVsaWJyYXJ5L3N0ZC9zcmMvc3lzL3BhbC91bml4L29zLnJzbGlicmFyeS9zdGQvc3JjL3N5cy9wYWwvdW5peC9zeW5jL2NvbmR2YXIucnMAAAAAbGlicmFyeS9zdGQvc3JjL3N5cy9wYWwvdW5peC9zeW5jL211dGV4LnJzZmFpbGVkIHRvIGxvY2sgbXV0ZXg6IAIAAABsaWJyYXJ5L3N0ZC9zcmMvc3lzL3N5bmMvcndsb2NrL3F1ZXVlLnJzZmF0YWwgcnVudGltZSBlcnJvcjogdHJpZWQgdG8gZHJvcCBub2RlIGluIGludHJ1c2l2ZSBsaXN0LiwgYWJvcnRpbmcKcGFyayBzdGF0ZSBjaGFuZ2VkIHVuZXhwZWN0ZWRseWxpYnJhcnkvc3RkL3NyYy9zeXMvc3luYy90aHJlYWRfcGFya2luZy9wdGhyZWFkLnJzaW5jb25zaXN0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")}function getBinarySync(file){if(ArrayBuffer.isView(file)){return file}if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["u"];updateMemoryViews();wasmTable=wasmExports["H"];assignWasmExports(wasmExports);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod,inst))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var base64Decode=b64=>{var b1,b2,i=0,j=0,bLength=b64.length;var output=new Uint8Array((bLength*3>>2)-(b64[bLength-2]=="=")-(b64[bLength-1]=="="));for(;i>4;output[j+1]=b1<<4|b2>>2;output[j+2]=b2<<6|base64ReverseLookup[b64.charCodeAt(i+3)]}return output};var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var exceptionLast=0;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var setTempRet0=val=>__emscripten_tempret_set(val);var findMatchingCatch=args=>{var thrown=exceptionLast;if(!thrown){setTempRet0(0);return 0}var info=new ExceptionInfo(thrown);info.set_adjusted_ptr(thrown);var thrownType=info.get_type();if(!thrownType){setTempRet0(0);return thrown}for(var caughtType of args){if(caughtType===0||caughtType===thrownType){break}var adjusted_ptr_addr=info.ptr+16;if(___cxa_can_catch(caughtType,thrownType,adjusted_ptr_addr)){setTempRet0(caughtType);return thrown}}setTempRet0(thrownType);return thrown};var ___cxa_find_matching_catch_2=()=>findMatchingCatch([]);var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var ___resumeException=ptr=>{if(!exceptionLast){exceptionLast=ptr}throw exceptionLast};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);function ___syscall_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd)+1;if(sizeabort("");var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.language||"C").replace("-","_")+".UTF-8";var env={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:lang,_:getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;var envp=0;for(var string of getEnvStrings()){var ptr=environ_buf+bufSize;HEAPU32[__environ+envp>>2]=ptr;bufSize+=stringToUTF8(string,ptr,Infinity)+1;envp+=4}return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;for(var string of strings){bufSize+=lengthBytesUTF8(string)+1}HEAPU32[penviron_buf_size>>2]=bufSize;return 0};var runtimeKeepaliveCounter=0;var keepRuntimeAlive=()=>noExitRuntime||runtimeKeepaliveCounter>0;var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){Module["onExit"]?.(code);ABORT=true}quit_(code,new ExitStatus(code))};var exitJS=(status,implicit)=>{EXITSTATUS=status;_proc_exit(status)};var _exit=exitJS;var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.slice(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.slice(0,-1)}return root+dir},basename:path=>path&&path.match(/([^\/]+|\/)\/*$/)[1],join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>view=>crypto.getRandomValues(view);var randomFill=view=>{(randomFill=initRandomFill())(view)};var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).slice(1);to=PATH_FS.resolve(to).slice(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var FS_stdin_getChar_buffer=[];var intArrayFromString=(stringy,dontAddNull,length)=>{var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array};var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output?.length>0){err(UTF8ArrayToString(tty.output));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16895,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.atime=node.mtime=node.ctime=Date.now();if(parent){parent.contents[name]=node;parent.atime=parent.mtime=parent.ctime=node.atime}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.atime);attr.mtime=new Date(node.mtime);attr.ctime=new Date(node.ctime);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){for(const key of["mode","atime","mtime","ctime"]){if(attr[key]!=null){node[key]=attr[key]}}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw MEMFS.doesNotExistError},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){if(FS.isDir(old_node.mode)){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}FS.hashRemoveNode(new_node)}delete old_node.parent.contents[old_node.name];new_dir.contents[new_name]=old_node;old_node.name=new_name;new_dir.ctime=new_dir.mtime=old_node.parent.ctime=old_node.parent.mtime=Date.now()},unlink(parent,name){delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},readdir(node){return[".","..",...Object.keys(node.contents)]},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var arrayBuffer=await readAsync(url);return new Uint8Array(arrayBuffer)};var FS_createDataFile=(...args)=>FS.createDataFile(...args);var getUniqueRunDependency=id=>id;var preloadPlugins=[];var FS_handledByPreloadPlugin=(byteArray,fullname,finish,onerror)=>{if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach(plugin=>{if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}});return handled};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}onload?.();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,()=>{onerror?.();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url).then(processData,onerror)}else{processData(url)}};var FS_modeStringToFlags=str=>{var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,filesystems:null,syncFSRequests:0,readFiles:{},ErrnoError:class{name="ErrnoError";constructor(errno){this.errno=errno}},FSStream:class{shared={};get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{node_ops={};stream_ops={};readMode=292|73;writeMode=146;mounted=null;constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.rdev=rdev;this.atime=this.mtime=this.ctime=Date.now()}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){if(!path){throw new FS.ErrnoError(44)}opts.follow_mount??=true;if(!PATH.isAbs(path)){path=FS.cwd()+"/"+path}linkloop:for(var nlinks=0;nlinks<40;nlinks++){var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){if(!FS.isDir(dir.mode)){return 54}try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&(512|64)){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},checkOpExists(op,err){if(!op){throw new FS.ErrnoError(err)}return op},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},doSetAttr(stream,node,attr){var setattr=stream?.stream_ops.setattr;var arg=setattr?stream:node;setattr??=node.node_ops.setattr;FS.checkOpExists(setattr,63);setattr(arg,attr)},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type,opts,mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name){throw new FS.ErrnoError(28)}if(name==="."||name===".."){throw new FS.ErrnoError(20)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},statfs(path){return FS.statfsNode(FS.lookupPath(path,{follow:true}).node)},statfsStream(stream){return FS.statfsNode(stream.node)},statfsNode(node){var rtn={bsize:4096,frsize:4096,blocks:1e6,bfree:5e5,bavail:5e5,files:FS.nextInode,ffree:FS.nextInode-1,fsid:42,flags:2,namelen:255};if(node.node_ops.statfs){Object.assign(rtn,node.node_ops.statfs(node.mount.opts.root))}return rtn},create(path,mode=438){mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode=511){mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var dir of dirs){if(!dir)continue;if(d||PATH.isAbs(path))d+="/";d+=dir;try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev(path,mode,dev){if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name);old_node.parent=new_dir}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var readdir=FS.checkOpExists(node.node_ops.readdir,54);return readdir(node)},unlink(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return link.node_ops.readlink(link)},stat(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;var getattr=FS.checkOpExists(node.node_ops.getattr,63);return getattr(node)},fstat(fd){var stream=FS.getStreamChecked(fd);var node=stream.node;var getattr=stream.stream_ops.getattr;var arg=getattr?stream:node;getattr??=node.node_ops.getattr;FS.checkOpExists(getattr,63);return getattr(arg)},lstat(path){return FS.stat(path,true)},doChmod(stream,node,mode,dontFollow){FS.doSetAttr(stream,node,{mode:mode&4095|node.mode&~4095,ctime:Date.now(),dontFollow})},chmod(path,mode,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChmod(null,node,mode,dontFollow)},lchmod(path,mode){FS.chmod(path,mode,true)},fchmod(fd,mode){var stream=FS.getStreamChecked(fd);FS.doChmod(stream,stream.node,mode,false)},doChown(stream,node,dontFollow){FS.doSetAttr(stream,node,{timestamp:Date.now(),dontFollow})},chown(path,uid,gid,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChown(null,node,dontFollow)},lchown(path,uid,gid){FS.chown(path,uid,gid,true)},fchown(fd,uid,gid){var stream=FS.getStreamChecked(fd);FS.doChown(stream,stream.node,false)},doTruncate(stream,node,len){if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}FS.doSetAttr(stream,node,{size:len,timestamp:Date.now()})},truncate(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}FS.doTruncate(null,node,len)},ftruncate(fd,len){var stream=FS.getStreamChecked(fd);if(len<0||(stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.doTruncate(stream,stream.node,len)},utime(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var setattr=FS.checkOpExists(node.node_ops.setattr,63);setattr(node,{atime,mtime})},open(path,flags,mode=438){if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;var isDirPath;if(typeof path=="object"){node=path}else{isDirPath=path.endsWith("/");var lookup=FS.lookupPath(path,{follow:!(flags&131072),noent_okay:true});node=lookup.node;path=lookup.path}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else if(isDirPath){throw new FS.ErrnoError(31)}else{node=FS.mknod(path,mode|511,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node,path:FS.getPath(node),flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(created){FS.chmod(node,mode&511)}if(Module["logReadFiles"]&&!(flags&1)){if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed(stream){return stream.fd===null},llseek(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},mmap(stream,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}if(!length){throw new FS.ErrnoError(28)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync(stream,buffer,offset,length,mmapFlags){if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){buf=UTF8ArrayToString(buf)}FS.close(stream);return buf},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){data=new Uint8Array(intArrayFromString(data,true))}if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length,llseek:()=>0});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomFill(randomBuffer);randomLeft=randomBuffer.byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16895,73);node.stream_ops={llseek:MEMFS.stream_ops.llseek};node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path},id:fd+1};ret.parent=ret;return ret},readdir(){return Array.from(FS.streams.entries()).filter(([k,v])=>v).map(([k,v])=>k.toString())}};return node}},{},"/proc/self/fd")},createStandardStreams(input,output,error){if(input){FS.createDevice("/dev","stdin",input)}else{FS.symlink("/dev/tty","/dev/stdin")}if(output){FS.createDevice("/dev","stdout",null,output)}else{FS.symlink("/dev/tty","/dev/stdout")}if(error){FS.createDevice("/dev","stderr",null,error)}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS}},init(input,output,error){FS.initialized=true;input??=Module["stdin"];output??=Module["stdout"];error??=Module["stderr"];FS.createStandardStreams(input,output,error)},quit(){FS.initialized=false;for(var stream of FS.streams){if(stream){FS.close(stream)}}},findObject(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath(parent,path,canRead,canWrite){parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){if(e.errno!=20)throw e}parent=current}return current},createFile(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile(parent,name,data,canRead,canWrite,canOwn){var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return dir+"/"+path},writeStat(buf,stat){HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAP32[buf+12>>2]=stat.uid;HEAP32[buf+16>>2]=stat.gid;HEAP32[buf+20>>2]=stat.rdev;HEAP64[buf+24>>3]=BigInt(stat.size);HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();HEAP64[buf+40>>3]=BigInt(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3*1e3;HEAP64[buf+56>>3]=BigInt(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3*1e3;HEAP64[buf+72>>3]=BigInt(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3*1e3;HEAP64[buf+88>>3]=BigInt(stat.ino);return 0},writeStatFs(buf,stats){HEAP32[buf+4>>2]=stats.bsize;HEAP32[buf+40>>2]=stats.bsize;HEAP32[buf+8>>2]=stats.blocks;HEAP32[buf+12>>2]=stats.bfree;HEAP32[buf+16>>2]=stats.bavail;HEAP32[buf+20>>2]=stats.files;HEAP32[buf+24>>2]=stats.ffree;HEAP32[buf+28>>2]=stats.fsid;HEAP32[buf+44>>2]=stats.flags;HEAP32[buf+36>>2]=stats.namelen},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>numINT53_MAX?NaN:Number(num);function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);HEAP64[newOffset>>3]=BigInt(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var wasmTableMirror=[];var wasmTable;var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};for(var base64ReverseLookup=new Uint8Array(123),i=25;i>=0;--i){base64ReverseLookup[48+i]=52+i;base64ReverseLookup[65+i]=i;base64ReverseLookup[97+i]=26+i}base64ReverseLookup[43]=62;base64ReverseLookup[47]=63;FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();MEMFS.doesNotExistError=new FS.ErrnoError(44);MEMFS.doesNotExistError.stack="";{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["preloadPlugins"])preloadPlugins=Module["preloadPlugins"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}Module["ccall"]=ccall;Module["cwrap"]=cwrap;var _AecNew,_AecCancelEcho,_AecDestroy,_malloc,_free,_setThrew,__emscripten_tempret_set,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,___cxa_can_catch;function assignWasmExports(wasmExports){Module["_AecNew"]=_AecNew=wasmExports["w"];Module["_AecCancelEcho"]=_AecCancelEcho=wasmExports["x"];Module["_AecDestroy"]=_AecDestroy=wasmExports["y"];Module["_malloc"]=_malloc=wasmExports["z"];Module["_free"]=_free=wasmExports["A"];_setThrew=wasmExports["B"];__emscripten_tempret_set=wasmExports["C"];__emscripten_stack_restore=wasmExports["D"];__emscripten_stack_alloc=wasmExports["E"];_emscripten_stack_get_current=wasmExports["F"];___cxa_can_catch=wasmExports["G"]}var wasmImports={a:___cxa_find_matching_catch_2,q:___cxa_throw,b:___resumeException,p:___syscall_getcwd,r:__abort_js,t:_emscripten_resize_heap,n:_environ_get,o:_environ_sizes_get,k:_exit,s:_fd_close,l:_fd_seek,g:_fd_write,i:invoke_ii,f:invoke_iiii,m:invoke_iiiiii,c:invoke_vi,d:invoke_vii,e:invoke_viii,j:invoke_viiii,h:invoke_viiiii};var wasmExports=await createWasm();function invoke_vi(index,a1){var sp=stackSave();try{getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viii(index,a1,a2,a3){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_vii(index,a1,a2){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viiii(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iiii(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_ii(index,a1){var sp=stackSave();try{return getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iiiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})} return moduleRtn; diff --git a/src/assets/aec.wasm b/src/assets/aec.wasm deleted file mode 100755 index 9d5924ada9ef44f43f2dff9c1fbaedc03fabe345..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113342 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 DCKAgt diff --git a/src/common/ai/providers/gemini.js b/src/common/ai/providers/gemini.js index c3c4743..be561d7 100644 --- a/src/common/ai/providers/gemini.js +++ b/src/common/ai/providers/gemini.js @@ -17,7 +17,14 @@ async function createSTT({ apiKey, language = 'en-US', callbacks = {}, ...config const session = await liveClient.live.connect({ model: 'gemini-live-2.5-flash-preview', - callbacks, + callbacks: { + ...callbacks, + onMessage: (msg) => { + if (!msg || typeof msg !== 'object') return; + msg.provider = 'gemini'; + callbacks.onmessage?.(msg); + } + }, config: { inputAudioTranscription: {}, speechConfig: { languageCode: lang }, diff --git a/src/common/ai/providers/openai.js b/src/common/ai/providers/openai.js index a27c547..7ede760 100644 --- a/src/common/ai/providers/openai.js +++ b/src/common/ai/providers/openai.js @@ -72,6 +72,7 @@ async function createSTT({ apiKey, language = 'en', callbacks = {}, usePortkey = close: () => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: 'session.close' })); + ws.onmessage = ws.onerror = () => {}; // 핸들러 제거 ws.close(1000, 'Client initiated close.'); } } @@ -79,10 +80,17 @@ async function createSTT({ apiKey, language = 'en', callbacks = {}, usePortkey = }; ws.onmessage = (event) => { - const message = JSON.parse(event.data); - if (callbacks && callbacks.onmessage) { - callbacks.onmessage(message); - } + // ── 종료·하트비트 패킷 필터링 ────────────────────────────── + if (!event.data || event.data === 'null' || event.data === '[DONE]') return; + + let msg; + try { msg = JSON.parse(event.data); } + catch { return; } // JSON 파싱 실패 무시 + + if (!msg || typeof msg !== 'object') return; + + msg.provider = 'openai'; // ← 항상 명시 + callbacks.onmessage?.(msg); }; ws.onerror = (error) => { diff --git a/src/features/listen/listenService.js b/src/features/listen/listenService.js index 3b89aa2..10aa459 100644 --- a/src/features/listen/listenService.js +++ b/src/features/listen/listenService.js @@ -1,4 +1,4 @@ -const { BrowserWindow } = require('electron'); +const { BrowserWindow, app } = require('electron'); const SttService = require('./stt/sttService'); const SummaryService = require('./summary/summaryService'); const authService = require('../../common/services/authService'); @@ -213,9 +213,9 @@ class ListenService { try { await this.sendAudioContent(data, mimeType); return { success: true }; - } catch (error) { - console.error('Error sending user audio:', error); - return { success: false, error: error.message }; + } catch (e) { + console.error('Error sending user audio:', e); + return { success: false, error: e.message }; } }); @@ -237,9 +237,13 @@ class ListenService { if (process.platform !== 'darwin') { return { success: false, error: 'macOS audio capture only available on macOS' }; } + if (this.sttService.isMacOSAudioRunning?.()) { + return { success: false, error: 'already_running' }; + } + try { const success = await this.startMacOSAudioCapture(); - return { success }; + return { success, error: null }; } catch (error) { console.error('Error starting macOS audio capture:', error); return { success: false, error: error.message }; @@ -274,4 +278,4 @@ class ListenService { } } -module.exports = ListenService; \ No newline at end of file +module.exports = ListenService; \ No newline at end of file diff --git a/src/features/listen/renderer/listenCapture.js b/src/features/listen/renderer/listenCapture.js index f8e1722..1607d0b 100644 --- a/src/features/listen/renderer/listenCapture.js +++ b/src/features/listen/renderer/listenCapture.js @@ -1,33 +1,30 @@ const { ipcRenderer } = require('electron'); +const createAecModule = require('../../../assets/aec.js'); -const createAecModule = require('../../../assets/aec.js'); // aec.js 위치 +let aecModPromise = null; // 한 번만 로드 +let aecMod = null; +let aecPtr = 0; // Rust Aec* 1개만 재사용 -let aecWasm; // 전역 캐시 +/** WASM 모듈 가져오고 1회 초기화 */ +async function getAec () { + if (aecModPromise) return aecModPromise; // 캐시 -export async function initAec () { - if (aecWasm) return aecWasm; // 이미 초기화됐으면 그대로 + aecModPromise = createAecModule().then((M) => { + aecMod = M; + // C 심볼 → JS 래퍼 바인딩 (딱 1번) + M.newPtr = M.cwrap('AecNew', 'number', + ['number','number','number','number']); + M.cancel = M.cwrap('AecCancelEcho', null, + ['number','number','number','number','number']); + M.destroy = M.cwrap('AecDestroy', null, ['number']); + return M; + }); - // ⬇️ locateFile: aec.js 가 wasm 로드를 시도할 때 호출 - aecWasm = await createAecModule({ - locateFile (filename) { - // aec.js 는 ‘aec.wasm’ 한 개만 요청하므로, 주소를 직접 반환 - return '../../../assets/' + filename; // ← **브라우저 기준 URL** - // (Electron renderer 에서 file://…/dist/renderer/… 에서 접근) - } - }); - - // C → JS 래퍼 - aecWasm.newPtr = aecWasm.cwrap('AecNew', 'number', - ['number','number','number','number']); - aecWasm.cancel = aecWasm.cwrap('AecCancelEcho', null, - ['number','number','number','number','number']); - aecWasm.destroy = aecWasm.cwrap('AecDestroy', null, ['number']); - - return aecWasm; + return aecModPromise; } // 바로 로드-실패 로그를 보기 위해 -initAec().catch(console.error); +getAec().catch(console.error); // --------------------------- // Constants & Globals // --------------------------- @@ -108,11 +105,14 @@ function arrayBufferToBase64(buffer) { return btoa(binary); } +/* ───────────────────────── JS ↔︎ WASM 헬퍼 ───────────────────────── */ function int16PtrFromFloat32(mod, f32) { const len = f32.length; const bytes = len * 2; const ptr = mod._malloc(bytes); - const i16 = new Int16Array(mod.HEAP16.buffer, ptr, len); + // HEAP16이 없으면 HEAPU8.buffer로 직접 래핑 + const heapBuf = (mod.HEAP16 ? mod.HEAP16.buffer : mod.HEAPU8.buffer); + const i16 = new Int16Array(heapBuf, ptr, len); for (let i = 0; i < len; ++i) { const s = Math.max(-1, Math.min(1, f32[i])); i16[i] = s < 0 ? s * 0x8000 : s * 0x7fff; @@ -126,128 +126,28 @@ function float32FromInt16View(i16) { return out; } -// --------------------------- -// Complete SimpleAEC implementation (exact from renderer.js) -// --------------------------- -class SimpleAEC { - constructor() { - this.adaptiveFilter = new Float32Array(1024); - this.mu = 0.2; - this.echoDelay = 100; - this.sampleRate = 24000; - this.delaySamples = Math.floor((this.echoDelay / 1000) * this.sampleRate); - - this.echoGain = 0.5; - this.noiseFloor = 0.01; - - // 🔧 Adaptive-gain parameters (User-tuned, very aggressive) - this.targetErr = 0.002; - this.adaptRate = 0.1; - - console.log('🎯 AEC initialized (hyper-aggressive)'); - } - - process(micData, systemData) { - if (!systemData || systemData.length === 0) { - return micData; - } - - for (let i = 0; i < systemData.length; i++) { - if (systemData[i] > 0.98) systemData[i] = 0.98; - else if (systemData[i] < -0.98) systemData[i] = -0.98; - - systemData[i] = Math.tanh(systemData[i] * 4); - } - - let sum2 = 0; - for (let i = 0; i < systemData.length; i++) sum2 += systemData[i] * systemData[i]; - const rms = Math.sqrt(sum2 / systemData.length); - const targetRms = 0.08; // 🔧 기준 RMS (기존 0.1) - const scale = targetRms / (rms + 1e-6); // 1e-6: 0-division 방지 - - const output = new Float32Array(micData.length); - - const optimalDelay = this.findOptimalDelay(micData, systemData); - - for (let i = 0; i < micData.length; i++) { - let echoEstimate = 0; - - for (let d = -500; d <= 500; d += 100) { - const delayIndex = i - optimalDelay - d; - if (delayIndex >= 0 && delayIndex < systemData.length) { - const weight = Math.exp(-Math.abs(d) / 1000); - echoEstimate += systemData[delayIndex] * scale * this.echoGain * weight; - } - } - - output[i] = micData[i] - echoEstimate * 0.9; - - if (Math.abs(output[i]) < this.noiseFloor) { - output[i] *= 0.5; - } - - if (this.isSimilarToSystem(output[i], systemData, i, optimalDelay)) { - output[i] *= 0.25; - } - - output[i] = Math.max(-1, Math.min(1, output[i])); - } - - - let errSum = 0; - for (let i = 0; i < output.length; i++) errSum += output[i] * output[i]; - const errRms = Math.sqrt(errSum / output.length); - - const err = errRms - this.targetErr; - this.echoGain += this.adaptRate * err; // 비례 제어 - this.echoGain = Math.max(0, Math.min(1, this.echoGain)); - - return output; - } - - findOptimalDelay(micData, systemData) { - let maxCorr = 0; - let optimalDelay = this.delaySamples; - - for (let delay = 0; delay < 5000 && delay < systemData.length; delay += 200) { - let corr = 0; - let count = 0; - - for (let i = 0; i < Math.min(500, micData.length); i++) { - if (i + delay < systemData.length) { - corr += micData[i] * systemData[i + delay]; - count++; - } - } - - if (count > 0) { - corr = Math.abs(corr / count); - if (corr > maxCorr) { - maxCorr = corr; - optimalDelay = delay; - } - } - } - - return optimalDelay; - } - - isSimilarToSystem(sample, systemData, index, delay) { - const windowSize = 50; - let similarity = 0; - - for (let i = -windowSize; i <= windowSize; i++) { - const sysIndex = index - delay + i; - if (sysIndex >= 0 && sysIndex < systemData.length) { - similarity += Math.abs(sample - systemData[sysIndex]); - } - } - - return similarity / (2 * windowSize + 1) < 0.15; - } +/* 필요하다면 종료 시 */ +function disposeAec () { + getAec().then(mod => { if (aecPtr) mod.destroy(aecPtr); }); +} + +function runAecSync (micF32, sysF32) { + if (!aecMod || !aecPtr || !aecMod.HEAPU8) return micF32; // 아직 모듈 안 뜸 → 패스 + + const len = micF32.length; + const mic = int16PtrFromFloat32(aecMod, micF32); + const echo = int16PtrFromFloat32(aecMod, sysF32); + const out = aecMod._malloc(len * 2); + + aecMod.cancel(aecPtr, mic.ptr, echo.ptr, out, len); + + const heapBuf = (aecMod.HEAP16 ? aecMod.HEAP16.buffer : aecMod.HEAPU8.buffer); + const outF32 = float32FromInt16View(new Int16Array(heapBuf, out, len)); + + aecMod._free(mic.ptr); aecMod._free(echo.ptr); aecMod._free(out); + return outF32; } -let aecProcessor = new SimpleAEC(); // System audio data handler ipcRenderer.on('system-audio-data', (event, { data }) => { @@ -260,8 +160,6 @@ ipcRenderer.on('system-audio-data', (event, { data }) => { if (systemAudioBuffer.length > MAX_SYSTEM_BUFFER_SIZE) { systemAudioBuffer = systemAudioBuffer.slice(-MAX_SYSTEM_BUFFER_SIZE); } - - console.log('📥 Received system audio for AEC reference'); }); // --------------------------- @@ -351,39 +249,47 @@ setInterval(() => { // --------------------------- // Audio processing functions (exact from renderer.js) // --------------------------- -function setupMicProcessing(micStream) { +async function setupMicProcessing(micStream) { + /* ── WASM 먼저 로드 ───────────────────────── */ + const mod = await getAec(); + if (!aecPtr) aecPtr = mod.newPtr(160, 1600, 24000, 1); + + const micAudioContext = new AudioContext({ sampleRate: SAMPLE_RATE }); + await micAudioContext.resume(); const micSource = micAudioContext.createMediaStreamSource(micStream); const micProcessor = micAudioContext.createScriptProcessor(BUFFER_SIZE, 1, 1); let audioBuffer = []; const samplesPerChunk = SAMPLE_RATE * AUDIO_CHUNK_DURATION; - micProcessor.onaudioprocess = async e => { + micProcessor.onaudioprocess = (e) => { const inputData = e.inputBuffer.getChannelData(0); audioBuffer.push(...inputData); + console.log('🎤 micProcessor.onaudioprocess'); + // samplesPerChunk(=2400) 만큼 모이면 전송 while (audioBuffer.length >= samplesPerChunk) { let chunk = audioBuffer.splice(0, samplesPerChunk); - let processedChunk = new Float32Array(chunk); + let processedChunk = new Float32Array(chunk); // 기본값 - // Check for system audio and apply AEC only if voice is active - if (aecProcessor && systemAudioBuffer.length > 0) { - const latestSystemAudio = systemAudioBuffer[systemAudioBuffer.length - 1]; - const systemFloat32 = base64ToFloat32Array(latestSystemAudio.data); + // ───────────────── WASM AEC ───────────────── + if (systemAudioBuffer.length > 0) { + const latest = systemAudioBuffer[systemAudioBuffer.length - 1]; + const sysF32 = base64ToFloat32Array(latest.data); - // Apply AEC only when system audio has active speech - if (isVoiceActive(systemFloat32)) { - processedChunk = aecProcessor.process(new Float32Array(chunk), systemFloat32); - console.log('🔊 Applied AEC because system audio is active'); - } + // **음성 구간일 때만 런** + processedChunk = runAecSync(new Float32Array(chunk), sysF32); + console.log('🔊 Applied WASM-AEC (speex)'); + } else { + console.log('🔊 No system audio for AEC reference'); } - const pcmData16 = convertFloat32ToInt16(processedChunk); - const base64Data = arrayBufferToBase64(pcmData16.buffer); + const pcm16 = convertFloat32ToInt16(processedChunk); + const b64 = arrayBufferToBase64(pcm16.buffer); - await ipcRenderer.invoke('send-audio-content', { - data: base64Data, + ipcRenderer.invoke('send-audio-content', { + data: b64, mimeType: 'audio/pcm;rate=24000', }); } @@ -566,7 +472,19 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu // Start macOS audio capture const audioResult = await ipcRenderer.invoke('start-macos-audio'); if (!audioResult.success) { - throw new Error('Failed to start macOS audio capture: ' + audioResult.error); + console.warn('[listenCapture] macOS audio start failed:', audioResult.error); + + // 이미 실행 중 → stop 후 재시도 + if (audioResult.error === 'already_running') { + await ipcRenderer.invoke('stop-macos-audio'); + await new Promise(r => setTimeout(r, 500)); + const retry = await ipcRenderer.invoke('start-macos-audio'); + if (!retry.success) { + throw new Error('Retry failed: ' + retry.error); + } + } else { + throw new Error('Failed to start macOS audio capture: ' + audioResult.error); + } } // Initialize screen capture in main process @@ -589,7 +507,7 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu }); console.log('macOS microphone capture started'); - const { context, processor } = setupMicProcessing(micMediaStream); + const { context, processor } = await setupMicProcessing(micMediaStream); audioContext = context; audioProcessor = processor; } catch (micErr) { @@ -662,7 +580,7 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu video: false, }); console.log('Windows microphone capture started'); - const { context, processor } = setupMicProcessing(micMediaStream); + const { context, processor } = await setupMicProcessing(micMediaStream); audioContext = context; audioProcessor = processor; } catch (micErr) { @@ -765,6 +683,9 @@ function stopCapture() { // Exports & global registration // --------------------------- module.exports = { + getAec, // 새로 만든 초기화 함수 + runAecSync, // sync 버전 + disposeAec, // 필요시 Rust 객체 파괴 startCapture, stopCapture, captureManualScreenshot, diff --git a/src/features/listen/stt/sttService.js b/src/features/listen/stt/sttService.js index 493c014..57c312d 100644 --- a/src/features/listen/stt/sttService.js +++ b/src/features/listen/stt/sttService.js @@ -217,6 +217,8 @@ class SttService { }; const handleTheirMessage = message => { + if (!message || typeof message !== 'object') return; + if (this.modelInfo.provider === 'gemini') { const text = message.serverContent?.inputTranscription?.text || ''; if (text && text.trim()) { From 5cc0d2b83a22605600be9bf3036a5639ad6d90b6 Mon Sep 17 00:00:00 2001 From: Surya Date: Tue, 8 Jul 2025 15:54:04 +0530 Subject: [PATCH 45/52] Fix : Gemini JSON Format Answer fixed to plain text answer --- package-lock.json | 66 +---- pickleglass_web/package-lock.json | 10 - src/common/ai/providers/gemini.js | 419 ++++++++++++++---------------- 3 files changed, 193 insertions(+), 302 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5ae800a..944e413 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,16 @@ { "name": "pickle-glass", - "version": "0.2.1", + "version": "0.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pickle-glass", - "version": "0.2.1", + "version": "0.2.2", "hasInstallScript": true, "license": "GPL-3.0", "dependencies": { - "@anthropic-ai/sdk": "^0.56.0", - "@google/genai": "^1.8.0", "@google/generative-ai": "^0.24.1", "axios": "^1.10.0", @@ -54,7 +52,6 @@ "electron-liquid-glass": "^1.0.1" } }, - "node_modules/@anthropic-ai/sdk": { "version": "0.56.0", "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.56.0.tgz", @@ -64,7 +61,6 @@ "anthropic-ai-sdk": "bin/cli" } }, - "node_modules/@develar/schema-utils": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", @@ -889,11 +885,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.4.4", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz", "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==", - "license": "MIT", "optional": true, "dependencies": { @@ -901,11 +895,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz", "integrity": "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==", - "cpu": [ "ppc64" ], @@ -920,11 +912,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.6.tgz", "integrity": "sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==", - "cpu": [ "arm" ], @@ -939,11 +929,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.6.tgz", "integrity": "sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==", - "cpu": [ "arm64" ], @@ -958,11 +946,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.6.tgz", "integrity": "sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==", - "cpu": [ "x64" ], @@ -977,11 +963,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.6.tgz", "integrity": "sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==", - "cpu": [ "arm64" ], @@ -996,11 +980,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.6.tgz", "integrity": "sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==", - "cpu": [ "x64" ], @@ -1015,11 +997,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.6.tgz", "integrity": "sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==", - "cpu": [ "arm64" ], @@ -1034,11 +1014,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.6.tgz", "integrity": "sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==", - "cpu": [ "x64" ], @@ -1053,11 +1031,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.6.tgz", "integrity": "sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==", - "cpu": [ "arm" ], @@ -1072,11 +1048,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.6.tgz", "integrity": "sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==", - "cpu": [ "arm64" ], @@ -1091,11 +1065,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.6.tgz", "integrity": "sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==", - "cpu": [ "ia32" ], @@ -1110,11 +1082,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.6.tgz", "integrity": "sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==", - "cpu": [ "loong64" ], @@ -1129,11 +1099,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.6.tgz", "integrity": "sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==", - "cpu": [ "mips64el" ], @@ -1148,11 +1116,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.6.tgz", "integrity": "sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==", - "cpu": [ "ppc64" ], @@ -1167,11 +1133,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.6.tgz", "integrity": "sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==", - "cpu": [ "riscv64" ], @@ -1186,11 +1150,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.6.tgz", "integrity": "sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==", - "cpu": [ "s390x" ], @@ -1205,11 +1167,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.6.tgz", "integrity": "sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==", - "cpu": [ "x64" ], @@ -1224,11 +1184,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.6.tgz", "integrity": "sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==", - "cpu": [ "arm64" ], @@ -1243,11 +1201,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.6.tgz", "integrity": "sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==", - "cpu": [ "x64" ], @@ -1262,11 +1218,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.6.tgz", "integrity": "sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==", - "cpu": [ "arm64" ], @@ -1281,11 +1235,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.6.tgz", "integrity": "sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==", - "cpu": [ "x64" ], @@ -1299,7 +1251,6 @@ "node": ">=18" } }, - "node_modules/@esbuild/openharmony-arm64": { "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.6.tgz", @@ -1321,7 +1272,6 @@ "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.6.tgz", "integrity": "sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==", - "cpu": [ "x64" ], @@ -1336,11 +1286,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.6.tgz", "integrity": "sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==", - "cpu": [ "arm64" ], @@ -1355,11 +1303,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.6.tgz", "integrity": "sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==", - "cpu": [ "ia32" ], @@ -1374,11 +1320,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.6.tgz", "integrity": "sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==", - "cpu": [ "x64" ], @@ -3255,11 +3199,9 @@ } }, "node_modules/agent-base": { - "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", "engines": { "node": ">= 14" @@ -6055,11 +5997,9 @@ "optional": true }, "node_modules/esbuild": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz", "integrity": "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==", - "dev": true, "hasInstallScript": true, "license": "MIT", @@ -6070,7 +6010,6 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.6", "@esbuild/android-arm": "0.25.6", "@esbuild/android-arm64": "0.25.6", @@ -6097,7 +6036,6 @@ "@esbuild/win32-arm64": "0.25.6", "@esbuild/win32-ia32": "0.25.6", "@esbuild/win32-x64": "0.25.6" - } }, "node_modules/escalade": { diff --git a/pickleglass_web/package-lock.json b/pickleglass_web/package-lock.json index a1726d6..f1d6fa0 100644 --- a/pickleglass_web/package-lock.json +++ b/pickleglass_web/package-lock.json @@ -42,27 +42,21 @@ } }, "node_modules/@emnapi/core": { - "version": "1.4.4", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.4.tgz", "integrity": "sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.0.3", - "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.4.4", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz", "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==", - "dev": true, "license": "MIT", "optional": true, @@ -71,11 +65,9 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.0.3", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.3.tgz", "integrity": "sha512-8K5IFFsQqF9wQNJptGbS6FNKgUTsSRYnTqNCG1vPP8jFdjSv18n2mQfJpkt2Oibo9iBEzcDnDxNwKTzC7svlJw==", - "dev": true, "license": "MIT", "optional": true, @@ -2675,11 +2667,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.180", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.180.tgz", "integrity": "sha512-ED+GEyEh3kYMwt2faNmgMB0b8O5qtATGgR4RmRsIp4T6p7B8vdMbIedYndnvZfsaXvSzegtpfqRMDNCjjiSduA==", - "license": "ISC" }, "node_modules/emoji-regex": { diff --git a/src/common/ai/providers/gemini.js b/src/common/ai/providers/gemini.js index c3c4743..f3f864c 100644 --- a/src/common/ai/providers/gemini.js +++ b/src/common/ai/providers/gemini.js @@ -1,5 +1,5 @@ -const { GoogleGenerativeAI } = require('@google/generative-ai'); -const { GoogleGenAI } = require('@google/genai'); +const { GoogleGenerativeAI } = require("@google/generative-ai") +const { GoogleGenAI } = require("@google/genai") /** * Creates a Gemini STT session @@ -9,322 +9,285 @@ const { GoogleGenAI } = require('@google/genai'); * @param {object} [opts.callbacks] - Event callbacks * @returns {Promise} STT session */ -async function createSTT({ apiKey, language = 'en-US', callbacks = {}, ...config }) { - const liveClient = new GoogleGenAI({ vertexai: false, apiKey }); +async function createSTT({ apiKey, language = "en-US", callbacks = {}, ...config }) { + const liveClient = new GoogleGenAI({ vertexai: false, apiKey }) // Language code BCP-47 conversion - const lang = language.includes('-') ? language : `${language}-US`; + const lang = language.includes("-") ? language : `${language}-US` const session = await liveClient.live.connect({ - model: 'gemini-live-2.5-flash-preview', + model: "gemini-live-2.5-flash-preview", callbacks, config: { inputAudioTranscription: {}, speechConfig: { languageCode: lang }, }, - }); + }) return { - sendRealtimeInput: async payload => session.sendRealtimeInput(payload), + sendRealtimeInput: async (payload) => session.sendRealtimeInput(payload), close: async () => session.close(), - }; + } } /** - * Creates a Gemini LLM instance - * @param {object} opts - Configuration options - * @param {string} opts.apiKey - Gemini API key - * @param {string} [opts.model='gemini-2.5-flash'] - Model name - * @param {number} [opts.temperature=0.7] - Temperature - * @param {number} [opts.maxTokens=8192] - Max tokens - * @returns {object} LLM instance + * Creates a Gemini LLM instance with proper text response handling */ -function createLLM({ apiKey, model = 'gemini-2.5-flash', temperature = 0.7, maxTokens = 8192, ...config }) { - const client = new GoogleGenerativeAI(apiKey); - +function createLLM({ apiKey, model = "gemini-2.5-flash", temperature = 0.7, maxTokens = 8192, ...config }) { + const client = new GoogleGenerativeAI(apiKey) + return { generateContent: async (parts) => { - const geminiModel = client.getGenerativeModel({ model: model }); - - let systemPrompt = ''; - let userContent = []; - + const geminiModel = client.getGenerativeModel({ + model: model, + generationConfig: { + temperature, + maxOutputTokens: maxTokens, + // Ensure we get text responses, not JSON + responseMimeType: "text/plain", + }, + }) + + const systemPrompt = "" + const userContent = [] + for (const part of parts) { - if (typeof part === 'string') { - if (systemPrompt === '' && part.includes('You are')) { - systemPrompt = part; - } else { - userContent.push(part); - } + if (typeof part === "string") { + // Don't automatically assume strings starting with "You are" are system prompts + // Check if it's explicitly marked as a system instruction + userContent.push(part) } else if (part.inlineData) { - // Convert base64 image data to Gemini format userContent.push({ inlineData: { mimeType: part.inlineData.mimeType, - data: part.inlineData.data - } - }); + data: part.inlineData.data, + }, + }) } } - - // Prepare content array - const content = []; - - // Add system instruction if present - if (systemPrompt) { - // For Gemini, we'll prepend system prompt to user content - content.push(systemPrompt + '\n\n' + userContent[0]); - content.push(...userContent.slice(1)); - } else { - content.push(...userContent); - } - + try { - const result = await geminiModel.generateContent(content); - const response = await result.response; - + const result = await geminiModel.generateContent(userContent) + const response = await result.response + + // Return plain text, not wrapped in JSON structure return { response: { - text: () => response.text() - } - }; + text: () => response.text(), + }, + } } catch (error) { - console.error('Gemini API error:', error); - throw error; + console.error("Gemini API error:", error) + throw error } }, - - // For compatibility with chat-style interfaces + chat: async (messages) => { - // Extract system instruction if present - let systemInstruction = ''; - const history = []; - let lastMessage; + // Filter out any system prompts that might be causing JSON responses + let systemInstruction = "" + const history = [] + let lastMessage messages.forEach((msg, index) => { - if (msg.role === 'system') { - systemInstruction = msg.content; - return; + if (msg.role === "system") { + // Clean system instruction - avoid JSON formatting requests + systemInstruction = msg.content + .replace(/respond in json/gi, "") + .replace(/format.*json/gi, "") + .replace(/return.*json/gi, "") + + // Add explicit instruction for natural text + if (!systemInstruction.includes("respond naturally")) { + systemInstruction += "\n\nRespond naturally in plain text, not in JSON or structured format." + } + return } - - // Gemini's history format - const role = msg.role === 'user' ? 'user' : 'model'; + + const role = msg.role === "user" ? "user" : "model" if (index === messages.length - 1) { - lastMessage = msg; + lastMessage = msg } else { - history.push({ role, parts: [{ text: msg.content }] }); + history.push({ role, parts: [{ text: msg.content }] }) } - }); - - const geminiModel = client.getGenerativeModel({ + }) + + const geminiModel = client.getGenerativeModel({ model: model, - systemInstruction: systemInstruction - }); - - const chat = geminiModel.startChat({ - history: history, + systemInstruction: + systemInstruction || + "Respond naturally in plain text format. Do not use JSON or structured responses unless specifically requested.", generationConfig: { temperature: temperature, maxOutputTokens: maxTokens, - } - }); - - // Get the last user message content - let content = lastMessage.content; - - // Handle multimodal content for the last message + // Force plain text responses + responseMimeType: "text/plain", + }, + }) + + const chat = geminiModel.startChat({ + history: history, + }) + + let content = lastMessage.content + + // Handle multimodal content if (Array.isArray(content)) { - const geminiContent = []; + const geminiContent = [] for (const part of content) { - if (typeof part === 'string') { - geminiContent.push(part); - } else if (part.type === 'text') { - geminiContent.push(part.text); - } else if (part.type === 'image_url' && part.image_url) { - // Convert base64 image to Gemini format - const base64Data = part.image_url.url.split(',')[1]; + if (typeof part === "string") { + geminiContent.push(part) + } else if (part.type === "text") { + geminiContent.push(part.text) + } else if (part.type === "image_url" && part.image_url) { + const base64Data = part.image_url.url.split(",")[1] geminiContent.push({ inlineData: { - mimeType: 'image/png', - data: base64Data - } - }); + mimeType: "image/png", + data: base64Data, + }, + }) } } - content = geminiContent; + content = geminiContent } - - const result = await chat.sendMessage(content); - const response = await result.response; + + const result = await chat.sendMessage(content) + const response = await result.response + + // Return plain text content return { content: response.text(), - raw: result - }; - } - }; + raw: result, + } + }, + } } /** - * Creates a Gemini streaming LLM instance - * @param {object} opts - Configuration options - * @param {string} opts.apiKey - Gemini API key - * @param {string} [opts.model='gemini-2.5-flash'] - Model name - * @param {number} [opts.temperature=0.7] - Temperature - * @param {number} [opts.maxTokens=8192] - Max tokens - * @returns {object} Streaming LLM instance + * Creates a Gemini streaming LLM instance with text response fix */ -function createStreamingLLM({ apiKey, model = 'gemini-2.5-flash', temperature = 0.7, maxTokens = 8192, ...config }) { - const client = new GoogleGenerativeAI(apiKey); - +function createStreamingLLM({ apiKey, model = "gemini-2.5-flash", temperature = 0.7, maxTokens = 8192, ...config }) { + const client = new GoogleGenerativeAI(apiKey) + return { streamChat: async (messages) => { - console.log('[Gemini Provider] Starting streaming request'); - - // Extract system instruction if present - let systemInstruction = ''; - const nonSystemMessages = []; - + console.log("[Gemini Provider] Starting streaming request") + + let systemInstruction = "" + const nonSystemMessages = [] + for (const msg of messages) { - if (msg.role === 'system') { - systemInstruction = msg.content; + if (msg.role === "system") { + // Clean and modify system instruction + systemInstruction = msg.content + .replace(/respond in json/gi, "") + .replace(/format.*json/gi, "") + .replace(/return.*json/gi, "") + + if (!systemInstruction.includes("respond naturally")) { + systemInstruction += "\n\nRespond naturally in plain text, not in JSON or structured format." + } } else { - nonSystemMessages.push(msg); + nonSystemMessages.push(msg) } } - - const geminiModel = client.getGenerativeModel({ + + const geminiModel = client.getGenerativeModel({ model: model, - systemInstruction: systemInstruction || undefined - }); - - const chat = geminiModel.startChat({ - history: [], + systemInstruction: + systemInstruction || + "Respond naturally in plain text format. Do not use JSON or structured responses unless specifically requested.", generationConfig: { temperature, maxOutputTokens: maxTokens || 8192, - } - }); - - // Create a ReadableStream to handle Gemini's streaming + // Force plain text responses + responseMimeType: "text/plain", + }, + }) + const stream = new ReadableStream({ async start(controller) { try { - console.log('[Gemini Provider] Processing messages:', nonSystemMessages.length, 'messages (excluding system)'); - - // Get the last user message - const lastMessage = nonSystemMessages[nonSystemMessages.length - 1]; - let lastUserMessage = lastMessage.content; - - // Handle case where content might be an array (multimodal) - if (Array.isArray(lastUserMessage)) { - // Extract text content from array - const textParts = lastUserMessage.filter(part => - typeof part === 'string' || (part && part.type === 'text') - ); - lastUserMessage = textParts.map(part => - typeof part === 'string' ? part : part.text - ).join(' '); - } - - console.log('[Gemini Provider] Sending message to Gemini:', - typeof lastUserMessage === 'string' ? lastUserMessage.substring(0, 100) + '...' : 'multimodal content'); - - // Prepare the message content for Gemini - let geminiContent = []; - - // Handle multimodal content properly + const lastMessage = nonSystemMessages[nonSystemMessages.length - 1] + let geminiContent = [] + if (Array.isArray(lastMessage.content)) { for (const part of lastMessage.content) { - if (typeof part === 'string') { - geminiContent.push(part); - } else if (part.type === 'text') { - geminiContent.push(part.text); - } else if (part.type === 'image_url' && part.image_url) { - // Convert base64 image to Gemini format - const base64Data = part.image_url.url.split(',')[1]; + if (typeof part === "string") { + geminiContent.push(part) + } else if (part.type === "text") { + geminiContent.push(part.text) + } else if (part.type === "image_url" && part.image_url) { + const base64Data = part.image_url.url.split(",")[1] geminiContent.push({ inlineData: { - mimeType: 'image/png', - data: base64Data - } - }); + mimeType: "image/png", + data: base64Data, + }, + }) } } } else { - geminiContent = [lastUserMessage]; + geminiContent = [lastMessage.content] } - - console.log('[Gemini Provider] Prepared Gemini content:', - geminiContent.length, 'parts'); - - // Stream the response - let chunkCount = 0; - let totalContent = ''; - - const contentParts = geminiContent.map(part => { - if (typeof part === 'string') { - return { text: part }; + + const contentParts = geminiContent.map((part) => { + if (typeof part === "string") { + return { text: part } } else if (part.inlineData) { - return { inlineData: part.inlineData }; + return { inlineData: part.inlineData } } - return part; - }); + return part + }) const result = await geminiModel.generateContentStream({ - contents: [{ - role: 'user', - parts: contentParts - }], - generationConfig: { - temperature, - maxOutputTokens: maxTokens || 8192, - } - }); - + contents: [ + { + role: "user", + parts: contentParts, + }, + ], + }) + for await (const chunk of result.stream) { - chunkCount++; - const chunkText = chunk.text() || ''; - totalContent += chunkText; - - // Format as SSE data + const chunkText = chunk.text() || "" + + // Format as SSE data - this should now be plain text const data = JSON.stringify({ - choices: [{ - delta: { - content: chunkText - } - }] - }); - controller.enqueue(new TextEncoder().encode(`data: ${data}\n\n`)); + choices: [ + { + delta: { + content: chunkText, + }, + }, + ], + }) + controller.enqueue(new TextEncoder().encode(`data: ${data}\n\n`)) } - - console.log(`[Gemini Provider] Streamed ${chunkCount} chunks, total length: ${totalContent.length} chars`); - - // Send the final done message - controller.enqueue(new TextEncoder().encode('data: [DONE]\n\n')); - controller.close(); - console.log('[Gemini Provider] Streaming completed successfully'); + + controller.enqueue(new TextEncoder().encode("data: [DONE]\n\n")) + controller.close() } catch (error) { - console.error('[Gemini Provider] Streaming error:', error); - controller.error(error); + console.error("[Gemini Provider] Streaming error:", error) + controller.error(error) } - } - }); - - // Create a Response object with the stream + }, + }) + return new Response(stream, { headers: { - 'Content-Type': 'text/event-stream', - 'Cache-Control': 'no-cache', - 'Connection': 'keep-alive' - } - }); - } - }; + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + Connection: "keep-alive", + }, + }) + }, + } } module.exports = { createSTT, createLLM, - createStreamingLLM -}; + createStreamingLLM, +} From e9b5f8ee35706b708e4cf863045cade4846c2054 Mon Sep 17 00:00:00 2001 From: samtiz Date: Tue, 8 Jul 2025 20:57:26 +0900 Subject: [PATCH 46/52] feat: Integrate AEC via submodule and apply related changes --- .gitmodules | 3 ++ aec | 2 +- package-lock.json | 66 +--------------------------- src/features/listen/listenService.js | 23 +++++++++- 4 files changed, 27 insertions(+), 67 deletions(-) create mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0c4ea82 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "aec"] + path = aec + url = https://github.com/samtiz/aec.git diff --git a/aec b/aec index 66c447b..f00bb1f 160000 --- a/aec +++ b/aec @@ -1 +1 @@ -Subproject commit 66c447ba544dfe8e3bb4091fda2961a11066910b +Subproject commit f00bb1fb948053c752b916adfee19f90644a0b2f diff --git a/package-lock.json b/package-lock.json index 5ae800a..944e413 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,16 @@ { "name": "pickle-glass", - "version": "0.2.1", + "version": "0.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pickle-glass", - "version": "0.2.1", + "version": "0.2.2", "hasInstallScript": true, "license": "GPL-3.0", "dependencies": { - "@anthropic-ai/sdk": "^0.56.0", - "@google/genai": "^1.8.0", "@google/generative-ai": "^0.24.1", "axios": "^1.10.0", @@ -54,7 +52,6 @@ "electron-liquid-glass": "^1.0.1" } }, - "node_modules/@anthropic-ai/sdk": { "version": "0.56.0", "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.56.0.tgz", @@ -64,7 +61,6 @@ "anthropic-ai-sdk": "bin/cli" } }, - "node_modules/@develar/schema-utils": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", @@ -889,11 +885,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.4.4", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz", "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==", - "license": "MIT", "optional": true, "dependencies": { @@ -901,11 +895,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz", "integrity": "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==", - "cpu": [ "ppc64" ], @@ -920,11 +912,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.6.tgz", "integrity": "sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==", - "cpu": [ "arm" ], @@ -939,11 +929,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.6.tgz", "integrity": "sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==", - "cpu": [ "arm64" ], @@ -958,11 +946,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.6.tgz", "integrity": "sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==", - "cpu": [ "x64" ], @@ -977,11 +963,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.6.tgz", "integrity": "sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==", - "cpu": [ "arm64" ], @@ -996,11 +980,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.6.tgz", "integrity": "sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==", - "cpu": [ "x64" ], @@ -1015,11 +997,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.6.tgz", "integrity": "sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==", - "cpu": [ "arm64" ], @@ -1034,11 +1014,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.6.tgz", "integrity": "sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==", - "cpu": [ "x64" ], @@ -1053,11 +1031,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.6.tgz", "integrity": "sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==", - "cpu": [ "arm" ], @@ -1072,11 +1048,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.6.tgz", "integrity": "sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==", - "cpu": [ "arm64" ], @@ -1091,11 +1065,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.6.tgz", "integrity": "sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==", - "cpu": [ "ia32" ], @@ -1110,11 +1082,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.6.tgz", "integrity": "sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==", - "cpu": [ "loong64" ], @@ -1129,11 +1099,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.6.tgz", "integrity": "sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==", - "cpu": [ "mips64el" ], @@ -1148,11 +1116,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.6.tgz", "integrity": "sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==", - "cpu": [ "ppc64" ], @@ -1167,11 +1133,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.6.tgz", "integrity": "sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==", - "cpu": [ "riscv64" ], @@ -1186,11 +1150,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.6.tgz", "integrity": "sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==", - "cpu": [ "s390x" ], @@ -1205,11 +1167,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.6.tgz", "integrity": "sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==", - "cpu": [ "x64" ], @@ -1224,11 +1184,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.6.tgz", "integrity": "sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==", - "cpu": [ "arm64" ], @@ -1243,11 +1201,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.6.tgz", "integrity": "sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==", - "cpu": [ "x64" ], @@ -1262,11 +1218,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.6.tgz", "integrity": "sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==", - "cpu": [ "arm64" ], @@ -1281,11 +1235,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.6.tgz", "integrity": "sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==", - "cpu": [ "x64" ], @@ -1299,7 +1251,6 @@ "node": ">=18" } }, - "node_modules/@esbuild/openharmony-arm64": { "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.6.tgz", @@ -1321,7 +1272,6 @@ "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.6.tgz", "integrity": "sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==", - "cpu": [ "x64" ], @@ -1336,11 +1286,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.6.tgz", "integrity": "sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==", - "cpu": [ "arm64" ], @@ -1355,11 +1303,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.6.tgz", "integrity": "sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==", - "cpu": [ "ia32" ], @@ -1374,11 +1320,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.6.tgz", "integrity": "sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==", - "cpu": [ "x64" ], @@ -3255,11 +3199,9 @@ } }, "node_modules/agent-base": { - "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", "engines": { "node": ">= 14" @@ -6055,11 +5997,9 @@ "optional": true }, "node_modules/esbuild": { - "version": "0.25.6", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz", "integrity": "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==", - "dev": true, "hasInstallScript": true, "license": "MIT", @@ -6070,7 +6010,6 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.6", "@esbuild/android-arm": "0.25.6", "@esbuild/android-arm64": "0.25.6", @@ -6097,7 +6036,6 @@ "@esbuild/win32-arm64": "0.25.6", "@esbuild/win32-ia32": "0.25.6", "@esbuild/win32-x64": "0.25.6" - } }, "node_modules/escalade": { diff --git a/src/features/listen/listenService.js b/src/features/listen/listenService.js index 10aa459..4218745 100644 --- a/src/features/listen/listenService.js +++ b/src/features/listen/listenService.js @@ -117,8 +117,27 @@ class ListenService { throw new Error('Failed to initialize database session'); } - // Initialize STT sessions - await this.sttService.initializeSttSessions(language); + /* ---------- STT Initialization Retry Logic ---------- */ + const MAX_RETRY = 10; + const RETRY_DELAY_MS = 300; // 0.3 seconds + + let sttReady = false; + for (let attempt = 1; attempt <= MAX_RETRY; attempt++) { + try { + await this.sttService.initializeSttSessions(language); + sttReady = true; + break; // Exit on success + } catch (err) { + console.warn( + `[ListenService] STT init attempt ${attempt} failed: ${err.message}` + ); + if (attempt < MAX_RETRY) { + await new Promise(r => setTimeout(r, RETRY_DELAY_MS)); + } + } + } + if (!sttReady) throw new Error('STT init failed after retries'); + /* ------------------------------------------- */ console.log('✅ Listen service initialized successfully.'); From 843694daac53e7f11d7c67df0dd947a45f4a4d6f Mon Sep 17 00:00:00 2001 From: sanio Date: Tue, 8 Jul 2025 21:35:20 +0900 Subject: [PATCH 47/52] add shortcut editing(beta) --- README.md | 5 +- src/app/MainHeader.js | 76 +- src/app/PickleGlassApp.js | 3 + src/electron/windowManager.js | 806 +++++++++--------- src/features/ask/AskView.js | 20 + src/features/settings/SettingsView.js | 134 ++- src/features/settings/ShortCutSettingsView.js | 235 +++++ 7 files changed, 759 insertions(+), 520 deletions(-) create mode 100644 src/features/settings/ShortCutSettingsView.js diff --git a/README.md b/README.md index 8397aec..e2842ff 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,6 @@ We have a list of [help wanted](https://github.com/pickle-com/glass/issues?q=is% | Status | Issue | Description | |--------|--------------------------------|---------------------------------------------------| -| 🚧 WIP | Code Refactoring | Refactoring the entire codebase for better maintainability. | | 🚧 WIP | Windows Build | Make Glass buildable & runnable in Windows | | 🚧 WIP | Local LLM Support | Supporting Local LLM to power AI answers | | 🚧 WIP | AEC Improvement | Transcription is not working occasionally | @@ -128,6 +127,10 @@ We have a list of [help wanted](https://github.com/pickle-com/glass/issues?q=is% ### Changelog - Jul 5: Now support Gemini, Intel Mac supported +- Jul 6: Full code refactoring has done. +- Jul 7: Now support Claude, LLM/STT model selection +- Jul 8: Now support Windows(beta), Improved AEC by Rust(to seperate mic/system audio), shortcut editing(beta) + ## About Pickle diff --git a/src/app/MainHeader.js b/src/app/MainHeader.js index 5212fae..7c92f7c 100644 --- a/src/app/MainHeader.js +++ b/src/app/MainHeader.js @@ -3,11 +3,12 @@ import { html, css, LitElement } from '../assets/lit-core-2.7.4.min.js'; export class MainHeader extends LitElement { static properties = { isSessionActive: { type: Boolean, state: true }, + shortcuts: { type: Object, state: true }, }; static styles = css` :host { - display: block; + display: flex; transform: translate3d(0, 0, 0); backface-visibility: hidden; transition: transform 0.2s cubic-bezier(0.23, 1, 0.32, 1), opacity 0.2s ease-out; @@ -99,7 +100,7 @@ export class MainHeader extends LitElement { } .header { - width: 100%; + width: max-content; height: 47px; padding: 2px 10px 2px 13px; background: transparent; @@ -212,16 +213,6 @@ export class MainHeader extends LitElement { } .action-button, - .settings-button { - background: transparent; - color: white; - border: none; - cursor: pointer; - display: flex; - align-items: center; - gap: 6px; - } - .action-text { padding-bottom: 1px; justify-content: center; @@ -275,9 +266,16 @@ export class MainHeader extends LitElement { .settings-button { padding: 5px; border-radius: 50%; + background: transparent; transition: background 0.15s ease; + color: white; + border: none; + cursor: pointer; + display: flex; + align-items: center; + gap: 6px; } - + .settings-button:hover { background: rgba(255, 255, 255, 0.1); } @@ -286,6 +284,7 @@ export class MainHeader extends LitElement { display: flex; align-items: center; justify-content: center; + padding: 3px; } .settings-icon svg { @@ -346,6 +345,7 @@ export class MainHeader extends LitElement { constructor() { super(); + this.shortcuts = {}; this.dragState = null; this.wasJustDragged = false; this.isVisible = true; @@ -501,6 +501,11 @@ export class MainHeader extends LitElement { this.isSessionActive = isActive; }; ipcRenderer.on('session-state-changed', this._sessionStateListener); + this._shortcutListener = (event, keybinds) => { + console.log('[MainHeader] Received updated shortcuts:', keybinds); + this.shortcuts = keybinds; + }; + ipcRenderer.on('shortcuts-updated', this._shortcutListener); } } @@ -518,6 +523,9 @@ export class MainHeader extends LitElement { if (this._sessionStateListener) { ipcRenderer.removeListener('session-state-changed', this._sessionStateListener); } + if (this._shortcutListener) { + ipcRenderer.removeListener('shortcuts-updated', this._shortcutListener); + } } } @@ -567,6 +575,29 @@ export class MainHeader extends LitElement { } + renderShortcut(accelerator) { + if (!accelerator) return html``; + + const keyMap = { + 'Cmd': '⌘', 'Command': '⌘', + 'Ctrl': '⌃', 'Control': '⌃', + 'Alt': '⌥', 'Option': '⌥', + 'Shift': '⇧', + 'Enter': '↵', + 'Backspace': '⌫', + 'Delete': '⌦', + 'Tab': '⇥', + 'Escape': '⎋', + 'Up': '↑', 'Down': '↓', 'Left': '←', 'Right': '→', + '\\': html``, + }; + + const keys = accelerator.split('+'); + return html`${keys.map(key => html` +
${keyMap[key] || key}
+ `)}`; + } + render() { return html`
@@ -599,14 +630,8 @@ export class MainHeader extends LitElement {
Ask
-
-
-
- - - - -
+
+ ${this.renderShortcut(this.shortcuts.nextStep)}
@@ -614,13 +639,8 @@ export class MainHeader extends LitElement {
Show/Hide
-
-
-
- - - -
+
+ ${this.renderShortcut(this.shortcuts.toggleVisibility)}
diff --git a/src/app/PickleGlassApp.js b/src/app/PickleGlassApp.js index 6cf1666..e2e8495 100644 --- a/src/app/PickleGlassApp.js +++ b/src/app/PickleGlassApp.js @@ -2,6 +2,7 @@ import { html, css, LitElement } from '../assets/lit-core-2.7.4.min.js'; import { SettingsView } from '../features/settings/SettingsView.js'; import { AssistantView } from '../features/listen/AssistantView.js'; import { AskView } from '../features/ask/AskView.js'; +import { ShortcutSettingsView } from '../features/settings/ShortCutSettingsView.js'; import '../features/listen/renderer/renderer.js'; @@ -268,6 +269,8 @@ export class PickleGlassApp extends LitElement { .onProfileChange=${profile => (this.selectedProfile = profile)} .onLanguageChange=${lang => (this.selectedLanguage = lang)} >`; + case 'shortcut-settings': + return html``; case 'history': return html``; case 'help': diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 32441b7..ff85e16 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -11,7 +11,13 @@ const authService = require('../common/services/authService'); const systemSettingsRepository = require('../common/repositories/systemSettings'); const userRepository = require('../common/repositories/user'); const fetch = require('node-fetch'); - +const Store = require('electron-store'); +const shortCutStore = new Store({ + name: 'user-preferences', + defaults: { + customKeybinds: {} + } +}); /* ────────────────[ GLASS BYPASS ]─────────────── */ let liquidGlass; @@ -51,6 +57,7 @@ let settingsHideTimer = null; let selectedCaptureSourceId = null; +// let shortcutEditorWindow = null; let layoutManager = null; function updateLayout() { if (layoutManager) { @@ -60,16 +67,16 @@ function updateLayout() { let movementManager = null; -let storedProvider = 'openai'; const featureWindows = ['listen','ask','settings']; +// const featureWindows = ['listen','ask','settings','shortcut-settings']; function isAllowed(name) { if (name === 'header') return true; return featureWindows.includes(name) && currentHeaderState === 'main'; } -function createFeatureWindows(header) { - if (windowPool.has('listen')) return; +function createFeatureWindows(header, namesToCreate) { + // if (windowPool.has('listen')) return; const commonChildOptions = { parent: header, @@ -84,106 +91,207 @@ function createFeatureWindows(header) { webPreferences: { nodeIntegration: true, contextIsolation: false }, }; - // listen - const listen = new BrowserWindow({ - ...commonChildOptions, width:400,minWidth:400,maxWidth:400, - maxHeight:700, - }); - listen.setContentProtection(isContentProtectionOn); - listen.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - if (process.platform === 'darwin') { - listen.setWindowButtonVisibility(false); - } - const listenLoadOptions = { query: { view: 'listen' } }; - if (!shouldUseLiquidGlass) { - listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); - } - else { - listenLoadOptions.query.glass = 'true'; - listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); - listen.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(listen.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); - if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); - // liquidGlass.unstable_setScrim(viewId, 1); - // liquidGlass.unstable_setSubdued(viewId, 1); + const createFeatureWindow = (name) => { + if (windowPool.has(name)) return; + + switch (name) { + case 'listen': { + const listen = new BrowserWindow({ + ...commonChildOptions, width:400,minWidth:400,maxWidth:400, + maxHeight:700, + }); + listen.setContentProtection(isContentProtectionOn); + listen.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); + if (process.platform === 'darwin') { + listen.setWindowButtonVisibility(false); + } + const listenLoadOptions = { query: { view: 'listen' } }; + if (!shouldUseLiquidGlass) { + listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); + } + else { + listenLoadOptions.query.glass = 'true'; + listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); + listen.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(listen.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + windowPool.set('listen', listen); + break; } - }); - } + // ask + case 'ask': { + const ask = new BrowserWindow({ ...commonChildOptions, width:600 }); + ask.setContentProtection(isContentProtectionOn); + ask.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); + if (process.platform === 'darwin') { + ask.setWindowButtonVisibility(false); + } + const askLoadOptions = { query: { view: 'ask' } }; + if (!shouldUseLiquidGlass) { + ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); + } + else { + askLoadOptions.query.glass = 'true'; + ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); + ask.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(ask.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } - windowPool.set('listen', listen); - - // ask - const ask = new BrowserWindow({ ...commonChildOptions, width:600 }); - ask.setContentProtection(isContentProtectionOn); - ask.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - if (process.platform === 'darwin') { - ask.setWindowButtonVisibility(false); - } - const askLoadOptions = { query: { view: 'ask' } }; - if (!shouldUseLiquidGlass) { - ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); - } - else { - askLoadOptions.query.glass = 'true'; - ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); - ask.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(ask.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); - if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); - // liquidGlass.unstable_setScrim(viewId, 1); - // liquidGlass.unstable_setSubdued(viewId, 1); + ask.on('blur',()=>ask.webContents.send('window-blur')); + + // Open DevTools in development + if (!app.isPackaged) { + ask.webContents.openDevTools({ mode: 'detach' }); + } + windowPool.set('ask', ask); + break; } - }); - } - ask.on('blur',()=>ask.webContents.send('window-blur')); - - // Open DevTools in development - if (!app.isPackaged) { - ask.webContents.openDevTools({ mode: 'detach' }); - } - windowPool.set('ask', ask); - - // settings - const settings = new BrowserWindow({ ...commonChildOptions, width:240, maxHeight:400, parent:undefined }); - settings.setContentProtection(isContentProtectionOn); - settings.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - if (process.platform === 'darwin') { - settings.setWindowButtonVisibility(false); - } - const settingsLoadOptions = { query: { view: 'settings' } }; - if (!shouldUseLiquidGlass) { - settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) - .catch(console.error); - } - else { - settingsLoadOptions.query.glass = 'true'; - settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) - .catch(console.error); - settings.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(settings.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); - if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); - // liquidGlass.unstable_setScrim(viewId, 1); - // liquidGlass.unstable_setSubdued(viewId, 1); + // settings + case 'settings': { + const settings = new BrowserWindow({ ...commonChildOptions, width:240, maxHeight:400, parent:undefined }); + settings.setContentProtection(isContentProtectionOn); + settings.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); + if (process.platform === 'darwin') { + settings.setWindowButtonVisibility(false); + } + const settingsLoadOptions = { query: { view: 'settings' } }; + if (!shouldUseLiquidGlass) { + settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) + .catch(console.error); + } + else { + settingsLoadOptions.query.glass = 'true'; + settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) + .catch(console.error); + settings.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(settings.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + windowPool.set('settings', settings); + break; } - }); + + case 'shortcut-settings': { + const shortcutEditor = new BrowserWindow({ + ...commonChildOptions, + width: 420, + height: 720, + modal: false, + parent: undefined, + alwaysOnTop: true, + titleBarOverlay: false, + }); + + if (process.platform === 'darwin') { + shortcutEditor.setAlwaysOnTop(true, 'screen-saver'); + } else { + shortcutEditor.setAlwaysOnTop(true); + } + + /* ──────────[ ① 다른 창 클릭 차단 ]────────── */ + const disableClicks = () => { + for (const [name, win] of windowPool) { + if (win !== shortcutEditor && !win.isDestroyed()) { + win.setIgnoreMouseEvents(true, { forward: true }); + } + } + }; + const restoreClicks = () => { + for (const [, win] of windowPool) { + if (!win.isDestroyed()) win.setIgnoreMouseEvents(false); + } + }; + + const header = windowPool.get('header'); + if (header && !header.isDestroyed()) { + const { x, y, width } = header.getBounds(); + shortcutEditor.setBounds({ x, y, width }); + } + + shortcutEditor.once('ready-to-show', () => { + disableClicks(); + shortcutEditor.show(); + }); + + const loadOptions = { query: { view: 'shortcut-settings' } }; + if (!shouldUseLiquidGlass) { + shortcutEditor.loadFile(path.join(__dirname, '../app/content.html'), loadOptions); + } else { + loadOptions.query.glass = 'true'; + shortcutEditor.loadFile(path.join(__dirname, '../app/content.html'), loadOptions); + shortcutEditor.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(shortcutEditor.getNativeWindowHandle(), { + cornerRadius: 12, tintColor: '#FF00001A', opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + } + }); + } + + shortcutEditor.on('closed', () => { + restoreClicks(); + windowPool.delete('shortcut-settings'); + console.log('[Shortcuts] Re-enabled after editing.'); + loadAndRegisterShortcuts(movementManager); + }); + + shortcutEditor.webContents.once('dom-ready', async () => { + const savedKeybinds = shortCutStore.get('customKeybinds', {}); + const defaultKeybinds = getDefaultKeybinds(); + const keybinds = { ...defaultKeybinds, ...savedKeybinds }; + shortcutEditor.webContents.send('load-shortcuts', keybinds); + }); + + if (!app.isPackaged) { + shortcutEditor.webContents.openDevTools({ mode: 'detach' }); + } + windowPool.set('shortcut-settings', shortcutEditor); + break; + } + } + }; + + if (Array.isArray(namesToCreate)) { + namesToCreate.forEach(name => createFeatureWindow(name)); + } else if (typeof namesToCreate === 'string') { + createFeatureWindow(namesToCreate); + } else { + createFeatureWindow('listen'); + createFeatureWindow('ask'); + createFeatureWindow('settings'); } - windowPool.set('settings', settings); } function destroyFeatureWindows() { @@ -199,6 +307,7 @@ function destroyFeatureWindows() { } + function getCurrentDisplay(window) { if (!window || window.isDestroyed()) return screen.getPrimaryDisplay(); @@ -354,7 +463,7 @@ function createWindows() { setupIpcHandlers(movementManager); if (currentHeaderState === 'main') { - createFeatureWindows(header); + createFeatureWindows(header, ['listen', 'ask', 'settings', 'shortcut-settings']); } header.setContentProtection(isContentProtectionOn); @@ -385,10 +494,6 @@ function createWindows() { header.on('resize', updateLayout); - // header.webContents.once('dom-ready', () => { - // loadAndRegisterShortcuts(); - // }); - ipcMain.handle('toggle-all-windows-visibility', () => toggleAllWindowsVisibility(movementManager)); ipcMain.handle('toggle-feature', async (event, featureName) => { @@ -584,37 +689,32 @@ function createWindows() { } }); - // setupIpcHandlers(); - return windowPool; } function loadAndRegisterShortcuts(movementManager) { + if (windowPool.has('shortcut-settings')) { + console.log('[Shortcuts] Editing in progress, skipping registration.'); + return; + } + const defaultKeybinds = getDefaultKeybinds(); - const header = windowPool.get('header'); + const savedKeybinds = shortCutStore.get('customKeybinds', {}); + const keybinds = { ...defaultKeybinds, ...savedKeybinds }; + const sendToRenderer = (channel, ...args) => { windowPool.forEach(win => { - try { - if (win && !win.isDestroyed()) { + if (win && !win.isDestroyed()) { + try { win.webContents.send(channel, ...args); + } catch (e) { + // 창이 이미 닫혔을 수 있으므로 오류를 무시합니다. } - } catch (e) {} + } }); }; - - if (!header) { - return updateGlobalShortcuts(defaultKeybinds, undefined, sendToRenderer, movementManager); - } - - header.webContents - .executeJavaScript(`(() => localStorage.getItem('customKeybinds'))()`) - .then(saved => (saved ? JSON.parse(saved) : {})) - .then(savedKeybinds => { - const keybinds = { ...defaultKeybinds, ...savedKeybinds }; - updateGlobalShortcuts(keybinds, header, sendToRenderer, movementManager); - }) - .catch(() => updateGlobalShortcuts(defaultKeybinds, header, sendToRenderer, movementManager)); + updateGlobalShortcuts(keybinds, windowPool.get('header'), sendToRenderer, movementManager); } @@ -768,6 +868,7 @@ function setupIpcHandlers(movementManager) { } else { // 'apikey' | 'permission' destroyFeatureWindows(); } + loadAndRegisterShortcuts(movementManager); for (const [name, win] of windowPool) { if (!isAllowed(name) && !win.isDestroyed()) { @@ -777,36 +878,69 @@ function setupIpcHandlers(movementManager) { win.show(); } } - - const header = windowPool.get('header'); - if (header && !header.isDestroyed()) { - header.webContents - .executeJavaScript(`(() => localStorage.getItem('customKeybinds'))()`) - .then(saved => { - const defaultKeybinds = getDefaultKeybinds(); - const savedKeybinds = saved ? JSON.parse(saved) : {}; - const keybinds = { ...defaultKeybinds, ...savedKeybinds }; - - const sendToRenderer = (channel, ...args) => { - windowPool.forEach(win => { - try { - if (win && !win.isDestroyed()) { - win.webContents.send(channel, ...args); - } - } catch (e) {} - }); - }; - - updateGlobalShortcuts(keybinds, header, sendToRenderer, movementManager); - }) - .catch(console.error); - } }); ipcMain.on('update-keybinds', (event, newKeybinds) => { updateGlobalShortcuts(newKeybinds); }); + ipcMain.handle('get-current-shortcuts', () => { + const defaultKeybinds = getDefaultKeybinds(); + const savedKeybinds = shortCutStore.get('customKeybinds', {}); + return { ...defaultKeybinds, ...savedKeybinds }; + }); + + ipcMain.handle('open-shortcut-editor', () => { + const header = windowPool.get('header'); + if (!header) return; + + // 편집기 열기 전 모든 단축키 비활성화 + globalShortcut.unregisterAll(); + console.log('[Shortcuts] Disabled for editing.'); + + createFeatureWindows(header, 'shortcut-settings'); + }); + + ipcMain.handle('get-default-shortcuts', () => { + shortCutStore.set('customKeybinds', {}); + return getDefaultKeybinds(); + }); + + ipcMain.handle('save-shortcuts', async (event, newKeybinds) => { + try { + const defaultKeybinds = getDefaultKeybinds(); + const customKeybinds = {}; + for (const key in newKeybinds) { + if (newKeybinds[key] && newKeybinds[key] !== defaultKeybinds[key]) { + customKeybinds[key] = newKeybinds[key]; + } + } + + shortCutStore.set('customKeybinds', customKeybinds); + console.log('[Shortcuts] Custom keybinds saved to store:', customKeybinds); + + const editor = windowPool.get('shortcut-settings'); + if (editor && !editor.isDestroyed()) { + editor.close(); + } else { + loadAndRegisterShortcuts(movementManager); + } + + return { success: true }; + } catch (error) { + console.error("Failed to save shortcuts:", error); + loadAndRegisterShortcuts(movementManager); + return { success: false, error: error.message }; + } + }); + + ipcMain.on('close-shortcut-editor', () => { + const editor = windowPool.get('shortcut-settings'); + if (editor && !editor.isDestroyed()) { + editor.close(); + } + }); + ipcMain.handle('open-login-page', () => { const webUrl = process.env.pickleglass_WEB_URL || 'http://localhost:3000'; const personalizeUrl = `${webUrl}/personalize?desktop=true`; @@ -971,15 +1105,6 @@ function setupIpcHandlers(movementManager) { console.log('[WindowManager] Received request to log out.'); await authService.signOut(); - //////// before_modelStateService //////// - // await setApiKey(null); - - // windowPool.forEach(win => { - // if (win && !win.isDestroyed()) { - // win.webContents.send('api-key-removed'); - // } - // }); - //////// before_modelStateService //////// }); ipcMain.handle('check-system-permissions', async () => { @@ -1114,101 +1239,6 @@ function setupIpcHandlers(movementManager) { } -//////// before_modelStateService //////// -// async function setApiKey(apiKey, provider = 'openai') { -// console.log('[WindowManager] Persisting API key and provider to DB'); - -// try { -// await userRepository.saveApiKey(apiKey, authService.getCurrentUserId(), provider); -// console.log('[WindowManager] API key and provider saved to SQLite'); - -// // Notify authService that the key status may have changed -// await authService.updateApiKeyStatus(); - -// } catch (err) { -// console.error('[WindowManager] Failed to save API key to SQLite:', err); -// } - -// windowPool.forEach(win => { -// if (win && !win.isDestroyed()) { -// const js = apiKey ? ` -// localStorage.setItem('openai_api_key', ${JSON.stringify(apiKey)}); -// localStorage.setItem('ai_provider', ${JSON.stringify(provider)}); -// ` : ` -// localStorage.removeItem('openai_api_key'); -// localStorage.removeItem('ai_provider'); -// `; -// win.webContents.executeJavaScript(js).catch(() => {}); -// } -// }); -// } - - -// async function getStoredApiKey() { -// const userId = authService.getCurrentUserId(); -// if (!userId) return null; -// const user = await userRepository.getById(userId); -// return user?.api_key || null; -// } - -// async function getStoredProvider() { -// const userId = authService.getCurrentUserId(); -// if (!userId) return 'openai'; -// const user = await userRepository.getById(userId); -// return user?.provider || 'openai'; -// } - -// function setupApiKeyIPC() { -// const { ipcMain } = require('electron'); - -// // Both handlers now do the same thing: fetch the key from the source of truth. -// ipcMain.handle('get-stored-api-key', getStoredApiKey); - -// ipcMain.handle('api-key-validated', async (event, data) => { -// console.log('[WindowManager] API key validation completed, saving...'); - -// // Support both old format (string) and new format (object) -// const apiKey = typeof data === 'string' ? data : data.apiKey; -// const provider = typeof data === 'string' ? 'openai' : (data.provider || 'openai'); - -// await setApiKey(apiKey, provider); - -// windowPool.forEach((win, name) => { -// if (win && !win.isDestroyed()) { -// win.webContents.send('api-key-validated', { apiKey, provider }); -// } -// }); - -// return { success: true }; -// }); - -// ipcMain.handle('remove-api-key', async () => { -// console.log('[WindowManager] API key removal requested'); -// await setApiKey(null); - -// windowPool.forEach((win, name) => { -// if (win && !win.isDestroyed()) { -// win.webContents.send('api-key-removed'); -// } -// }); - -// const settingsWindow = windowPool.get('settings'); -// if (settingsWindow && settingsWindow.isVisible()) { -// settingsWindow.hide(); -// console.log('[WindowManager] Settings window hidden after clearing API key.'); -// } - -// return { success: true }; -// }); - -// ipcMain.handle('get-ai-provider', getStoredProvider); - -// console.log('[WindowManager] API key related IPC handlers registered (SQLite-backed)'); -// } -//////// before_modelStateService //////// - - - //////// after_modelStateService //////// async function getStoredApiKey() { @@ -1227,15 +1257,15 @@ async function getStoredProvider() { } /** - * 렌더러에서 요청한 타입('llm' 또는 'stt')에 대한 모델 정보를 반환합니다. - * @param {IpcMainInvokeEvent} event - 일렉트론 IPC 이벤트 객체 - * @param {{type: 'llm' | 'stt'}} { type } - 요청할 모델 타입 + * + * @param {IpcMainInvokeEvent} event + * @param {{type: 'llm' | 'stt'}} */ async function getCurrentModelInfo(event, { type }) { if (global.modelStateService && (type === 'llm' || type === 'stt')) { return global.modelStateService.getCurrentModelInfo(type); } - return null; // 서비스가 없거나 유효하지 않은 타입일 경우 null 반환 + return null; } function setupApiKeyIPC() { @@ -1279,33 +1309,26 @@ function getDefaultKeybinds() { } function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementManager) { - // console.log('Updating global shortcuts with:', keybinds); - - // Unregister all existing shortcuts globalShortcut.unregisterAll(); - let toggleVisibilityDebounceTimer = null; - + if (sendToRenderer) { + sendToRenderer('shortcuts-updated', keybinds); + console.log('[Shortcuts] Broadcasted updated shortcuts to all windows.'); + } + + // ✨ 하드코딩된 단축키 등록을 위해 변수 유지 const isMac = process.platform === 'darwin'; const modifier = isMac ? 'Cmd' : 'Ctrl'; + const header = windowPool.get('header'); + const state = header?.currentHeaderState || currentHeaderState; - if (keybinds.toggleVisibility) { - try { - globalShortcut.register(keybinds.toggleVisibility, () => toggleAllWindowsVisibility(movementManager)); - console.log(`Registered toggleVisibility: ${keybinds.toggleVisibility}`); - } catch (error) { - console.error(`Failed to register toggleVisibility (${keybinds.toggleVisibility}):`, error); - } - } - + // ✨ 기능 1: 사용자가 설정할 수 없는 '모니터 이동' 단축키 (기존 로직 유지) const displays = screen.getAllDisplays(); if (displays.length > 1) { displays.forEach((display, index) => { const key = `${modifier}+Shift+${index + 1}`; try { - globalShortcut.register(key, () => { - movementManager.moveToDisplay(display.id); - }); + globalShortcut.register(key, () => movementManager.moveToDisplay(display.id)); console.log(`Registered display switch shortcut: ${key} -> Display ${index + 1}`); } catch (error) { console.error(`Failed to register display switch ${key}:`, error); @@ -1313,171 +1336,122 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan }); } - if (currentHeaderState === 'apikey') { + // API 키 입력 상태에서는 필수 단축키(toggleVisibility) 외에는 아무것도 등록하지 않음 + if (state === 'apikey') { + if (keybinds.toggleVisibility) { + try { + globalShortcut.register(keybinds.toggleVisibility, () => toggleAllWindowsVisibility(movementManager)); + } catch (error) { + console.error(`Failed to register toggleVisibility (${keybinds.toggleVisibility}):`, error); + } + } console.log('ApiKeyHeader is active, skipping conditional shortcuts'); return; } - const directions = [ - { key: `${modifier}+Left`, direction: 'left' }, - { key: `${modifier}+Right`, direction: 'right' }, - { key: `${modifier}+Up`, direction: 'up' }, - { key: `${modifier}+Down`, direction: 'down' }, - ]; - - directions.forEach(({ key, direction }) => { - try { - globalShortcut.register(key, () => { - const header = windowPool.get('header'); - if (header && header.isVisible()) { - movementManager.moveStep(direction); - } - }); - // console.log(`Registered global shortcut: ${key} -> ${direction}`); - } catch (error) { - console.error(`Failed to register ${key}:`, error); - } - }); - + // ✨ 기능 2: 사용자가 설정할 수 없는 '화면 가장자리 이동' 단축키 (기존 로직 유지) const edgeDirections = [ { key: `${modifier}+Shift+Left`, direction: 'left' }, { key: `${modifier}+Shift+Right`, direction: 'right' }, - { key: `${modifier}+Shift+Up`, direction: 'up' }, - { key: `${modifier}+Shift+Down`, direction: 'down' }, + // { key: `${modifier}+Shift+Up`, direction: 'up' }, + // { key: `${modifier}+Shift+Down`, direction: 'down' }, ]; - edgeDirections.forEach(({ key, direction }) => { try { globalShortcut.register(key, () => { - const header = windowPool.get('header'); - if (header && header.isVisible()) { - movementManager.moveToEdge(direction); - } + if (header && header.isVisible()) movementManager.moveToEdge(direction); }); - console.log(`Registered global shortcut: ${key} -> edge ${direction}`); } catch (error) { - console.error(`Failed to register ${key}:`, error); + console.error(`Failed to register edge move for ${key}:`, error); } }); - if (keybinds.toggleClickThrough) { + + // ✨ 기능 3: 사용자가 설정 가능한 모든 단축키를 동적으로 등록 (새로운 방식 적용) + for (const action in keybinds) { + const accelerator = keybinds[action]; + if (!accelerator) continue; + try { - globalShortcut.register(keybinds.toggleClickThrough, () => { - mouseEventsIgnored = !mouseEventsIgnored; - if (mouseEventsIgnored) { - mainWindow.setIgnoreMouseEvents(true, { forward: true }); - console.log('Mouse events ignored'); - } else { - mainWindow.setIgnoreMouseEvents(false); - console.log('Mouse events enabled'); - } - mainWindow.webContents.send('click-through-toggled', mouseEventsIgnored); - }); - // console.log(`Registered toggleClickThrough: ${keybinds.toggleClickThrough}`); - } catch (error) { - console.error(`Failed to register toggleClickThrough (${keybinds.toggleClickThrough}):`, error); - } - } - - if (keybinds.nextStep) { - try { - globalShortcut.register(keybinds.nextStep, () => { - console.log('⌘/Ctrl+Enter Ask shortcut triggered'); - - const askWindow = windowPool.get('ask'); - if (!askWindow || askWindow.isDestroyed()) { - console.error('Ask window not found or destroyed'); - return; - } - - if (askWindow.isVisible()) { - askWindow.webContents.send('ask-global-send'); - } else { - try { - askWindow.show(); - - const header = windowPool.get('header'); - if (header) { - const currentHeaderPosition = header.getBounds(); + let callback; + switch(action) { + case 'toggleVisibility': + callback = () => toggleAllWindowsVisibility(movementManager); + break; + case 'nextStep': + callback = () => { + const askWindow = windowPool.get('ask'); + if (!askWindow || askWindow.isDestroyed()) return; + if (askWindow.isVisible()) { + askWindow.webContents.send('ask-global-send'); + } else { + askWindow.show(); updateLayout(); - header.setPosition(currentHeaderPosition.x, currentHeaderPosition.y, false); + askWindow.webContents.send('window-show-animation'); } - - askWindow.webContents.send('window-show-animation'); - } catch (e) { - console.error('Error showing Ask window:', e); - } - } - }); - // console.log(`Registered Ask shortcut (nextStep): ${keybinds.nextStep}`); - } catch (error) { - console.error(`Failed to register Ask shortcut (${keybinds.nextStep}):`, error); - } - } - - if (keybinds.manualScreenshot) { - try { - globalShortcut.register(keybinds.manualScreenshot, () => { - console.log('Manual screenshot shortcut triggered'); - mainWindow.webContents.executeJavaScript(` - if (window.captureManualScreenshot) { - window.captureManualScreenshot(); - } else { - console.log('Manual screenshot function not available'); - } - `); - }); - // console.log(`Registered manualScreenshot: ${keybinds.manualScreenshot}`); - } catch (error) { - console.error(`Failed to register manualScreenshot (${keybinds.manualScreenshot}):`, error); - } - } - - if (keybinds.previousResponse) { - try { - globalShortcut.register(keybinds.previousResponse, () => { - console.log('Previous response shortcut triggered'); - sendToRenderer('navigate-previous-response'); - }); - // console.log(`Registered previousResponse: ${keybinds.previousResponse}`); - } catch (error) { - console.error(`Failed to register previousResponse (${keybinds.previousResponse}):`, error); - } - } - - if (keybinds.nextResponse) { - try { - globalShortcut.register(keybinds.nextResponse, () => { - console.log('Next response shortcut triggered'); - sendToRenderer('navigate-next-response'); - }); - // console.log(`Registered nextResponse: ${keybinds.nextResponse}`); - } catch (error) { - console.error(`Failed to register nextResponse (${keybinds.nextResponse}):`, error); - } - } - - if (keybinds.scrollUp) { - try { - globalShortcut.register(keybinds.scrollUp, () => { - console.log('Scroll up shortcut triggered'); - sendToRenderer('scroll-response-up'); - }); - // console.log(`Registered scrollUp: ${keybinds.scrollUp}`); - } catch (error) { - console.error(`Failed to register scrollUp (${keybinds.scrollUp}):`, error); - } - } - - if (keybinds.scrollDown) { - try { - globalShortcut.register(keybinds.scrollDown, () => { - console.log('Scroll down shortcut triggered'); - sendToRenderer('scroll-response-down'); - }); - // console.log(`Registered scrollDown: ${keybinds.scrollDown}`); - } catch (error) { - console.error(`Failed to register scrollDown (${keybinds.scrollDown}):`, error); + }; + break; + case 'scrollUp': + callback = () => { + // 'ask' 창을 명시적으로 가져옵니다. + const askWindow = windowPool.get('ask'); + // 'ask' 창이 존재하고, 파괴되지 않았으며, 보이는 경우에만 이벤트를 전송합니다. + if (askWindow && !askWindow.isDestroyed() && askWindow.isVisible()) { + askWindow.webContents.send('scroll-response-up'); + } + }; + break; + case 'scrollDown': + callback = () => { + // 'ask' 창을 명시적으로 가져옵니다. + const askWindow = windowPool.get('ask'); + // 'ask' 창이 존재하고, 파괴되지 않았으며, 보이는 경우에만 이벤트를 전송합니다. + if (askWindow && !askWindow.isDestroyed() && askWindow.isVisible()) { + askWindow.webContents.send('scroll-response-down'); + } + }; + break; + case 'moveUp': + callback = () => { if (header && header.isVisible()) movementManager.moveStep('up'); }; + break; + case 'moveDown': + callback = () => { if (header && header.isVisible()) movementManager.moveStep('down'); }; + break; + case 'moveLeft': + callback = () => { if (header && header.isVisible()) movementManager.moveStep('left'); }; + break; + case 'moveRight': + callback = () => { if (header && header.isVisible()) movementManager.moveStep('right'); }; + break; + case 'toggleClickThrough': + callback = () => { + mouseEventsIgnored = !mouseEventsIgnored; + if(mainWindow && !mainWindow.isDestroyed()){ + mainWindow.setIgnoreMouseEvents(mouseEventsIgnored, { forward: true }); + mainWindow.webContents.send('click-through-toggled', mouseEventsIgnored); + } + }; + break; + case 'manualScreenshot': + callback = () => { + if(mainWindow && !mainWindow.isDestroyed()) { + mainWindow.webContents.executeJavaScript('window.captureManualScreenshot && window.captureManualScreenshot();'); + } + }; + break; + case 'previousResponse': + callback = () => sendToRenderer('navigate-previous-response'); + break; + case 'nextResponse': + callback = () => sendToRenderer('navigate-next-response'); + break; + } + + if (callback) { + globalShortcut.register(accelerator, callback); + } + } catch(e) { + console.error(`Failed to register shortcut for "${action}" (${accelerator}):`, e.message); } } } diff --git a/src/features/ask/AskView.js b/src/features/ask/AskView.js index 33cb43c..ee0c153 100644 --- a/src/features/ask/AskView.js +++ b/src/features/ask/AskView.js @@ -658,6 +658,8 @@ export class AskView extends LitElement { this.handleDocumentClick = this.handleDocumentClick.bind(this); this.handleWindowBlur = this.handleWindowBlur.bind(this); + this.handleScroll = this.handleScroll.bind(this); + this.loadLibraries(); // --- Resize helpers --- @@ -863,6 +865,9 @@ export class AskView extends LitElement { ipcRenderer.on('ask-response-chunk', this.handleStreamChunk); ipcRenderer.on('ask-response-stream-end', this.handleStreamEnd); + + ipcRenderer.on('scroll-response-up', () => this.handleScroll('up')); + ipcRenderer.on('scroll-response-down', () => this.handleScroll('down')); console.log('✅ AskView: IPC 이벤트 리스너 등록 완료'); } } @@ -901,9 +906,24 @@ export class AskView extends LitElement { ipcRenderer.removeListener('ask-response-chunk', this.handleStreamChunk); ipcRenderer.removeListener('ask-response-stream-end', this.handleStreamEnd); + + ipcRenderer.removeListener('scroll-response-up', () => this.handleScroll('up')); + ipcRenderer.removeListener('scroll-response-down', () => this.handleScroll('down')); console.log('✅ AskView: IPC 이벤트 리스너 제거 완료'); } } + + handleScroll(direction) { + const scrollableElement = this.shadowRoot.querySelector('#responseContainer'); + if (scrollableElement) { + const scrollAmount = 100; // 한 번에 스크롤할 양 (px) + if (direction === 'up') { + scrollableElement.scrollTop -= scrollAmount; + } else { + scrollableElement.scrollTop += scrollAmount; + } + } + } // --- 스트리밍 처리 핸들러 --- handleStreamChunk(event, { token }) { diff --git a/src/features/settings/SettingsView.js b/src/features/settings/SettingsView.js index d78703c..7dbd9f1 100644 --- a/src/features/settings/SettingsView.js +++ b/src/features/settings/SettingsView.js @@ -437,22 +437,10 @@ export class SettingsView extends LitElement { } `; - //////// before_modelStateService //////// - // static properties = { - // firebaseUser: { type: Object, state: true }, - // apiKey: { type: String, state: true }, - // isLoading: { type: Boolean, state: true }, - // isContentProtectionOn: { type: Boolean, state: true }, - // settings: { type: Object, state: true }, - // presets: { type: Array, state: true }, - // selectedPreset: { type: Object, state: true }, - // showPresets: { type: Boolean, state: true }, - // saving: { type: Boolean, state: true }, - // }; - //////// before_modelStateService //////// //////// after_modelStateService //////// static properties = { + shortcuts: { type: Object, state: true }, firebaseUser: { type: Object, state: true }, isLoading: { type: Boolean, state: true }, isContentProtectionOn: { type: Boolean, state: true }, @@ -473,20 +461,8 @@ export class SettingsView extends LitElement { constructor() { super(); - //////// before_modelStateService //////// - // this.firebaseUser = null; - // this.apiKey = null; - // this.isLoading = false; - // this.isContentProtectionOn = true; - // this.settings = null; - // this.presets = []; - // this.selectedPreset = null; - // this.showPresets = false; - // this.saving = false; - // this.loadInitialData(); - //////// before_modelStateService //////// - //////// after_modelStateService //////// + this.shortcuts = {}; this.firebaseUser = null; this.apiKeys = { openai: '', gemini: '', anthropic: '' }; this.providerConfig = {}; @@ -507,55 +483,13 @@ export class SettingsView extends LitElement { //////// after_modelStateService //////// } - - //////// before_modelStateService //////// - // async loadInitialData() { - // if (!window.require) return; - - // try { - // this.isLoading = true; - // const { ipcRenderer } = window.require('electron'); - - // // Load all data in parallel - // const [settings, presets, apiKey, contentProtection, userState] = await Promise.all([ - // ipcRenderer.invoke('settings:getSettings'), - // ipcRenderer.invoke('settings:getPresets'), - // ipcRenderer.invoke('get-stored-api-key'), - // ipcRenderer.invoke('get-content-protection-status'), - // ipcRenderer.invoke('get-current-user') - // ]); - - // this.settings = settings; - // this.presets = presets || []; - // this.apiKey = apiKey; - // this.isContentProtectionOn = contentProtection; - - // // Set first user preset as selected - // if (this.presets.length > 0) { - // const firstUserPreset = this.presets.find(p => p.is_default === 0); - // if (firstUserPreset) { - // this.selectedPreset = firstUserPreset; - // } - // } - - // if (userState && userState.isLoggedIn) { - // this.firebaseUser = userState.user; - // } - // } catch (error) { - // console.error('Error loading initial data:', error); - // } finally { - // this.isLoading = false; - // } - // } - //////// before_modelStateService //////// - //////// after_modelStateService //////// async loadInitialData() { if (!window.require) return; this.isLoading = true; const { ipcRenderer } = window.require('electron'); try { - const [userState, config, storedKeys, availableLlm, availableStt, selectedModels, presets, contentProtection] = await Promise.all([ + const [userState, config, storedKeys, availableLlm, availableStt, selectedModels, presets, contentProtection, shortcuts] = await Promise.all([ ipcRenderer.invoke('get-current-user'), ipcRenderer.invoke('model:get-provider-config'), // Provider 설정 로드 ipcRenderer.invoke('model:get-all-keys'), @@ -563,7 +497,8 @@ export class SettingsView extends LitElement { ipcRenderer.invoke('model:get-available-models', { type: 'stt' }), ipcRenderer.invoke('model:get-selected-models'), ipcRenderer.invoke('settings:getPresets'), - ipcRenderer.invoke('get-content-protection-status') + ipcRenderer.invoke('get-content-protection-status'), + ipcRenderer.invoke('get-current-shortcuts') ]); if (userState && userState.isLoggedIn) this.firebaseUser = userState; @@ -575,6 +510,7 @@ export class SettingsView extends LitElement { this.selectedStt = selectedModels.stt; this.presets = presets || []; this.isContentProtectionOn = contentProtection; + this.shortcuts = shortcuts || {}; if (this.presets.length > 0) { const firstUserPreset = this.presets.find(p => p.is_default === 0); if (firstUserPreset) this.selectedPreset = firstUserPreset; @@ -668,6 +604,13 @@ export class SettingsView extends LitElement { } //////// after_modelStateService //////// + openShortcutEditor() { + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.invoke('open-shortcut-editor'); + } + } + connectedCallback() { super.connectedCallback(); @@ -732,10 +675,15 @@ export class SettingsView extends LitElement { console.error('[SettingsView] Failed to refresh presets:', error); } }; + this._shortcutListener = (event, keybinds) => { + console.log('[SettingsView] Received updated shortcuts:', keybinds); + this.shortcuts = keybinds; + }; ipcRenderer.on('user-state-changed', this._userStateListener); ipcRenderer.on('settings-updated', this._settingsUpdatedListener); ipcRenderer.on('presets-updated', this._presetsUpdatedListener); + ipcRenderer.on('shortcuts-updated', this._shortcutListener); } cleanupIpcListeners() { @@ -752,6 +700,9 @@ export class SettingsView extends LitElement { if (this._presetsUpdatedListener) { ipcRenderer.removeListener('presets-updated', this._presetsUpdatedListener); } + if (this._shortcutListener) { + ipcRenderer.removeListener('shortcuts-updated', this._shortcutListener); + } } setupWindowResize() { @@ -797,14 +748,41 @@ export class SettingsView extends LitElement { } } + // getMainShortcuts() { + // return [ + // { name: 'Show / Hide', key: '\\' }, + // { name: 'Ask Anything', key: '↵' }, + // { name: 'Scroll AI Response', key: '↕' } + // ]; + // } getMainShortcuts() { return [ - { name: 'Show / Hide', key: '\\' }, - { name: 'Ask Anything', key: '↵' }, - { name: 'Scroll AI Response', key: '↕' } + { name: 'Show / Hide', accelerator: this.shortcuts.toggleVisibility }, + { name: 'Ask Anything', accelerator: this.shortcuts.nextStep }, + { name: 'Scroll Up Response', accelerator: this.shortcuts.scrollUp }, + { name: 'Scroll Down Response', accelerator: this.shortcuts.scrollDown }, ]; } + renderShortcutKeys(accelerator) { + if (!accelerator) return html`N/A`; + + const keyMap = { + 'Cmd': '⌘', 'Command': '⌘', 'Ctrl': '⌃', 'Alt': '⌥', 'Shift': '⇧', 'Enter': '↵', + 'Up': '↑', 'Down': '↓', 'Left': '←', 'Right': '→' + }; + + // scrollDown/scrollUp의 특수 처리 + if (accelerator.includes('↕')) { + const keys = accelerator.replace('↕','').split('+'); + keys.push('↕'); + return html`${keys.map(key => html`${keyMap[key] || key}`)}`; + } + + const keys = accelerator.split('+'); + return html`${keys.map(key => html`${keyMap[key] || key}`)}`; + } + togglePresets() { this.showPresets = !this.showPresets; } @@ -1131,14 +1109,20 @@ export class SettingsView extends LitElement { ${apiKeyManagementHTML} ${modelSelectionHTML} + +
+ +
+
${this.getMainShortcuts().map(shortcut => html`
${shortcut.name}
- - ${shortcut.key} + ${this.renderShortcutKeys(shortcut.accelerator)}
`)} diff --git a/src/features/settings/ShortCutSettingsView.js b/src/features/settings/ShortCutSettingsView.js new file mode 100644 index 0000000..aac45e4 --- /dev/null +++ b/src/features/settings/ShortCutSettingsView.js @@ -0,0 +1,235 @@ +import { html, css, LitElement } from '../../assets/lit-core-2.7.4.min.js'; + +const commonSystemShortcuts = new Set([ + 'Cmd+Q', 'Cmd+W', 'Cmd+A', 'Cmd+S', 'Cmd+Z', 'Cmd+X', 'Cmd+C', 'Cmd+V', 'Cmd+P', 'Cmd+F', 'Cmd+G', 'Cmd+H', 'Cmd+M', 'Cmd+N', 'Cmd+O', 'Cmd+T', + 'Ctrl+Q', 'Ctrl+W', 'Ctrl+A', 'Ctrl+S', 'Ctrl+Z', 'Ctrl+X', 'Ctrl+C', 'Ctrl+V', 'Ctrl+P', 'Ctrl+F', 'Ctrl+G', 'Ctrl+H', 'Ctrl+M', 'Ctrl+N', 'Ctrl+O', 'Ctrl+T' +]); + +const displayNameMap = { + nextStep: 'Ask Anything', + moveUp: 'Move Up Window', + moveDown: 'Move Down Window', + scrollUp: 'Scroll Up Response', + scrollDown: 'Scroll Down Response', + }; + +export class ShortcutSettingsView extends LitElement { + static styles = css` + * { font-family:'Helvetica Neue',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; + cursor:default; user-select:none; box-sizing:border-box; } + + :host { display:flex; width:100%; height:100%; color:white; } + + .container { display:flex; flex-direction:column; height:100%; + background:rgba(20,20,20,.9); border-radius:12px; + outline:.5px rgba(255,255,255,.2) solid; outline-offset:-1px; + position:relative; overflow:hidden; padding:12px; } + + .close-button{position:absolute;top:10px;right:10px;inline-size:14px;block-size:14px; + background:rgba(255,255,255,.1);border:none;border-radius:3px; + color:rgba(255,255,255,.7);display:grid;place-items:center; + font-size:14px;line-height:0;cursor:pointer;transition:.15s;z-index:10;} + .close-button:hover{background:rgba(255,255,255,.2);color:rgba(255,255,255,.9);} + + .title{font-size:14px;font-weight:500;margin:0 0 8px;padding-bottom:8px; + border-bottom:1px solid rgba(255,255,255,.1);text-align:center;} + + .scroll-area{flex:1 1 auto;overflow-y:auto;margin:0 -4px;padding:4px;} + + .shortcut-entry{display:flex;align-items:center;width:100%;gap:8px; + margin-bottom:8px;font-size:12px;padding:4px;} + .shortcut-name{flex:1 1 auto;color:rgba(255,255,255,.9);font-weight:300; + white-space:nowrap;overflow:hidden;text-overflow:ellipsis;} + + .action-btn{background:none;border:none;color:rgba(0,122,255,.8); + font-size:11px;padding:0 4px;cursor:pointer;transition:.15s;} + .action-btn:hover{color:#0a84ff;text-decoration:underline;} + + .shortcut-input{inline-size:120px;background:rgba(0,0,0,.2); + border:1px solid rgba(255,255,255,.2);border-radius:4px; + padding:4px 6px;font:11px 'SF Mono','Menlo',monospace; + color:white;text-align:right;cursor:text;margin-left:auto;} + .shortcut-input:focus,.shortcut-input.capturing{ + outline:none;border-color:rgba(0,122,255,.6); + box-shadow:0 0 0 1px rgba(0,122,255,.3);} + + .feedback{font-size:10px;margin-top:2px;min-height:12px;} + .feedback.error{color:#ef4444;} + .feedback.success{color:#22c55e;} + + .actions{display:flex;gap:4px;padding-top:8px;border-top:1px solid rgba(255,255,255,.1);} + .settings-button{flex:1;background:rgba(255,255,255,.1); + border:1px solid rgba(255,255,255,.2);border-radius:4px; + color:white;padding:5px 10px;font-size:11px;cursor:pointer;transition:.15s;} + .settings-button:hover{background:rgba(255,255,255,.15);} + .settings-button.primary{background:rgba(0,122,255,.25);border-color:rgba(0,122,255,.6);} + .settings-button.primary:hover{background:rgba(0,122,255,.35);} + .settings-button.danger{background:rgba(255,59,48,.1);border-color:rgba(255,59,48,.3); + color:rgba(255,59,48,.9);} + .settings-button.danger:hover{background:rgba(255,59,48,.15);} + `; + + static properties = { + shortcuts: { type: Object, state: true }, + isLoading: { type: Boolean, state: true }, + capturingKey: { type: String, state: true }, + feedback: { type:Object, state:true } + }; + + constructor() { + super(); + this.shortcuts = {}; + this.feedback = {}; + this.isLoading = true; + this.capturingKey = null; + this.ipcRenderer = window.require ? window.require('electron').ipcRenderer : null; + } + + connectedCallback() { + super.connectedCallback(); + if (!this.ipcRenderer) return; + this.loadShortcutsHandler = (event, keybinds) => { + this.shortcuts = keybinds; + this.isLoading = false; + }; + this.ipcRenderer.on('load-shortcuts', this.loadShortcutsHandler); + } + + disconnectedCallback() { + super.disconnectedCallback(); + if (this.ipcRenderer && this.loadShortcutsHandler) { + this.ipcRenderer.removeListener('load-shortcuts', this.loadShortcutsHandler); + } + } + + handleKeydown(e, shortcutKey){ + e.preventDefault(); e.stopPropagation(); + const result = this._parseAccelerator(e); + if(!result) return; // modifier키만 누른 상태 + + const {accel, error} = result; + if(error){ + this.feedback = {...this.feedback, [shortcutKey]:{type:'error',msg:error}}; + return; + } + // 성공 + this.shortcuts = {...this.shortcuts, [shortcutKey]:accel}; + this.feedback = {...this.feedback, [shortcutKey]:{type:'success',msg:'Shortcut set'}}; + this.stopCapture(); + } + + _parseAccelerator(e){ + /* returns {accel?, error?} */ + const parts=[]; if(e.metaKey) parts.push('Cmd'); + if(e.ctrlKey) parts.push('Ctrl'); + if(e.altKey) parts.push('Alt'); + if(e.shiftKey) parts.push('Shift'); + + const isModifier=['Meta','Control','Alt','Shift'].includes(e.key); + if(isModifier) return null; + + const map={ArrowUp:'Up',ArrowDown:'Down',ArrowLeft:'Left',ArrowRight:'Right',' ':'Space'}; + parts.push(e.key.length===1? e.key.toUpperCase() : (map[e.key]||e.key)); + const accel=parts.join('+'); + + /* ---- validation ---- */ + if(parts.length===1) return {error:'Invalid shortcut: needs a modifier'}; + if(parts.length>4) return {error:'Invalid shortcut: max 4 keys'}; + if(commonSystemShortcuts.has(accel)) return {error:'Invalid shortcut: system reserved'}; + return {accel}; + } + + startCapture(key){ this.capturingKey = key; this.feedback = {...this.feedback, [key]:undefined}; } + + disableShortcut(key){ + this.shortcuts = {...this.shortcuts, [key]:''}; // 공백 => 작동 X + this.feedback = {...this.feedback, [key]:{type:'success',msg:'Shortcut disabled'}}; + } + + stopCapture() { + this.capturingKey = null; + } + + async handleSave() { + if (!this.ipcRenderer) return; + const result = await this.ipcRenderer.invoke('save-shortcuts', this.shortcuts); + if (!result.success) { + alert('Failed to save shortcuts: ' + result.error); + } + } + + handleClose() { + if (!this.ipcRenderer) return; + this.ipcRenderer.send('close-shortcut-editor'); + } + + async handleResetToDefault() { + if (!this.ipcRenderer) return; + const confirmation = confirm("Are you sure you want to reset all shortcuts to their default values?"); + if (!confirmation) return; + + try { + const defaultShortcuts = await this.ipcRenderer.invoke('get-default-shortcuts'); + this.shortcuts = defaultShortcuts; + } catch (error) { + alert('Failed to load default settings.'); + } + } + + formatShortcutName(name) { + if (displayNameMap[name]) { + return displayNameMap[name]; + } + const result = name.replace(/([A-Z])/g, " $1"); + return result.charAt(0).toUpperCase() + result.slice(1); + } + + render(){ + if(this.isLoading){ + return html`
Loading Shortcuts...
`; + } + return html` +
+ +

Edit Shortcuts

+ +
+ ${Object.keys(this.shortcuts).map(key=>html` +
+
+ ${this.formatShortcutName(key)} + + + + + + this.startCapture(key)} + @keydown=${e=>this.handleKeydown(e,key)} + @blur=${()=>this.stopCapture()} + /> +
+ + ${this.feedback[key] ? html` + ` : html`` + } +
+ `)} +
+ +
+ + + +
+
+ `; + } + } + +customElements.define('shortcut-settings-view', ShortcutSettingsView); \ No newline at end of file From 18cb1e0efdf03c13808c6fa2bfe24aa5fe5493af Mon Sep 17 00:00:00 2001 From: sanio Date: Tue, 8 Jul 2025 21:57:23 +0900 Subject: [PATCH 48/52] fix api key store error --- src/common/services/modelStateService.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common/services/modelStateService.js b/src/common/services/modelStateService.js index 33de127..7218ce7 100644 --- a/src/common/services/modelStateService.js +++ b/src/common/services/modelStateService.js @@ -67,6 +67,11 @@ class ModelStateService { }; this.state = this.store.get(`users.${userId}`, defaultState); console.log(`[ModelStateService] State loaded for user: ${userId}`); + for (const p of Object.keys(PROVIDERS)) { + if (!(p in this.state.apiKeys)) { + this.state.apiKeys[p] = null; + } + } this._autoSelectAvailableModels(); this._saveState(); this._logCurrentSelection(); From 2ba95ece928b12600673158653eaf7f75102e783 Mon Sep 17 00:00:00 2001 From: samtiz Date: Tue, 8 Jul 2025 22:21:23 +0900 Subject: [PATCH 49/52] update README.md --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 8b84994..e5510e2 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,6 @@ > This project is a fork of [CheatingDaddy](https://github.com/sohzm/cheating-daddy) with modifications and enhancements. Thanks to [Soham](https://x.com/soham_btw) and all the open-source contributors who made this possible! -> Currently, we're working on a full code refactor and modularization. Once that's completed, we'll jump into addressing the major issues. You can find WIP issues & changelog below this document. - 🤖 **Fast, light & open-source**—Glass lives on your desktop, sees what you see, listens in real time, understands your context, and turns every moment into structured knowledge. 💬 **Proactive in meetings**—it surfaces action items, summaries, and answers the instant you need them. @@ -117,9 +115,7 @@ We have a list of [help wanted](https://github.com/pickle-com/glass/issues?q=is% | Status | Issue | Description | |--------|--------------------------------|---------------------------------------------------| -| 🚧 WIP | Windows Build | Make Glass buildable & runnable in Windows | | 🚧 WIP | Local LLM Support | Supporting Local LLM to power AI answers | -| 🚧 WIP | AEC Improvement | Transcription is not working occasionally | | 🚧 WIP | Firebase Data Storage Issue | Session & ask should be saved in firebase for signup users | | 🚧 WIP | Liquid Glass | Liquid Glass UI for MacOS 26 | From e267026a22046a242834fda1d5fc77680f0fba61 Mon Sep 17 00:00:00 2001 From: sanio <151643051+entry-sanio@users.noreply.github.com> Date: Tue, 8 Jul 2025 22:32:36 +0900 Subject: [PATCH 50/52] Revert "Fix : Gemini JSON Format Answer fixed to plain Text answer" From 194507cb50fa4c3b1b79ea74c0588471143273ae Mon Sep 17 00:00:00 2001 From: sanio <151643051+entry-sanio@users.noreply.github.com> Date: Tue, 8 Jul 2025 22:42:08 +0900 Subject: [PATCH 51/52] Revert "Revert "Fix : Gemini JSON Format Answer fixed to plain Text answer"" From 9977387fbc50a0ce6528d83e0899b55c9c082c97 Mon Sep 17 00:00:00 2001 From: samtiz Date: Wed, 9 Jul 2025 00:19:46 +0900 Subject: [PATCH 52/52] stt UI fix + more responsibility --- src/common/ai/providers/openai.js | 6 +- src/features/listen/stt/sttService.js | 150 ++++++++++++-------------- 2 files changed, 71 insertions(+), 85 deletions(-) diff --git a/src/common/ai/providers/openai.js b/src/common/ai/providers/openai.js index 7ede760..79b1ef3 100644 --- a/src/common/ai/providers/openai.js +++ b/src/common/ai/providers/openai.js @@ -48,11 +48,11 @@ async function createSTT({ apiKey, language = 'en', callbacks = {}, usePortkey = turn_detection: { type: 'server_vad', threshold: 0.5, - prefix_padding_ms: 50, - silence_duration_ms: 25, + prefix_padding_ms: 200, + silence_duration_ms: 100, }, input_audio_noise_reduction: { - type: 'near_field' + type: 'far_field' } } }; diff --git a/src/features/listen/stt/sttService.js b/src/features/listen/stt/sttService.js index d48dd62..187f76e 100644 --- a/src/features/listen/stt/sttService.js +++ b/src/features/listen/stt/sttService.js @@ -12,11 +12,6 @@ class SttService { this.myCurrentUtterance = ''; this.theirCurrentUtterance = ''; - this.myLastPartialText = ''; - this.theirLastPartialText = ''; - this.myInactivityTimer = null; - this.theirInactivityTimer = null; - // Turn-completion debouncing this.myCompletionBuffer = ''; this.theirCompletionBuffer = ''; @@ -38,33 +33,6 @@ class SttService { this.onStatusUpdate = onStatusUpdate; } - // async getApiKey() { - // const storedKey = await getStoredApiKey(); - // if (storedKey) { - // console.log('[SttService] Using stored API key'); - // return storedKey; - // } - - // const envKey = process.env.OPENAI_API_KEY; - // if (envKey) { - // console.log('[SttService] Using environment API key'); - // return envKey; - // } - - // console.error('[SttService] No API key found in storage or environment'); - // return null; - // } - - // async getAiProvider() { - // try { - // const { ipcRenderer } = require('electron'); - // const provider = await ipcRenderer.invoke('get-ai-provider'); - // return provider || 'openai'; - // } catch (error) { - // return getStoredProvider ? getStoredProvider() : 'openai'; - // } - // } - sendToRenderer(channel, data) { BrowserWindow.getAllWindows().forEach(win => { if (!win.isDestroyed()) { @@ -74,10 +42,9 @@ class SttService { } flushMyCompletion() { - if (!this.modelInfo || !this.myCompletionBuffer.trim()) return; + const finalText = (this.myCompletionBuffer + this.myCurrentUtterance).trim(); + if (!this.modelInfo || !finalText) return; - const finalText = this.myCompletionBuffer.trim(); - // Notify completion callback if (this.onTranscriptionComplete) { this.onTranscriptionComplete('Me', finalText); @@ -102,9 +69,8 @@ class SttService { } flushTheirCompletion() { - if (!this.modelInfo || !this.theirCompletionBuffer.trim()) return; - - const finalText = this.theirCompletionBuffer.trim(); + const finalText = (this.theirCompletionBuffer + this.theirCurrentUtterance).trim(); + if (!this.modelInfo || !finalText) return; // Notify completion callback if (this.onTranscriptionComplete) { @@ -130,39 +96,29 @@ class SttService { } debounceMyCompletion(text) { - // 상대방이 말하고 있던 경우, 화자가 변경되었으므로 즉시 상대방의 말풍선을 완성합니다. - if (this.theirCompletionTimer) { - clearTimeout(this.theirCompletionTimer); - this.flushTheirCompletion(); + if (this.modelInfo?.provider === 'gemini') { + this.myCompletionBuffer += text; + } else { + this.myCompletionBuffer += (this.myCompletionBuffer ? ' ' : '') + text; } - this.myCompletionBuffer += (this.myCompletionBuffer ? ' ' : '') + text; - if (this.myCompletionTimer) clearTimeout(this.myCompletionTimer); this.myCompletionTimer = setTimeout(() => this.flushMyCompletion(), COMPLETION_DEBOUNCE_MS); } debounceTheirCompletion(text) { - // 내가 말하고 있던 경우, 화자가 변경되었으므로 즉시 내 말풍선을 완성합니다. - if (this.myCompletionTimer) { - clearTimeout(this.myCompletionTimer); - this.flushMyCompletion(); + if (this.modelInfo?.provider === 'gemini') { + this.theirCompletionBuffer += text; + } else { + this.theirCompletionBuffer += (this.theirCompletionBuffer ? ' ' : '') + text; } - this.theirCompletionBuffer += (this.theirCompletionBuffer ? ' ' : '') + text; - if (this.theirCompletionTimer) clearTimeout(this.theirCompletionTimer); this.theirCompletionTimer = setTimeout(() => this.flushTheirCompletion(), COMPLETION_DEBOUNCE_MS); } async initializeSttSessions(language = 'en') { const effectiveLanguage = process.env.OPENAI_TRANSCRIBE_LANG || language || 'en'; - - // const API_KEY = await this.getApiKey(); - // if (!API_KEY) { - // throw new Error('No API key available'); - // } - // const provider = await this.getAiProvider(); const modelInfo = await getCurrentModelInfo(null, { type: 'stt' }); if (!modelInfo || !modelInfo.apiKey) { @@ -171,10 +127,6 @@ class SttService { this.modelInfo = modelInfo; console.log(`[SttService] Initializing STT for ${modelInfo.provider} using model ${modelInfo.model}`); - - // const isGemini = modelInfo.provider === 'gemini'; - // console.log(`[SttService] Initializing STT for provider: ${modelInfo.provider}`); - const handleMyMessage = message => { if (!this.modelInfo) { console.log('[SttService] Ignoring message - session already closed'); @@ -182,13 +134,35 @@ class SttService { } if (this.modelInfo.provider === 'gemini') { - const text = message.serverContent?.inputTranscription?.text || ''; - if (text && text.trim()) { - const finalUtteranceText = text.trim().replace(//g, '').trim(); - if (finalUtteranceText && finalUtteranceText !== '.') { - this.debounceMyCompletion(finalUtteranceText); - } + if (!message.serverContent?.modelTurn) { + console.log('[Gemini STT - Me]', JSON.stringify(message, null, 2)); } + + if (message.serverContent?.turnComplete) { + if (this.myCompletionTimer) { + clearTimeout(this.myCompletionTimer); + this.flushMyCompletion(); + } + return; + } + + const transcription = message.serverContent?.inputTranscription; + if (!transcription || !transcription.text) return; + + const textChunk = transcription.text; + if (!textChunk.trim() || textChunk.trim() === '') { + return; // 1. Ignore whitespace-only chunks or noise + } + + this.debounceMyCompletion(textChunk); + + this.sendToRenderer('stt-update', { + speaker: 'Me', + text: this.myCompletionBuffer, + isPartial: true, + isFinal: false, + timestamp: Date.now(), + }); } else { const type = message.type; const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || ''; @@ -230,13 +204,35 @@ class SttService { } if (this.modelInfo.provider === 'gemini') { - const text = message.serverContent?.inputTranscription?.text || ''; - if (text && text.trim()) { - const finalUtteranceText = text.trim().replace(//g, '').trim(); - if (finalUtteranceText && finalUtteranceText !== '.') { - this.debounceTheirCompletion(finalUtteranceText); - } + if (!message.serverContent?.modelTurn) { + console.log('[Gemini STT - Them]', JSON.stringify(message, null, 2)); } + + if (message.serverContent?.turnComplete) { + if (this.theirCompletionTimer) { + clearTimeout(this.theirCompletionTimer); + this.flushTheirCompletion(); + } + return; + } + + const transcription = message.serverContent?.inputTranscription; + if (!transcription || !transcription.text) return; + + const textChunk = transcription.text; + if (!textChunk.trim() || textChunk.trim() === '') { + return; // 1. Ignore whitespace-only chunks or noise + } + + this.debounceTheirCompletion(textChunk); + + this.sendToRenderer('stt-update', { + speaker: 'Them', + text: this.theirCompletionBuffer, + isPartial: true, + isFinal: false, + timestamp: Date.now(), + }); } else { const type = message.type; const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || ''; @@ -496,14 +492,6 @@ class SttService { this.stopMacOSAudioCapture(); // Clear timers - if (this.myInactivityTimer) { - clearTimeout(this.myInactivityTimer); - this.myInactivityTimer = null; - } - if (this.theirInactivityTimer) { - clearTimeout(this.theirInactivityTimer); - this.theirInactivityTimer = null; - } if (this.myCompletionTimer) { clearTimeout(this.myCompletionTimer); this.myCompletionTimer = null; @@ -529,8 +517,6 @@ class SttService { // Reset state this.myCurrentUtterance = ''; this.theirCurrentUtterance = ''; - this.myLastPartialText = ''; - this.theirLastPartialText = ''; this.myCompletionBuffer = ''; this.theirCompletionBuffer = ''; this.modelInfo = null;