diff --git a/.github/workflows/pr-verification.yml b/.github/workflows/pr-verification.yml index 930ef5a..9dc7f60 100644 --- a/.github/workflows/pr-verification.yml +++ b/.github/workflows/pr-verification.yml @@ -1,18 +1,13 @@ name: PR Verification on: - push: - branches: ['**'] pull_request: jobs: build: - # run on the matrix platform runs-on: ${{ matrix.platform }} strategy: - # do not fail other matrix runs if one fails fail-fast: false - # set all platforms our test should run on matrix: platform: [windows-latest] timeout-minutes: 30 @@ -21,20 +16,6 @@ jobs: - name: Checkout uses: actions/checkout@v6 - - name: Tauri dependencies - if: matrix.platform == 'ubuntu-latest' - run: | - sudo apt-get update && - sudo apt-get install -y \ - libwebkit2gtk-4.1-dev \ - libayatana-appindicator3-dev \ - webkit2gtk-driver \ - xvfb - - - name: install WebDriver (Windows) - if: matrix.platform == 'windows-latest' - run: cargo install tauri-driver - - name: Setup Rust uses: dtolnay/rust-toolchain@stable with: @@ -72,12 +53,133 @@ jobs: - name: Run Clippy run: cargo clippy --manifest-path src-tauri/Cargo.toml --all-targets -- -D warnings - - name: Setup AppImage environment (Linux) - if: matrix.platform == 'ubuntu-latest' - run: | - sudo add-apt-repository universe - sudo apt-get update - sudo apt-get install -y libfuse2 - - name: Build app (Tauri, no bundle) run: pnpm run tauri build + + system-tests: + runs-on: windows-latest + timeout-minutes: 45 + needs: build + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + + - name: Rust cache + uses: swatinem/rust-cache@v2 + with: + workspaces: src-tauri + + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: 24 + + - name: Setup pnpm + uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c + with: + package_json_file: ./package.json + cache: true + cache_dependency_path: ./pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Install tauri-driver + run: cargo install tauri-driver --locked + + - name: Ensure Edge WebDriver is available + shell: pwsh + run: | + function Add-DriverToPath([string]$driverPath) { + $driverDir = Split-Path $driverPath -Parent + $driverDir | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + Write-Host "Using msedgedriver at: $driverPath" + } + + $existingDriver = Get-Command msedgedriver -ErrorAction SilentlyContinue + if ($existingDriver) { + Write-Host "msedgedriver already available on PATH." + msedgedriver --version + exit 0 + } + + $preinstalledCandidates = @( + "C:\SeleniumWebDrivers\EdgeDriver\msedgedriver.exe", + "C:\WebDriver\msedgedriver.exe" + ) + + foreach ($candidate in $preinstalledCandidates) { + if (Test-Path $candidate) { + Add-DriverToPath $candidate + exit 0 + } + } + + $edgeExe = "${env:ProgramFiles(x86)}\Microsoft\Edge\Application\msedge.exe" + if (-not (Test-Path $edgeExe)) { + $edgeExe = "${env:ProgramFiles}\Microsoft\Edge\Application\msedge.exe" + } + + if (-not (Test-Path $edgeExe)) { + throw "Could not find Microsoft Edge executable." + } + + $edgeVersion = (Get-Item $edgeExe).VersionInfo.ProductVersion + $majorVersion = $edgeVersion.Split('.')[0] + $driverDir = Join-Path $env:RUNNER_TEMP "msedgedriver" + New-Item -ItemType Directory -Path $driverDir -Force | Out-Null + $driverZipPath = Join-Path $driverDir "edgedriver.zip" + + $downloadHosts = @( + "https://msedgedriver.azureedge.net", + "https://msedgedriver.microsoft.com" + ) + + $downloaded = $false + $errors = @() + foreach ($host in $downloadHosts) { + try { + $latestReleaseUrl = "$host/LATEST_RELEASE_$majorVersion" + $driverVersion = (Invoke-WebRequest -Uri $latestReleaseUrl -UseBasicParsing).Content.Trim() + $driverZipUrl = "$host/$driverVersion/edgedriver_win64.zip" + + Invoke-WebRequest -Uri $driverZipUrl -OutFile $driverZipPath + Expand-Archive -Path $driverZipPath -DestinationPath $driverDir -Force + + $driverBinary = Join-Path $driverDir "msedgedriver.exe" + if (Test-Path $driverBinary) { + Add-DriverToPath $driverBinary + $downloaded = $true + break + } + } catch { + $errors += "${host}: $($_.Exception.Message)" + } + } + + if (-not $downloaded) { + throw "Unable to install msedgedriver. Attempts: $($errors -join ' | ')" + } + + - name: Verify Edge WebDriver + run: msedgedriver --version + + - name: Run system tests + env: + TAURI_TEST_KEEP_DATA: '1' + run: pnpm run test:system + + - name: Upload system test artifacts on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: system-test-artifacts-${{ github.run_id }} + path: | + .wdio-artifacts + .system-test-data + if-no-files-found: ignore + retention-days: 7 diff --git a/.gitignore b/.gitignore index caef659..4e3f5b7 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,5 @@ dist-ssr *.sw? scripts/ -.vs/ \ No newline at end of file +.vs/ +.system-test-data/ \ No newline at end of file diff --git a/README.md b/README.md index a492885..748d1df 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,53 @@ npm run tauri build pnpm run tauri:windows:build --arch "x64,arm64" --runner pnpm ``` +## System Test Mode + +For deterministic system-test runs, you can enable test mode: + +- `TAURI_TEST_MODE=1` enables deterministic import/export paths and test data isolation. +- `TAURI_TEST_RUN_ID` (optional) isolates each run into its own data subdirectory. +- `TAURI_TEST_EXPORT_PATH` and `TAURI_TEST_IMPORT_PATH` (optional) override deterministic file paths. + +Windows PowerShell example: + +```powershell +$env:TAURI_TEST_MODE = "1" +$env:TAURI_TEST_RUN_ID = "local-smoke" +pnpm run tauri dev +``` + +## System Tests (WebdriverIO + tauri-driver) + +Run the system suite: + +```bash +pnpm run test:system +``` + +By default, each run uses an isolated data folder and cleans it up when the suite finishes. + +Prerequisites: + +- Install `tauri-driver`: `cargo install tauri-driver --locked` +- On Windows, ensure `msedgedriver` is installed and version-matched to Edge + +Useful env overrides: + +- `TAURI_TEST_RUN_ID`: isolate each run's app data folder +- `TAURI_TEST_REUSE_RUN_ID=1`: reuse a fixed `TAURI_TEST_RUN_ID` across runs +- `TAURI_TEST_DATA_ROOT`: custom root folder for system-test data +- `TAURI_TEST_KEEP_DATA=1`: keep run data after test completion (no cleanup) +- `TAURI_DRIVER_PATH`: explicit path to `tauri-driver` +- `TAURI_TEST_EXPORT_PATH` / `TAURI_TEST_IMPORT_PATH`: deterministic transfer file paths + +Current automated scenarios (`e2e/specs/system.e2e.mjs`): + +- Smoke flow (create board + open/close settings) +- Board lifecycle (create, rename, duplicate) +- Board persistence across app restart (`browser.reloadSession`) +- Settings persistence across app restart (`browser.reloadSession`) + ## How It Works **Board Management**: The app stores board metadata and data in your system's app data directory diff --git a/e2e/helpers/board-ui.mjs b/e2e/helpers/board-ui.mjs new file mode 100644 index 0000000..74f5152 --- /dev/null +++ b/e2e/helpers/board-ui.mjs @@ -0,0 +1,133 @@ +const SELECTORS = { + createBoardInput: '[data-testid="create-board-input"]', + createBoardSubmit: '[data-testid="create-board-submit"]', + settingsOpenButton: '[data-testid="open-settings-btn"]', + settingsModal: '[data-testid="settings-modal"]', + settingsCloseButton: '[data-testid="close-settings-btn"]', + hideExportRowToggle: '[data-testid="toggle-hide-export-row"]', + boardActionRename: '[data-testid="board-action-rename"]', + boardActionDuplicate: '[data-testid="board-action-duplicate"]', +}; + +function boardNameXpath(name) { + return `//span[contains(@class, "board-name") and normalize-space()="${name}"]`; +} + +function boardMenuButtonXpath(name) { + return `//div[contains(@class, "board-item")][.//span[contains(@class, "board-name") and normalize-space()="${name}"]]//button[contains(@class, "menu-btn")]`; +} + +function boardItemXpath(name) { + return `//div[contains(@class, "board-item")][.//span[contains(@class, "board-name") and normalize-space()="${name}"]]`; +} + +export function uniqueBoardName(prefix) { + return `${prefix} ${Date.now().toString(36)}`; +} + +export async function waitForAppReady() { + const createBoardInput = await $(SELECTORS.createBoardInput); + await createBoardInput.waitForDisplayed({ timeout: 30000 }); +} + +export async function createBoard(name) { + const createBoardInput = await $(SELECTORS.createBoardInput); + await createBoardInput.waitForDisplayed({ timeout: 30000 }); + await createBoardInput.setValue(name); + + const createBoardSubmit = await $(SELECTORS.createBoardSubmit); + await createBoardSubmit.click(); + + await waitForBoardVisible(name); +} + +export async function waitForBoardVisible(name) { + const boardName = await $(boardNameXpath(name)); + await boardName.waitForDisplayed({ timeout: 10000 }); +} + +export async function openBoardMenu(name) { + const boardItem = await $(boardItemXpath(name)); + await boardItem.waitForDisplayed({ timeout: 10000 }); + await boardItem.moveTo(); + + const menuButton = await $(boardMenuButtonXpath(name)); + await menuButton.waitForClickable({ timeout: 10000 }); + await menuButton.click(); +} + +export async function renameBoard(currentName, nextName) { + await openBoardMenu(currentName); + + const renameAction = await $(SELECTORS.boardActionRename); + await renameAction.waitForDisplayed({ timeout: 10000 }); + await renameAction.click(); + + const editInput = await $('.edit-input'); + await editInput.waitForDisplayed({ timeout: 10000 }); + await editInput.clearValue(); + await editInput.setValue(nextName); + await browser.keys('Enter'); + + await waitForBoardVisible(nextName); +} + +export async function duplicateBoard(name) { + await openBoardMenu(name); + + const duplicateAction = await $(SELECTORS.boardActionDuplicate); + await duplicateAction.waitForDisplayed({ timeout: 10000 }); + await duplicateAction.click(); + + const duplicatedName = `${name} (Copy)`; + await waitForBoardVisible(duplicatedName); + return duplicatedName; +} + +export async function openSettings() { + const settingsButton = await $(SELECTORS.settingsOpenButton); + await settingsButton.waitForDisplayed({ timeout: 10000 }); + await settingsButton.click(); + + const settingsModal = await $(SELECTORS.settingsModal); + await settingsModal.waitForDisplayed({ timeout: 10000 }); +} + +export async function closeSettings() { + const closeButton = await $(SELECTORS.settingsCloseButton); + await closeButton.waitForDisplayed({ timeout: 10000 }); + await closeButton.click(); + + const settingsModal = await $(SELECTORS.settingsModal); + await settingsModal.waitForDisplayed({ reverse: true, timeout: 10000 }); +} + +export async function setHideExportRow(enabled) { + const toggle = await $(SELECTORS.hideExportRowToggle); + await toggle.waitForExist({ timeout: 10000 }); + + const selected = await toggle.isSelected(); + if (selected !== enabled) { + await browser.execute((element) => { + element.click(); + }, toggle); + } + + await browser.waitUntil(async () => (await toggle.isSelected()) === enabled, { + timeout: 10000, + timeoutMsg: `Hide export row toggle did not switch to ${enabled}.`, + }); +} + +export async function assertExportRowHidden() { + const exportRow = await $('.board-export-actions'); + const exists = await exportRow.isExisting(); + if (exists) { + throw new Error('Expected export row to be hidden, but it is visible.'); + } +} + +export async function restartAppSession() { + await browser.reloadSession(); + await waitForAppReady(); +} diff --git a/e2e/specs/system.e2e.mjs b/e2e/specs/system.e2e.mjs new file mode 100644 index 0000000..f16f415 --- /dev/null +++ b/e2e/specs/system.e2e.mjs @@ -0,0 +1,61 @@ +import { + assertExportRowHidden, + closeSettings, + createBoard, + duplicateBoard, + openSettings, + renameBoard, + restartAppSession, + setHideExportRow, + uniqueBoardName, + waitForAppReady, + waitForBoardVisible, +} from '../helpers/board-ui.mjs'; + +describe('System suite', () => { + it('smoke: creates a board and opens settings', async () => { + const boardName = uniqueBoardName('Smoke Board'); + + await createBoard(boardName); + await openSettings(); + await closeSettings(); + }); + + it('lifecycle: creates, renames, and duplicates a board', async () => { + const createdName = uniqueBoardName('Lifecycle Board'); + const renamedName = `${createdName} Renamed`; + + await createBoard(createdName); + await renameBoard(createdName, renamedName); + const duplicatedName = await duplicateBoard(renamedName); + + await waitForBoardVisible(renamedName); + await waitForBoardVisible(duplicatedName); + }); + + it('persistence: keeps created boards after app restart', async () => { + const boardName = uniqueBoardName('Persistence Board'); + const editedName = `${boardName} Edited`; + + await createBoard(boardName); + await renameBoard(boardName, editedName); + await restartAppSession(); + await waitForBoardVisible(editedName); + }); + + it('settings persistence: keeps hide export row after app restart', async () => { + await waitForAppReady(); + await openSettings(); + await setHideExportRow(true); + await closeSettings(); + + await assertExportRowHidden(); + + await restartAppSession(); + await assertExportRowHidden(); + + await openSettings(); + await setHideExportRow(false); + await closeSettings(); + }); +}); diff --git a/e2e/wdio.conf.mjs b/e2e/wdio.conf.mjs new file mode 100644 index 0000000..cebcabf --- /dev/null +++ b/e2e/wdio.conf.mjs @@ -0,0 +1,326 @@ +import fs from 'node:fs'; +import net from 'node:net'; +import os from 'node:os'; +import path from 'node:path'; +import { spawn, spawnSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; + +const __dirname = fileURLToPath(new URL('.', import.meta.url)); +const repoRoot = path.resolve(__dirname, '..'); +const tauriDriverPort = 4444; +const artifactsDir = path.resolve(repoRoot, '.wdio-artifacts'); + +const appBinaryName = process.platform === 'win32' ? 'excastoneboard.exe' : 'excastoneboard'; +const appBinaryPath = path.resolve(repoRoot, 'src-tauri', 'target', 'debug', appBinaryName); + +const defaultTauriDriverPath = path.resolve( + os.homedir(), + '.cargo', + 'bin', + process.platform === 'win32' ? 'tauri-driver.exe' : 'tauri-driver', +); + +const tauriDriverBinary = + process.env.TAURI_DRIVER_PATH || + (fs.existsSync(defaultTauriDriverPath) ? defaultTauriDriverPath : 'tauri-driver'); + +let tauriDriverProcess; +let tauriDriverExitExpected = false; + +function ensureSystemTestEnvironment() { + if (!process.env.TAURI_TEST_MODE) { + process.env.TAURI_TEST_MODE = '1'; + } + + const reuseRunId = process.env.TAURI_TEST_REUSE_RUN_ID === '1'; + if (!reuseRunId || !process.env.TAURI_TEST_RUN_ID) { + process.env.TAURI_TEST_RUN_ID = `wdio-${Date.now()}`; + } + + if (!process.env.TAURI_TEST_DATA_ROOT) { + process.env.TAURI_TEST_DATA_ROOT = path.resolve(repoRoot, '.system-test-data'); + } +} + +function sanitizeRunId(value) { + return value + .split('') + .map((character) => (/^[a-zA-Z0-9_-]$/.test(character) ? character : '_')) + .join(''); +} + +function sanitizeFileName(value) { + return value + .split('') + .map((character) => (/^[a-zA-Z0-9_.-]$/.test(character) ? character : '_')) + .join(''); +} + +function getCurrentRunDataDir() { + const dataRoot = process.env.TAURI_TEST_DATA_ROOT; + const runId = process.env.TAURI_TEST_RUN_ID; + + if (!dataRoot || !runId) { + return null; + } + + return path.join(dataRoot, sanitizeRunId(runId)); +} + +async function cleanupCurrentRunData() { + const runDataDir = getCurrentRunDataDir(); + if (!runDataDir) { + return; + } + + await removeDirectoryWithRetries(runDataDir); +} + +async function cleanupStaleRunData() { + const dataRoot = process.env.TAURI_TEST_DATA_ROOT; + const currentRunDataDir = getCurrentRunDataDir(); + const currentRunFolder = currentRunDataDir ? path.basename(currentRunDataDir) : null; + + if (!dataRoot) { + return; + } + + let entries; + try { + entries = await fs.promises.readdir(dataRoot, { withFileTypes: true }); + } catch { + return; + } + + const staleRunDirs = entries + .filter((entry) => entry.isDirectory()) + .map((entry) => entry.name) + .filter((name) => name.startsWith('wdio-') && name !== currentRunFolder) + .map((name) => path.join(dataRoot, name)); + + await Promise.all(staleRunDirs.map((directory) => removeDirectoryWithRetries(directory))); +} + +async function removeDirectoryWithRetries(directory) { + for (let attempt = 0; attempt < 5; attempt += 1) { + try { + await fs.promises.rm(directory, { recursive: true, force: true }); + return; + } catch { + if (attempt === 4) { + return; + } + await new Promise((resolve) => setTimeout(resolve, 200)); + } + } +} + +function shouldCleanupTestData() { + const keepData = process.env.TAURI_TEST_KEEP_DATA === '1'; + return !keepData; +} + +function buildDebugTauriApp() { + const result = + process.platform === 'win32' + ? spawnSync('pnpm run tauri build --debug --no-bundle', { + cwd: repoRoot, + stdio: 'inherit', + shell: true, + env: process.env, + }) + : spawnSync('pnpm', ['run', 'tauri', 'build', '--debug', '--no-bundle'], { + cwd: repoRoot, + stdio: 'inherit', + env: process.env, + }); + + if (result.status !== 0) { + const details = result.error ? ` (${result.error.message})` : ''; + throw new Error(`Failed to build Tauri app for system tests${details}`); + } + + if (!fs.existsSync(appBinaryPath)) { + throw new Error(`Expected Tauri debug binary at ${appBinaryPath}, but it was not found.`); + } +} + +function ensureBinaryAvailable(commandName) { + const lookup = + process.platform === 'win32' + ? spawnSync('where', [commandName], { stdio: 'ignore', shell: true }) + : spawnSync('which', [commandName], { stdio: 'ignore' }); + + return lookup.status === 0; +} + +function assertAbsoluteDriverPathExists() { + if (path.isAbsolute(tauriDriverBinary) && !fs.existsSync(tauriDriverBinary)) { + throw new Error(`TAURI_DRIVER_PATH points to a missing binary: ${tauriDriverBinary}`); + } +} + +function assertDriverBinaryResolvable() { + if (path.isAbsolute(tauriDriverBinary)) { + return; + } + + if (ensureBinaryAvailable('tauri-driver')) { + return; + } + + throw new Error('tauri-driver not found. Install it with: cargo install tauri-driver --locked'); +} + +function needsEdgeDriverValidation() { + return process.platform === 'win32' && !process.env.TAURI_NATIVE_DRIVER_PATH; +} + +function assertEdgeDriverAvailable() { + if (ensureBinaryAvailable('msedgedriver')) { + return; + } + + throw new Error( + 'msedgedriver not found in PATH. Install a version matching Edge or set TAURI_NATIVE_DRIVER_PATH.', + ); +} + +function verifyDriverPrerequisites() { + assertAbsoluteDriverPathExists(); + assertDriverBinaryResolvable(); + + if (needsEdgeDriverValidation()) { + assertEdgeDriverAvailable(); + } +} + +function waitForDriverReady(port, timeoutMs) { + const start = Date.now(); + + return new Promise((resolve, reject) => { + const attempt = () => { + const socket = net.connect({ host: '127.0.0.1', port }); + + socket.once('connect', () => { + socket.end(); + resolve(); + }); + + socket.once('error', () => { + socket.destroy(); + + if (Date.now() - start >= timeoutMs) { + reject( + new Error( + `Timed out waiting for tauri-driver on port ${port}. Ensure msedgedriver is available and matches Edge version.`, + ), + ); + return; + } + + setTimeout(attempt, 250); + }); + }; + + attempt(); + }); +} + +async function startTauriDriver() { + verifyDriverPrerequisites(); + + if (tauriDriverProcess && tauriDriverProcess.exitCode === null) { + return; + } + + tauriDriverExitExpected = false; + tauriDriverProcess = spawn(tauriDriverBinary, [], { + stdio: 'inherit', + env: process.env, + shell: process.platform === 'win32', + }); + + tauriDriverProcess.on('exit', (code) => { + tauriDriverProcess = undefined; + + if (code === 0) { + return; + } + + if (!tauriDriverExitExpected) { + console.error(`tauri-driver exited unexpectedly with code ${code}.`); + process.exitCode = 1; + } + }); + + await waitForDriverReady(tauriDriverPort, 10000); +} + +function stopTauriDriver() { + tauriDriverExitExpected = true; + tauriDriverProcess?.kill(); + tauriDriverProcess = undefined; +} + +export const config = { + runner: 'local', + hostname: '127.0.0.1', + port: tauriDriverPort, + specs: ['./specs/system.e2e.mjs'], + maxInstances: 1, + capabilities: [ + { + maxInstances: 1, + 'tauri:options': { + application: appBinaryPath, + }, + }, + ], + outputDir: artifactsDir, + logLevel: 'warn', + bail: 0, + maxInstancesPerCapability: 1, + waitforTimeout: 10000, + connectionRetryTimeout: 120000, + connectionRetryCount: 2, + services: [], + framework: 'mocha', + reporters: ['spec'], + mochaOpts: { + ui: 'bdd', + timeout: 120000, + }, + onPrepare: async () => { + ensureSystemTestEnvironment(); + await fs.promises.mkdir(path.join(artifactsDir, 'screenshots'), { recursive: true }); + if (shouldCleanupTestData()) { + await cleanupStaleRunData(); + await cleanupCurrentRunData(); + } + try { + verifyDriverPrerequisites(); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + console.error(message); + process.exit(1); + } + buildDebugTauriApp(); + await startTauriDriver(); + }, + onComplete: async () => { + stopTauriDriver(); + if (shouldCleanupTestData()) { + await cleanupCurrentRunData(); + } + }, + afterTest: async (test, _context, result) => { + if (result.passed) { + return; + } + + const testName = sanitizeFileName(test.fullTitle || test.title || 'test-failure'); + const screenshotPath = path.join(artifactsDir, 'screenshots', `${testName}.png`); + await browser.saveScreenshot(screenshotPath); + }, +}; diff --git a/package.json b/package.json index 7f03773..b315f5d 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "format": "prettier --write \"src/**/*.{ts,tsx,css}\" \"*.{js,ts,json,html}\"", "format:check": "prettier --check \"src/**/*.{ts,tsx,css}\" \"*.{js,ts,json,html}\"", "preview": "vite preview", + "test:system": "cross-env TAURI_TEST_MODE=1 wdio run e2e/wdio.conf.mjs --maxInstances 1", + "test:system:headed": "cross-env TAURI_TEST_MODE=1 WDIO_HEADLESS=0 wdio run e2e/wdio.conf.mjs --maxInstances 1", "tauri": "tauri", "tauri:windows:build": "tauri-windows-bundle build" }, @@ -37,9 +39,15 @@ "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.4", + "@wdio/cli": "^9.25.0", + "@wdio/local-runner": "^9.25.0", + "@wdio/mocha-framework": "^9.25.0", + "@wdio/spec-reporter": "^9.25.0", + "cross-env": "^10.1.0", "eslint": "^9.39.3", "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.2", + "expect-webdriverio": "^5.6.5", "globals": "^17.4.0", "prettier": "^3.8.1", "typescript": "~5.9.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cedb730..ebfdc64 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,16 +65,34 @@ importers: version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: ^5.1.4 - version: 5.1.4(vite@7.3.1) + version: 5.1.4(vite@7.3.1(@types/node@20.19.37)(jiti@2.6.1)(tsx@4.21.0)) + '@wdio/cli': + specifier: ^9.25.0 + version: 9.25.0(@types/node@20.19.37)(expect-webdriverio@5.6.5) + '@wdio/local-runner': + specifier: ^9.25.0 + version: 9.25.0(@wdio/globals@9.23.0)(webdriverio@9.25.0) + '@wdio/mocha-framework': + specifier: ^9.25.0 + version: 9.25.0 + '@wdio/spec-reporter': + specifier: ^9.25.0 + version: 9.25.0 + cross-env: + specifier: ^10.1.0 + version: 10.1.0 eslint: specifier: ^9.39.3 - version: 9.39.3 + version: 9.39.3(jiti@2.6.1) eslint-plugin-react-hooks: specifier: ^7.0.1 - version: 7.0.1(eslint@9.39.3) + version: 7.0.1(eslint@9.39.3(jiti@2.6.1)) eslint-plugin-react-refresh: specifier: ^0.5.2 - version: 0.5.2(eslint@9.39.3) + version: 0.5.2(eslint@9.39.3(jiti@2.6.1)) + expect-webdriverio: + specifier: ^5.6.5 + version: 5.6.5(@wdio/globals@9.23.0)(@wdio/logger@9.18.0)(webdriverio@9.25.0) globals: specifier: ^17.4.0 version: 17.4.0 @@ -86,10 +104,10 @@ importers: version: 5.9.3 typescript-eslint: specifier: ^8.56.1 - version: 8.56.1(eslint@9.39.3)(typescript@5.9.3) + version: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) vite: specifier: ^7.3.1 - version: 7.3.1 + version: 7.3.1(@types/node@20.19.37)(jiti@2.6.1)(tsx@4.21.0) packages: @@ -209,6 +227,9 @@ packages: peerDependencies: react: '>=16.8.0' + '@epic-web/invariant@1.0.0': + resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} + '@esbuild/aix-ppc64@0.27.3': resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} engines: {node: '>=18'} @@ -472,6 +493,168 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} + engines: {node: '>=18'} + + '@inquirer/checkbox@4.3.2': + resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/editor@4.2.23': + resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/expand@4.0.23': + resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + engines: {node: '>=18'} + + '@inquirer/input@4.3.1': + resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/number@3.0.23': + resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/password@4.0.23': + resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/prompts@7.10.1': + resolution: {integrity: sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/rawlist@4.1.11': + resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/search@3.2.2': + resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/select@4.4.2': + resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jest/diff-sequences@30.3.0': + resolution: {integrity: sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/expect-utils@30.3.0': + resolution: {integrity: sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/get-type@30.1.0': + resolution: {integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/pattern@30.0.1': + resolution: {integrity: sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/schemas@30.0.5': + resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/types@30.3.0': + resolution: {integrity: sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jimp/core@1.6.0': resolution: {integrity: sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w==} engines: {node: '>=18'} @@ -600,6 +783,18 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@promptbook/utils@0.69.5': + resolution: {integrity: sha512-xm5Ti/Hp3o4xHrsK9Yy3MS6KbDxYbq485hDsFvxqaNA7equHLPdo8H8faTitTeb14QCDfLW4iwCxdVYu5sn6YQ==} + + '@puppeteer/browsers@2.13.0': + resolution: {integrity: sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==} + engines: {node: '>=18'} + hasBin: true + '@radix-ui/primitive@1.0.0': resolution: {integrity: sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==} @@ -1023,6 +1218,16 @@ packages: cpu: [x64] os: [win32] + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sinclair/typebox@0.34.48': + resolution: {integrity: sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + '@tauri-apps/api@2.10.1': resolution: {integrity: sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==} @@ -1114,6 +1319,9 @@ packages: '@tokenizer/token@0.3.0': resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + '@tootallnate/quickjs-emscripten@0.23.0': + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1141,18 +1349,36 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} '@types/mdast@3.0.15': resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + '@types/mocha@10.0.10': + resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} + '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} '@types/node@16.9.1': resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==} + '@types/node@20.19.37': + resolution: {integrity: sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: @@ -1161,9 +1387,30 @@ packages: '@types/react@19.2.14': resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + '@types/sinonjs__fake-timers@8.1.5': + resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@types/which@2.0.2': + resolution: {integrity: sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + '@typescript-eslint/eslint-plugin@8.56.1': resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1229,6 +1476,91 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/pretty-format@4.1.0': + resolution: {integrity: sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==} + + '@vitest/snapshot@2.1.9': + resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + + '@vitest/snapshot@4.1.0': + resolution: {integrity: sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==} + + '@vitest/utils@4.1.0': + resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==} + + '@wdio/cli@9.25.0': + resolution: {integrity: sha512-7m6Au8U0Fz+/n6vlchxHd5ogYESjz2XEYVnmcqnDapCAUo570Ilb86Muz69AFrBiZ6D+xkesQTwlWOdNRjIY1w==} + engines: {node: '>=18.20.0'} + hasBin: true + + '@wdio/config@9.25.0': + resolution: {integrity: sha512-EWa7l1rrbSNthCRDpdBw7ESAa1/jAjSsWCGkaVAO0HMOGlQjzvYI6gNi4KUeymnurDZ2IPr0jr+f9We6AWi6QA==} + engines: {node: '>=18.20.0'} + + '@wdio/dot-reporter@9.25.0': + resolution: {integrity: sha512-yFlyHfCJOERWIgiFzbyliCr6YxEYZDM3rykCHmpIlbAOwATxjIh26fvkKI8/23LDqMybym8Pn/Yjj/W78/KgIg==} + engines: {node: '>=18.20.0'} + + '@wdio/globals@9.23.0': + resolution: {integrity: sha512-OmwPKV8c5ecLqo+EkytN7oUeYfNmRI4uOXGIR1ybP7AK5Zz+l9R0dGfoadEuwi1aZXAL0vwuhtq3p0OL3dfqHQ==} + engines: {node: '>=18.20.0'} + peerDependencies: + expect-webdriverio: ^5.3.4 + webdriverio: ^9.0.0 + + '@wdio/local-runner@9.25.0': + resolution: {integrity: sha512-E6pEeQouVLle19Gk55Y/JxPGMzT2jhmHS80yjT3g481Q1EML9y8m3T6UMemAUnz70FGneP0aCcuFKJdmkF9dKw==} + engines: {node: '>=18.20.0'} + + '@wdio/logger@9.18.0': + resolution: {integrity: sha512-HdzDrRs+ywAqbXGKqe1i/bLtCv47plz4TvsHFH3j729OooT5VH38ctFn5aLXgECmiAKDkmH/A6kOq2Zh5DIxww==} + engines: {node: '>=18.20.0'} + + '@wdio/mocha-framework@9.25.0': + resolution: {integrity: sha512-30qPP7w0UGG49LB3nAMxVf9Q9GA8q/NeDPHjBsXCjpSnO0AswtjFktb91hkqQqssrlGMQV+QyQuBD+kMxkhrDQ==} + engines: {node: '>=18.20.0'} + + '@wdio/protocols@9.25.0': + resolution: {integrity: sha512-PErbZqdpFmE69bRuku3OR34Ro2xuZNNLXYFOcJnjXJVzf5+ApDyGHYrMlvhtrrSy9/55LUybk851ppjS+3RoDA==} + + '@wdio/repl@9.16.2': + resolution: {integrity: sha512-FLTF0VL6+o5BSTCO7yLSXocm3kUnu31zYwzdsz4n9s5YWt83sCtzGZlZpt7TaTzb3jVUfxuHNQDTb8UMkCu0lQ==} + engines: {node: '>=18.20.0'} + + '@wdio/reporter@9.25.0': + resolution: {integrity: sha512-zmyjr7/EoGwlmrICNzhRL3k0dlJoqdQShzHd5l8V1axYsaC3UHGy2oNDXwKD/OjhEThJsGHxwjyUDkKYhbZdCw==} + engines: {node: '>=18.20.0'} + + '@wdio/runner@9.25.0': + resolution: {integrity: sha512-Oe7NnFWJICF5g+LGLVWi3x41aL2ZRto3bOQZlBjNnGFRkx+BPz7qHdENueflfh7VCX9o3qRns6cQ3CEuurLaNg==} + engines: {node: '>=18.20.0'} + peerDependencies: + expect-webdriverio: ^5.3.4 + webdriverio: ^9.0.0 + + '@wdio/spec-reporter@9.25.0': + resolution: {integrity: sha512-15+YnhnXDW7dAJ4PP+qZ2imAbVcMMSwewtjVrKRWK0OsMASXRXka/zV3jViRp1Rf+WCGp76HMxhv7YOygfE68A==} + engines: {node: '>=18.20.0'} + + '@wdio/types@9.25.0': + resolution: {integrity: sha512-ovSEcUBLz6gVDIsBZYKQXz8EGU37jS8sqbmlOe5+jB4XbsTBCyTLjQK/rO7LWQAKJcs0vBq+Pd+VrlsFtA7tTQ==} + engines: {node: '>=18.20.0'} + + '@wdio/utils@9.25.0': + resolution: {integrity: sha512-w/ej8gZkc2tZr8L91ATyA1AWrbPDYDOvblQ7r+zt1uPRobuA4H98GME7Zm7i3FIP695BvV4G35Gcs5NssZW1pw==} + engines: {node: '>=18.20.0'} + + '@wdio/xvfb@9.25.0': + resolution: {integrity: sha512-qbsdWm1sP5CGikz3n3dwoVGqbRyBsERGzckDMsQeQ9QVTG6OsNOm4KiVejdiwdPXqDjLUnBv8xGtfuFrftFwcA==} + engines: {node: '>=18'} + + '@zip.js/zip.js@2.8.23': + resolution: {integrity: sha512-RB+RLnxPJFPrGvQ9rgO+4JOcsob6lD32OcF0QE0yg24oeW9q8KnTTNlugcDaIveEcCbclobJcZP+fLQ++sH0bw==} + engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=18.0.0'} + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -1243,13 +1575,37 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + ajv@6.14.0: resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + any-base@1.1.0: resolution: {integrity: sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==} @@ -1257,6 +1613,14 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} + + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1264,10 +1628,33 @@ packages: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + + async-exit-hook@2.0.1: + resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==} + engines: {node: '>=0.12.0'} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + await-to-js@3.0.0: resolution: {integrity: sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==} engines: {node: '>=6.0.0'} + b4a@1.8.0: + resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1275,6 +1662,44 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} + bare-events@2.8.2: + resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + + bare-fs@4.5.5: + resolution: {integrity: sha512-XvwYM6VZqKoqDll8BmSww5luA5eflDzY0uEFfBJtFKe4PAAtxBjU3YIxzIBzhyaEQBy1VXEQBto4cpN5RZJw+w==} + engines: {bare: '>=1.16.0'} + peerDependencies: + bare-buffer: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + + bare-os@3.8.0: + resolution: {integrity: sha512-Dc9/SlwfxkXIGYhvMQNUtKaXCaGkZYGcd1vuNUUADVqzu4/vQfvnMkYYOUnt2VwQ2AqKr/8qAVFRtwETljgeFg==} + engines: {bare: '>=1.14.0'} + + bare-path@3.0.0: + resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + + bare-stream@2.8.1: + resolution: {integrity: sha512-bSeR8RfvbRwDpD7HWZvn8M3uYNDrk7m9DQjYOFkENZlXW8Ju/MPaqUPQq5LqJ3kyjEm07siTaAQ7wBKCU59oHg==} + peerDependencies: + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + bare-events: + optional: true + + bare-url@2.3.2: + resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -1283,6 +1708,10 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + basic-ftp@5.2.0: + resolution: {integrity: sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==} + engines: {node: '>=10.0.0'} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -1290,9 +1719,15 @@ packages: bmp-ts@1.0.9: resolution: {integrity: sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.3: resolution: {integrity: sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==} engines: {node: 18 || 20 || >=22} @@ -1304,11 +1739,21 @@ packages: browser-fs-access@0.29.1: resolution: {integrity: sha512-LSvVX5e21LRrXqVMhqtAwj5xPgDb+fXAIH80NsnCQ9xuZPs2xWsOREi24RKgZa1XOiQRbcmVrv87+ulOKsgjxw==} + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + browserslist@4.28.1: resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} @@ -1316,6 +1761,10 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + caniuse-lite@1.0.30001774: resolution: {integrity: sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==} @@ -1326,13 +1775,50 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.2.0: + resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} + engines: {node: '>=20.18.1'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + clsx@1.1.1: resolution: {integrity: sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==} engines: {node: '>=6'} @@ -1356,12 +1842,23 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cose-base@1.0.3: resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} @@ -1369,6 +1866,25 @@ packages: resolution: {integrity: sha512-kucVIjOmMc1f0tv53BJ/5WIX+MGLcKuoBhnGqQrgKJNqLByb/sVMWfW/Aw6hw0jgcqjJ2pi9E5y32zOIpaUlsA==} engines: {node: '>=0.8'} + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} + + create-wdio@9.25.0: + resolution: {integrity: sha512-ZnkJVDx3HB7UNH2t1kxK1VoNWQAQhLYyTjSEdpcFTHoj/QUrzS7K9nW99Q6WT0mgsedbtl86VMq4IXfy6f8Jrw==} + engines: {node: '>=12.0.0'} + hasBin: true + + cross-env@10.1.0: + resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} + engines: {node: '>=20'} + hasBin: true + cross-env@7.0.3: resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} @@ -1378,6 +1894,19 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-shorthand-properties@1.1.2: + resolution: {integrity: sha512-C2AugXIpRGQTxaCW0N7n5jD/p5irUmCrwl03TrnMFBHDbdq44CFWR2zO7rK9xPN4Eo3pUxC4vQzQgbIpzrD1PQ==} + + css-value@0.0.1: + resolution: {integrity: sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -1532,6 +2061,10 @@ packages: dagre-d3-es@7.0.10: resolution: {integrity: sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==} + data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} + engines: {node: '>= 14'} + dayjs@1.11.19: resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} @@ -1544,12 +2077,35 @@ packages: supports-color: optional: true + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + decamelize@6.0.1: + resolution: {integrity: sha512-G7Cqgaelq68XHJNGlZ7lrNQyhZGsFqpwtGFexqUv4IQdjKoSYF7ipZ9UuTJZUSQXFj/XaoBLuEVIVqr8EJngEQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + decode-named-character-reference@1.3.0: resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge-ts@7.1.5: + resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==} + engines: {node: '>=16.0.0'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + delaunator@5.0.1: resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} @@ -1564,17 +2120,85 @@ packages: resolution: {integrity: sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==} engines: {node: '>=0.3.1'} + diff@8.0.3: + resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} + engines: {node: '>=0.3.1'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + dompurify@3.1.6: resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==} + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dotenv@17.3.1: + resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} + engines: {node: '>=12'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + easy-table@1.2.0: + resolution: {integrity: sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==} + + edge-paths@3.0.5: + resolution: {integrity: sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==} + engines: {node: '>=14.0.0'} + + edgedriver@6.3.0: + resolution: {integrity: sha512-ggEQL+oEyIcM4nP2QC3AtCQ04o4kDNefRM3hja0odvlPSnsaxiruMxEZ93v3gDCKWYW6BXUr51PPradb+3nffw==} + engines: {node: '>=20.0.0'} + hasBin: true + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + electron-to-chromium@1.5.302: resolution: {integrity: sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==} elkjs@0.9.3: resolution: {integrity: sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==} - es6-promise-pool@2.5.0: - resolution: {integrity: sha512-VHErXfzR/6r/+yyzPKeBvO0lgjfC5cbDCQWjWwMZWSb6YU39TGIl51OUmCfWCq4ylMdJSB8zkz2vIuIeIxXApA==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es6-promise-pool@2.5.0: + resolution: {integrity: sha512-VHErXfzR/6r/+yyzPKeBvO0lgjfC5cbDCQWjWwMZWSb6YU39TGIl51OUmCfWCq4ylMdJSB8zkz2vIuIeIxXApA==} engines: {node: '>=0.10.0'} esbuild@0.27.3: @@ -1586,10 +2210,19 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + eslint-plugin-react-hooks@7.0.1: resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} engines: {node: '>=18'} @@ -1631,6 +2264,11 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.7.0: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} @@ -1651,22 +2289,66 @@ packages: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} + engines: {node: ^18.19.0 || >=20.5.0} + exif-parser@0.1.12: resolution: {integrity: sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==} + exit-hook@4.0.0: + resolution: {integrity: sha512-Fqs7ChZm72y40wKjOFXBKg7nJZvQJmewP5/7LtePDdnah/+FH9Hp5sgMujSCMPXlxOAW2//1jrW9pnsY7o20vQ==} + engines: {node: '>=18'} + + expect-webdriverio@5.6.5: + resolution: {integrity: sha512-5ot+Apo0bEvMD/nqzWymQpgyWnOdu0kVpmahLx5T7NzUc6RyifucZ24Gsfr6F6C8yRGBhmoFh7ZeY+W9kteEBQ==} + engines: {node: '>=20'} + peerDependencies: + '@wdio/globals': ^9.0.0 + '@wdio/logger': ^9.0.0 + webdriverio: ^9.0.0 + + expect@30.3.0: + resolution: {integrity: sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + + fast-deep-equal@2.0.1: + resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-xml-builder@1.1.3: + resolution: {integrity: sha512-1o60KoFw2+LWKQu3IdcfcFlGTW4dpqEWmjhYec6H82AYZU2TVBXep6tMl8Z1Y+wM+ZrzCwe3BZ9Vyd9N2rIvmg==} + + fast-xml-parser@5.5.5: + resolution: {integrity: sha512-NLY+V5NNbdmiEszx9n14mZBseJTC50bRq1VHsaxOmR72JDuZt+5J1Co+dC/4JPnyq+WrIHNM69r0sqf7BMb3Mg==} + hasBin: true + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1676,6 +2358,10 @@ packages: picomatch: optional: true + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -1684,6 +2370,9 @@ packages: resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} engines: {node: '>=10'} + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1692,17 +2381,32 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + flatted@3.3.4: resolution: {integrity: sha512-3+mMldrTAPdta5kjX2G2J7iX4zxtnwpdA8Tr2ZSjkyPSanvbZAcy6flmtnXbEybHrDcU9641lxrMfFuUxVz9vA==} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + fractional-indexing@3.2.0: resolution: {integrity: sha512-PcOxmqwYCW7O2ovKRU8OoQQj2yqTfEB/yeTYk4gPid6dN5ODRfU1hXd9tTVZzax/0NkO7AxpHykvZnT1aYp/BQ==} engines: {node: ^14.13.1 || >=16.0.0} + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1712,14 +2416,42 @@ packages: resolution: {integrity: sha512-/gZffu4ykarLrCiP3Ygsa86UAo1E5vEVlvTrpkKywXSbP9Xhln3oSp9QSV57gEq3JFFpGJ4GZ+5zdEp3FcUh4w==} engines: {node: '>= 0.6.0'} + geckodriver@6.1.0: + resolution: {integrity: sha512-ZRXLa4ZaYTTgUO4Eefw+RsQCleugU2QLb1ME7qTYxxuRj51yAhfnXaItXNs5/vUzfIaDHuZ+YnSF005hfp07nQ==} + engines: {node: '>=20.0.0'} + hasBin: true + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-nonce@1.0.1: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} + get-port@7.1.0: + resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} + engines: {node: '>=16'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + get-tsconfig@4.13.6: + resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + + get-uri@6.0.5: + resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} + engines: {node: '>= 14'} + gifwrap@0.10.1: resolution: {integrity: sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==} @@ -1731,10 +2463,20 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + glob@13.0.6: resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} engines: {node: 18 || 20 || >=22} + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -1746,6 +2488,12 @@ packages: glur@1.1.2: resolution: {integrity: sha512-l+8esYHTKOx2G/Aao4lEQ0bnHWg4fWtJbVoZZT9Knxi01pB8C80BR85nONLFwkkQoFRCmXY+BUcGZN3yZ2QsRA==} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + hachure-fill@0.5.2: resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} @@ -1753,16 +2501,50 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + hermes-estree@0.25.1: resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} hermes-parser@0.25.1: resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + + hosted-git-info@8.1.0: + resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==} + engines: {node: ^18.17.0 || >=20.5.0} + + htmlfy@0.8.1: + resolution: {integrity: sha512-xWROBw9+MEGwxpotll0h672KCaLrKKiCYzsyN8ZgL9cQbVumFnyvsk2JqiB9ELAV1GLj1GG/jxZUjV9OZZi/yQ==} + + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -1780,6 +2562,9 @@ packages: image-q@4.0.0: resolution: {integrity: sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==} + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + immutable@4.3.7: resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} @@ -1787,13 +2572,29 @@ packages: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + inquirer@12.11.1: + resolution: {integrity: sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + internmap@1.0.1: resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} @@ -1801,6 +2602,13 @@ packages: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -1809,6 +2617,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -1817,13 +2629,80 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@4.0.0: + resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} + engines: {node: '>=20'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + engines: {node: '>=10'} + hasBin: true + + jest-diff@30.3.0: + resolution: {integrity: sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-matcher-utils@30.3.0: + resolution: {integrity: sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-message-util@30.3.0: + resolution: {integrity: sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-mock@30.3.0: + resolution: {integrity: sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-regex-util@30.0.1: + resolution: {integrity: sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-util@30.3.0: + resolution: {integrity: sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jimp@1.6.0: resolution: {integrity: sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg==} engines: {node: '>=18'} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + jotai-scope@0.7.2: resolution: {integrity: sha512-Gwed97f3dDObrO43++2lRcgOqw4O2sdr4JCjP/7eHK1oPACDJ7xKHGScpJX9XaflU+KBHXF+VhwECnzcaQiShg==} peerDependencies: @@ -1860,6 +2739,10 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -1871,6 +2754,9 @@ packages: engines: {node: '>=6'} hasBin: true + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + katex@0.16.33: resolution: {integrity: sha512-q3N5u+1sY9Bu7T4nlXoiRBXWfwSefNGoKeOwekV+gw0cAXQlz2Ww6BLcmBxVDeXBMUDQv6fK5bcNaJLxob3ZQA==} hasBin: true @@ -1888,26 +2774,76 @@ packages: layout-base@1.0.2: resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + + lines-and-columns@2.0.4: + resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + locate-app@2.5.0: + resolution: {integrity: sha512-xIqbzPMBYArJRmPGUZD9CzV9wOqmVtQnaAn3wrj3s6WYW0bQvPI7x+sPYUGmDTYMHefVK//zc6HEYZ1qnxIK+Q==} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lodash-es@4.17.23: resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + lodash.flattendeep@4.4.0: + resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.pickby@4.6.0: + resolution: {integrity: sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==} + lodash.throttle@4.1.1: resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + + lodash.zip@4.2.0: + resolution: {integrity: sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==} + + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + loglevel-plugin-prefix@0.8.4: + resolution: {integrity: sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==} + + loglevel@1.9.2: + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} + engines: {node: '>= 0.6.0'} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.2.6: resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} engines: {node: 20 || >=22} @@ -1915,6 +2851,13 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + mdast-util-from-markdown@1.3.1: resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} @@ -1999,10 +2942,30 @@ packages: minimatch@3.1.5: resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mocha@10.8.2: + resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} + engines: {node: '>= 14.0.0'} + hasBin: true + + modern-tar@0.7.5: + resolution: {integrity: sha512-YTefgdpKKFgoTDbEUqXqgUJct2OG6/4hs4XWLsxcHkDLj/x/V8WmKIRppPnXP5feQ7d1vuYWSp3qKkxfwaFaxA==} + engines: {node: '>=18.0.0'} + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -2013,6 +2976,10 @@ packages: multimath@2.0.0: resolution: {integrity: sha512-toRx66cAMJ+Ccz7pMIg38xSIrtnbozk0dchXezwQDMgQmbGpfxjtv68H+L00iFL8hxDaVjrmwAFSb3I6bg8Q2g==} + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2031,23 +2998,49 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} non-layered-tidy-tree-layout@2.0.2: resolution: {integrity: sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==} + normalize-package-data@6.0.2: + resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} + engines: {node: ^16.14.0 || >=18.0.0} + + normalize-package-data@7.0.1: + resolution: {integrity: sha512-linxNAT6M0ebEYZOx2tO6vBEFsVgnPpv+AVjk0wJHfaUIbq31Jm3T6vvZaarnOeWDh8ShnwXuaAyM7WT3RzErA==} + engines: {node: ^18.17.0 || >=20.5.0} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + omggif@1.0.10: resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + open-color@1.9.1: resolution: {integrity: sha512-vCseG/EQ6/RcvxhUcGJiHViOgrtz4x0XbZepXvKik66TMGkvbmjeJrKFyBEx6daG5rNyyd14zYXhz0hZVwQFOw==} @@ -2059,10 +3052,29 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + pac-proxy-agent@7.2.0: + resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} + engines: {node: '>= 14'} + + pac-resolver@7.0.1: + resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} + engines: {node: '>= 14'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -2082,6 +3094,23 @@ packages: parse-bmfont-xml@1.1.6: resolution: {integrity: sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==} + parse-json@7.1.1: + resolution: {integrity: sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==} + engines: {node: '>=16'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + path-data-parser@0.1.0: resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} @@ -2089,18 +3118,43 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-expression-matcher@1.1.3: + resolution: {integrity: sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==} + engines: {node: '>=14.0.0'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.2: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + peek-readable@4.1.0: resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==} engines: {node: '>=8'} + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + perfect-freehand@1.2.0: resolution: {integrity: sha512-h/0ikF1M3phW7CwpZ5MMvKnfpHficWoOEyr//KVNTxV4F6deRK1eYMtHyBKEAKFK0aXIEUK9oBvlF6PNXMDsAw==} @@ -2161,10 +3215,35 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@30.3.0: + resolution: {integrity: sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + pretty-ms@9.3.0: + resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} + engines: {node: '>=18'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + proxy-agent@6.5.0: + resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} + engines: {node: '>= 14'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2172,11 +3251,20 @@ packages: pwacompat@2.0.17: resolution: {integrity: sha512-6Du7IZdIy7cHiv7AhtDy4X2QRM8IAD5DII69mt5qWibC2d15ZU8DmBG1WdZKekG11cChSu4zkSUGPF9sweOl6w==} + query-selector-shadow-dom@1.0.1: + resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + react-dom@19.2.4: resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: react: ^19.2.4 + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-refresh@0.18.0: resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} engines: {node: '>=0.10.0'} @@ -2215,6 +3303,17 @@ packages: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} + read-pkg-up@10.1.0: + resolution: {integrity: sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==} + engines: {node: '>=16'} + + read-pkg@8.1.0: + resolution: {integrity: sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==} + engines: {node: '>=16'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@4.7.0: resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2223,14 +3322,42 @@ packages: resolution: {integrity: sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==} engines: {node: '>=8'} + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + recursive-readdir@2.2.3: + resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==} + engines: {node: '>=6.0.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resq@1.11.0: + resolution: {integrity: sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==} + + ret@0.5.0: + resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} + engines: {node: '>=10'} + + rgb2hex@0.2.5: + resolution: {integrity: sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==} + robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} @@ -2242,16 +3369,34 @@ packages: roughjs@4.6.4: resolution: {integrity: sha512-s6EZ0BntezkFYMf/9mGn7M8XGIoaav9QQBCnJROWB3brUWQ683Q2LbRD/hq0Z3bAJ/9NVpU/5LpiTWvQMyLDhw==} + run-async@4.0.6: + resolution: {integrity: sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==} + engines: {node: '>=0.12.0'} + rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} + safaridriver@1.0.1: + resolution: {integrity: sha512-jkg4434cYgtrIF2AeY/X0Wmd2W73cK5qIEFE3hDrrQenJH/2SDJIXGvPAigfvQTcE9+H31zkiNHbUqcihEiMRA==} + engines: {node: '>=18.0.0'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-regex2@5.1.0: + resolution: {integrity: sha512-pNHAuBW7TrcleFHsxBr5QMi/Iyp0ENjUKz7GCcX1UO7cMh+NmVK6HxQckNL1tJp1XAJVjG6B8OKIPqodqj9rtw==} + hasBin: true + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -2276,6 +3421,16 @@ packages: engines: {node: '>=10'} hasBin: true + serialize-error@12.0.0: + resolution: {integrity: sha512-ZYkZLAvKTKQXWuh5XpBw7CdbSzagarX39WyZ2H07CDLC5/KfsRGlIXV8d4+tfqX1M7916mRqR1QfNHSij+c9Pw==} + engines: {node: '>=18'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2284,24 +3439,104 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + simple-xml-to-json@1.2.3: resolution: {integrity: sha512-kWJDCr9EWtZ+/EYYM5MareWj2cRnZGF93YDNpH4jQiHB+hBIZnfPFSQiVMzZOdk+zXWqTZ/9fTeQNu2DqeiudA==} engines: {node: '>=20.12.2'} + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + sliced@1.0.1: resolution: {integrity: sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==} + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + + socks@2.8.7: + resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + spacetrim@0.11.59: + resolution: {integrity: sha512-lLYsktklSRKprreOm7NXReW8YiX2VBjbgmXYEziOoGf/qsJqAEACaDvoTtUOycwjpaSh+bT8eu0KrJn7UNxiCg==} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + stream-buffers@3.0.3: + resolution: {integrity: sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==} + engines: {node: '>= 0.10.0'} + + streamx@2.23.0: + resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strnum@2.2.0: + resolution: {integrity: sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==} + strtok3@6.3.0: resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} engines: {node: '>=10'} @@ -2313,6 +3548,22 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + tar-fs@3.1.2: + resolution: {integrity: sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==} + + tar-stream@3.1.8: + resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==} + + teex@1.0.1: + resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} + + text-decoder@1.2.7: + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} + tinycolor2@1.6.0: resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} @@ -2320,6 +3571,14 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -2341,6 +3600,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + tunnel-rat@0.1.2: resolution: {integrity: sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==} @@ -2348,7 +3612,19 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.56.1: + type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + + type-fest@4.26.0: + resolution: {integrity: sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==} + engines: {node: '>=16'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typescript-eslint@8.56.1: resolution: {integrity: sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: @@ -2360,6 +3636,21 @@ packages: engines: {node: '>=14.17'} hasBin: true + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici@6.24.0: + resolution: {integrity: sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA==} + engines: {node: '>=18.17'} + + undici@7.24.1: + resolution: {integrity: sha512-5xoBibbmnjlcR3jdqtY2Lnx7WbrD/tHlT01TmvqZUFVc9Q1w4+j5hbnapTqbcXITMH1ovjq/W7BkqBilHiVAaA==} + engines: {node: '>=20.18.1'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + unist-util-stringify-position@3.0.3: resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} @@ -2372,6 +3663,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + urlpattern-polyfill@10.1.0: + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} + use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -2397,9 +3691,16 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + userhome@1.0.1: + resolution: {integrity: sha512-5cnLm4gseXjAclKowC4IjByaGsjtAoV6PrOQOljplNB54ReUYJP8HdAFq2muHinSDAh09PPX/uXDPfdxRHvuSA==} + engines: {node: '>= 0.8.0'} + utif2@4.1.0: resolution: {integrity: sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==} + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -2409,6 +3710,9 @@ packages: engines: {node: '>=8'} hasBin: true + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vite@7.3.1: resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2449,21 +3753,86 @@ packages: yaml: optional: true + wait-port@1.1.0: + resolution: {integrity: sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==} + engines: {node: '>=10'} + hasBin: true + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + web-worker@1.5.0: resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} + webdriver@9.25.0: + resolution: {integrity: sha512-XnABKdrp83zX3xVltmX0OcFzn8zOzWGtZQxIUKY0+INB0g9Nnnfu7G75W0G+0y4nyb3zH8mavGzDBiXctdEd3Q==} + engines: {node: '>=18.20.0'} + + webdriverio@9.25.0: + resolution: {integrity: sha512-ualC/LtWGjL5rwGAbUUzURKqKoHJG2/qecEppcS9k4n1IX3MlbzGXuL/qpXiRbs/h4981HpRbZAKBxRYqwUe3g==} + engines: {node: '>=18.20.0'} + peerDependencies: + puppeteer-core: '>=22.x || <=24.x' + peerDependenciesMeta: + puppeteer-core: + optional: true + webworkify@1.5.0: resolution: {integrity: sha512-AMcUeyXAhbACL8S2hqqdqOLqvJ8ylmIbNwUIqQujRSouf4+eUFaXbG6F1Rbu+srlJMmxQWsiU7mOJi0nMBfM1g==} + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + which@6.0.1: + resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + 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 + xml-parse-from-string@1.0.1: resolution: {integrity: sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==} @@ -2475,13 +3844,56 @@ packages: resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} engines: {node: '>=4.0'} + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + zod-validation-error@4.0.2: resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} engines: {node: '>=18.0.0'} @@ -2529,7 +3941,7 @@ snapshots: '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -2613,7 +4025,7 @@ snapshots: '@babel/parser': 7.29.0 '@babel/template': 7.28.6 '@babel/types': 7.29.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -2655,6 +4067,8 @@ snapshots: react: 19.2.4 tslib: 2.8.1 + '@epic-web/invariant@1.0.0': {} + '@esbuild/aix-ppc64@0.27.3': optional: true @@ -2733,9 +4147,9 @@ snapshots: '@esbuild/win32-x64@0.27.3': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.3)': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.3(jiti@2.6.1))': dependencies: - eslint: 9.39.3 + eslint: 9.39.3(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -2743,7 +4157,7 @@ snapshots: '@eslint/config-array@0.21.1': dependencies: '@eslint/object-schema': 2.1.7 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -2759,7 +4173,7 @@ snapshots: '@eslint/eslintrc@3.3.4': dependencies: ajv: 6.14.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -2877,6 +4291,167 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@inquirer/ansi@1.0.2': {} + + '@inquirer/checkbox@4.3.2(@types/node@20.19.37)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@20.19.37) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/confirm@5.1.21(@types/node@20.19.37)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/type': 3.0.10(@types/node@20.19.37) + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/core@10.3.2(@types/node@20.19.37)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@20.19.37) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/editor@4.2.23(@types/node@20.19.37)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/external-editor': 1.0.3(@types/node@20.19.37) + '@inquirer/type': 3.0.10(@types/node@20.19.37) + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/expand@4.0.23(@types/node@20.19.37)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/type': 3.0.10(@types/node@20.19.37) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/external-editor@1.0.3(@types/node@20.19.37)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/figures@1.0.15': {} + + '@inquirer/input@4.3.1(@types/node@20.19.37)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/type': 3.0.10(@types/node@20.19.37) + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/number@3.0.23(@types/node@20.19.37)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/type': 3.0.10(@types/node@20.19.37) + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/password@4.0.23(@types/node@20.19.37)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/type': 3.0.10(@types/node@20.19.37) + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/prompts@7.10.1(@types/node@20.19.37)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@20.19.37) + '@inquirer/confirm': 5.1.21(@types/node@20.19.37) + '@inquirer/editor': 4.2.23(@types/node@20.19.37) + '@inquirer/expand': 4.0.23(@types/node@20.19.37) + '@inquirer/input': 4.3.1(@types/node@20.19.37) + '@inquirer/number': 3.0.23(@types/node@20.19.37) + '@inquirer/password': 4.0.23(@types/node@20.19.37) + '@inquirer/rawlist': 4.1.11(@types/node@20.19.37) + '@inquirer/search': 3.2.2(@types/node@20.19.37) + '@inquirer/select': 4.4.2(@types/node@20.19.37) + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/rawlist@4.1.11(@types/node@20.19.37)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/type': 3.0.10(@types/node@20.19.37) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/search@3.2.2(@types/node@20.19.37)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@20.19.37) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/select@4.4.2(@types/node@20.19.37)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@20.19.37) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 20.19.37 + + '@inquirer/type@3.0.10(@types/node@20.19.37)': + optionalDependencies: + '@types/node': 20.19.37 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jest/diff-sequences@30.3.0': {} + + '@jest/expect-utils@30.3.0': + dependencies: + '@jest/get-type': 30.1.0 + + '@jest/get-type@30.1.0': {} + + '@jest/pattern@30.0.1': + dependencies: + '@types/node': 16.9.1 + jest-regex-util: 30.0.1 + + '@jest/schemas@30.0.5': + dependencies: + '@sinclair/typebox': 0.34.48 + + '@jest/types@30.3.0': + dependencies: + '@jest/pattern': 30.0.1 + '@jest/schemas': 30.0.5 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 16.9.1 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + '@jimp/core@1.6.0': dependencies: '@jimp/file-ops': 1.6.0 @@ -3085,6 +4660,28 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@pkgjs/parseargs@0.11.0': + optional: true + + '@promptbook/utils@0.69.5': + dependencies: + spacetrim: 0.11.59 + + '@puppeteer/browsers@2.13.0': + dependencies: + debug: 4.4.3(supports-color@8.1.1) + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.5.0 + semver: 7.7.4 + tar-fs: 3.1.2 + yargs: 17.7.2 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + - supports-color + '@radix-ui/primitive@1.0.0': dependencies: '@babel/runtime': 7.28.6 @@ -3442,6 +5039,12 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true + '@sec-ant/readable-stream@0.4.1': {} + + '@sinclair/typebox@0.34.48': {} + + '@sindresorhus/merge-streams@4.0.0': {} + '@tauri-apps/api@2.10.1': {} '@tauri-apps/cli-darwin-arm64@2.10.0': @@ -3505,6 +5108,8 @@ snapshots: '@tokenizer/token@0.3.0': {} + '@tootallnate/quickjs-emscripten@0.23.0': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.29.0 @@ -3540,16 +5145,34 @@ snapshots: '@types/estree@1.0.8': {} + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + '@types/json-schema@7.0.15': {} '@types/mdast@3.0.15': dependencies: '@types/unist': 2.0.11 + '@types/mocha@10.0.10': {} + '@types/ms@2.1.0': {} '@types/node@16.9.1': {} + '@types/node@20.19.37': + dependencies: + undici-types: 6.21.0 + + '@types/normalize-package-data@2.4.4': {} + '@types/react-dom@19.2.3(@types/react@19.2.14)': dependencies: '@types/react': 19.2.14 @@ -3558,17 +5181,38 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/sinonjs__fake-timers@8.1.5': {} + + '@types/stack-utils@2.0.3': {} + '@types/unist@2.0.11': {} - '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@5.9.3))(eslint@9.39.3)(typescript@5.9.3)': + '@types/which@2.0.2': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 20.19.37 + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.35': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@types/yauzl@2.10.3': + dependencies: + '@types/node': 16.9.1 + optional: true + + '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.56.1(eslint@9.39.3)(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/type-utils': 8.56.1(eslint@9.39.3)(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@9.39.3)(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.56.1 - eslint: 9.39.3 + eslint: 9.39.3(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.4.0(typescript@5.9.3) @@ -3576,14 +5220,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@5.9.3)': + '@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.56.1 '@typescript-eslint/types': 8.56.1 '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.56.1 - debug: 4.4.3 - eslint: 9.39.3 + debug: 4.4.3(supports-color@8.1.1) + eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -3592,7 +5236,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) '@typescript-eslint/types': 8.56.1 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -3606,13 +5250,13 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.56.1(eslint@9.39.3)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.56.1 '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@9.39.3)(typescript@5.9.3) - debug: 4.4.3 - eslint: 9.39.3 + '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + debug: 4.4.3(supports-color@8.1.1) + eslint: 9.39.3(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -3626,7 +5270,7 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) '@typescript-eslint/types': 8.56.1 '@typescript-eslint/visitor-keys': 8.56.1 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) minimatch: 10.2.4 semver: 7.7.4 tinyglobby: 0.2.15 @@ -3635,13 +5279,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.56.1(eslint@9.39.3)(typescript@5.9.3)': + '@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.56.1 '@typescript-eslint/types': 8.56.1 '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - eslint: 9.39.3 + eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -3651,7 +5295,7 @@ snapshots: '@typescript-eslint/types': 8.56.1 eslint-visitor-keys: 5.0.1 - '@vitejs/plugin-react@5.1.4(vite@7.3.1)': + '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@20.19.37)(jiti@2.6.1)(tsx@4.21.0))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) @@ -3659,10 +5303,215 @@ snapshots: '@rolldown/pluginutils': 1.0.0-rc.3 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.3.1 + vite: 7.3.1(@types/node@20.19.37)(jiti@2.6.1)(tsx@4.21.0) + transitivePeerDependencies: + - supports-color + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@4.1.0': + dependencies: + tinyrainbow: 3.1.0 + + '@vitest/snapshot@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + magic-string: 0.30.21 + pathe: 1.1.2 + + '@vitest/snapshot@4.1.0': + dependencies: + '@vitest/pretty-format': 4.1.0 + '@vitest/utils': 4.1.0 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/utils@4.1.0': + dependencies: + '@vitest/pretty-format': 4.1.0 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + + '@wdio/cli@9.25.0(@types/node@20.19.37)(expect-webdriverio@5.6.5)': + dependencies: + '@vitest/snapshot': 2.1.9 + '@wdio/config': 9.25.0 + '@wdio/globals': 9.23.0(expect-webdriverio@5.6.5)(webdriverio@9.25.0) + '@wdio/logger': 9.18.0 + '@wdio/protocols': 9.25.0 + '@wdio/types': 9.25.0 + '@wdio/utils': 9.25.0 + async-exit-hook: 2.0.1 + chalk: 5.6.2 + chokidar: 4.0.3 + create-wdio: 9.25.0(@types/node@20.19.37) + dotenv: 17.3.1 + import-meta-resolve: 4.2.0 + lodash.flattendeep: 4.4.0 + lodash.pickby: 4.6.0 + lodash.union: 4.6.0 + read-pkg-up: 10.1.0 + tsx: 4.21.0 + webdriverio: 9.25.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - bare-abort-controller + - bare-buffer + - bufferutil + - expect-webdriverio + - puppeteer-core + - react-native-b4a + - supports-color + - utf-8-validate + + '@wdio/config@9.25.0': + dependencies: + '@wdio/logger': 9.18.0 + '@wdio/types': 9.25.0 + '@wdio/utils': 9.25.0 + deepmerge-ts: 7.1.5 + glob: 10.5.0 + import-meta-resolve: 4.2.0 + jiti: 2.6.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + - supports-color + + '@wdio/dot-reporter@9.25.0': + dependencies: + '@wdio/reporter': 9.25.0 + '@wdio/types': 9.25.0 + chalk: 5.6.2 + + '@wdio/globals@9.23.0(expect-webdriverio@5.6.5)(webdriverio@9.25.0)': + dependencies: + expect-webdriverio: 5.6.5(@wdio/globals@9.23.0)(@wdio/logger@9.18.0)(webdriverio@9.25.0) + webdriverio: 9.25.0 + + '@wdio/local-runner@9.25.0(@wdio/globals@9.23.0)(webdriverio@9.25.0)': + dependencies: + '@types/node': 20.19.37 + '@wdio/logger': 9.18.0 + '@wdio/repl': 9.16.2 + '@wdio/runner': 9.25.0(expect-webdriverio@5.6.5)(webdriverio@9.25.0) + '@wdio/types': 9.25.0 + '@wdio/xvfb': 9.25.0 + exit-hook: 4.0.0 + expect-webdriverio: 5.6.5(@wdio/globals@9.23.0)(@wdio/logger@9.18.0)(webdriverio@9.25.0) + split2: 4.2.0 + stream-buffers: 3.0.3 + transitivePeerDependencies: + - '@wdio/globals' + - bare-abort-controller + - bare-buffer + - bufferutil + - react-native-b4a + - supports-color + - utf-8-validate + - webdriverio + + '@wdio/logger@9.18.0': + dependencies: + chalk: 5.6.2 + loglevel: 1.9.2 + loglevel-plugin-prefix: 0.8.4 + safe-regex2: 5.1.0 + strip-ansi: 7.2.0 + + '@wdio/mocha-framework@9.25.0': + dependencies: + '@types/mocha': 10.0.10 + '@types/node': 20.19.37 + '@wdio/logger': 9.18.0 + '@wdio/types': 9.25.0 + '@wdio/utils': 9.25.0 + mocha: 10.8.2 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + - supports-color + + '@wdio/protocols@9.25.0': {} + + '@wdio/repl@9.16.2': + dependencies: + '@types/node': 20.19.37 + + '@wdio/reporter@9.25.0': + dependencies: + '@types/node': 20.19.37 + '@wdio/logger': 9.18.0 + '@wdio/types': 9.25.0 + diff: 8.0.3 + object-inspect: 1.13.4 + + '@wdio/runner@9.25.0(expect-webdriverio@5.6.5)(webdriverio@9.25.0)': + dependencies: + '@types/node': 20.19.37 + '@wdio/config': 9.25.0 + '@wdio/dot-reporter': 9.25.0 + '@wdio/globals': 9.23.0(expect-webdriverio@5.6.5)(webdriverio@9.25.0) + '@wdio/logger': 9.18.0 + '@wdio/types': 9.25.0 + '@wdio/utils': 9.25.0 + deepmerge-ts: 7.1.5 + expect-webdriverio: 5.6.5(@wdio/globals@9.23.0)(@wdio/logger@9.18.0)(webdriverio@9.25.0) + webdriver: 9.25.0 + webdriverio: 9.25.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - bufferutil + - react-native-b4a + - supports-color + - utf-8-validate + + '@wdio/spec-reporter@9.25.0': + dependencies: + '@wdio/reporter': 9.25.0 + '@wdio/types': 9.25.0 + chalk: 5.6.2 + easy-table: 1.2.0 + pretty-ms: 9.3.0 + + '@wdio/types@9.25.0': + dependencies: + '@types/node': 20.19.37 + + '@wdio/utils@9.25.0': + dependencies: + '@puppeteer/browsers': 2.13.0 + '@wdio/logger': 9.18.0 + '@wdio/types': 9.25.0 + decamelize: 6.0.1 + deepmerge-ts: 7.1.5 + edgedriver: 6.3.0 + geckodriver: 6.1.0 + get-port: 7.1.0 + import-meta-resolve: 4.2.0 + locate-app: 2.5.0 + mitt: 3.0.1 + safaridriver: 1.0.1 + split2: 4.2.0 + wait-port: 1.1.0 transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a - supports-color + '@wdio/xvfb@9.25.0': + dependencies: + '@wdio/logger': 9.18.0 + + '@zip.js/zip.js@2.8.23': {} + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -3673,6 +5522,8 @@ snapshots: acorn@8.16.0: {} + agent-base@7.1.4: {} + ajv@6.14.0: dependencies: fast-deep-equal: 3.1.3 @@ -3680,10 +5531,20 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + + ansi-styles@6.2.3: {} + any-base@1.1.0: {} anymatch@3.1.3: @@ -3691,31 +5552,108 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + archiver-utils@5.0.2: + dependencies: + glob: 10.5.0 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.17.23 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.7.0 + readdir-glob: 1.1.3 + tar-stream: 3.1.8 + zip-stream: 6.0.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + argparse@2.0.1: {} aria-hidden@1.2.6: dependencies: tslib: 2.8.1 + aria-query@5.3.2: {} + + ast-types@0.13.4: + dependencies: + tslib: 2.8.1 + + async-exit-hook@2.0.1: {} + + async@3.2.6: {} + await-to-js@3.0.0: {} + b4a@1.8.0: {} + balanced-match@1.0.2: {} balanced-match@4.0.4: {} + bare-events@2.8.2: {} + + bare-fs@4.5.5: + dependencies: + bare-events: 2.8.2 + bare-path: 3.0.0 + bare-stream: 2.8.1(bare-events@2.8.2) + bare-url: 2.3.2 + fast-fifo: 1.3.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + bare-os@3.8.0: {} + + bare-path@3.0.0: + dependencies: + bare-os: 3.8.0 + + bare-stream@2.8.1(bare-events@2.8.2): + dependencies: + streamx: 2.23.0 + teex: 1.0.1 + optionalDependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + bare-url@2.3.2: + dependencies: + bare-path: 3.0.0 + base64-js@1.5.1: {} baseline-browser-mapping@2.10.0: {} + basic-ftp@5.2.0: {} + binary-extensions@2.3.0: {} bmp-ts@1.0.9: {} + boolbase@1.0.0: {} + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + brace-expansion@5.0.3: dependencies: balanced-match: 4.0.4 @@ -3726,6 +5664,8 @@ snapshots: browser-fs-access@0.29.1: {} + browser-stdout@1.3.1: {} + browserslist@4.28.1: dependencies: baseline-browser-mapping: 2.10.0 @@ -3734,6 +5674,10 @@ snapshots: node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) + buffer-crc32@0.2.13: {} + + buffer-crc32@1.0.0: {} + buffer@6.0.3: dependencies: base64-js: 1.5.1 @@ -3741,6 +5685,8 @@ snapshots: callsites@3.1.0: {} + camelcase@6.3.0: {} + caniuse-lite@1.0.30001774: {} canvas-roundrect-polyfill@0.0.1: {} @@ -3750,8 +5696,35 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.6.2: {} + character-entities@2.0.2: {} + chardet@2.1.1: {} + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.2.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + encoding-sniffer: 0.2.1 + htmlparser2: 10.1.0 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 7.24.1 + whatwg-mimetype: 4.0.0 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -3764,30 +5737,95 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - clsx@1.1.1: {} - - color-convert@2.0.1: + chokidar@4.0.3: dependencies: - color-name: 1.1.4 + readdirp: 4.1.2 - color-name@1.1.4: {} + ci-info@4.4.0: {} - commander@14.0.3: {} + cli-width@4.1.0: {} - commander@7.2.0: {} + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 - commander@8.3.0: {} + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: + optional: true + + clsx@1.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@14.0.3: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + commander@9.5.0: {} + + compress-commons@6.0.2: + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 concat-map@0.0.1: {} convert-source-map@2.0.0: {} + core-util-is@1.0.3: {} + cose-base@1.0.3: dependencies: layout-base: 1.0.2 crc-32@0.3.0: {} + crc-32@1.2.2: {} + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.7.0 + + create-wdio@9.25.0(@types/node@20.19.37): + dependencies: + chalk: 5.6.2 + commander: 14.0.3 + cross-spawn: 7.0.6 + ejs: 3.1.10 + execa: 9.6.1 + import-meta-resolve: 4.2.0 + inquirer: 12.11.1(@types/node@20.19.37) + normalize-package-data: 7.0.1 + read-pkg-up: 10.1.0 + recursive-readdir: 2.2.3 + semver: 7.7.4 + type-fest: 4.41.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + + cross-env@10.1.0: + dependencies: + '@epic-web/invariant': 1.0.0 + cross-spawn: 7.0.6 + cross-env@7.0.3: dependencies: cross-spawn: 7.0.6 @@ -3798,6 +5836,20 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-shorthand-properties@1.1.2: {} + + css-value@0.0.1: {} + + css-what@6.2.2: {} + csstype@3.2.3: {} cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): @@ -3979,18 +6031,41 @@ snapshots: d3: 7.9.0 lodash-es: 4.17.23 + data-uri-to-buffer@6.0.2: {} + dayjs@1.11.19: {} - debug@4.4.3: + debug@4.4.3(supports-color@8.1.1): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 + + decamelize@4.0.0: {} + + decamelize@6.0.1: {} decode-named-character-reference@1.3.0: dependencies: character-entities: 2.0.2 + deep-eql@5.0.2: {} + deep-is@0.1.4: {} + deepmerge-ts@7.1.5: {} + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + optional: true + + degenerator@5.0.1: + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + delaunator@5.0.1: dependencies: robust-predicates: 3.0.2 @@ -4001,12 +6076,87 @@ snapshots: diff@5.2.2: {} + diff@8.0.3: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + dompurify@3.1.6: {} + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dotenv@17.3.1: {} + + eastasianwidth@0.2.0: {} + + easy-table@1.2.0: + dependencies: + ansi-regex: 5.0.1 + optionalDependencies: + wcwidth: 1.0.1 + + edge-paths@3.0.5: + dependencies: + '@types/which': 2.0.2 + which: 2.0.2 + + edgedriver@6.3.0: + dependencies: + '@wdio/logger': 9.18.0 + '@zip.js/zip.js': 2.8.23 + decamelize: 6.0.1 + edge-paths: 3.0.5 + fast-xml-parser: 5.5.5 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + which: 6.0.1 + transitivePeerDependencies: + - supports-color + + ejs@3.1.10: + dependencies: + jake: 10.9.4 + electron-to-chromium@1.5.302: {} elkjs@0.9.3: {} + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encoding-sniffer@0.2.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + entities@4.5.0: {} + + entities@6.0.1: {} + + entities@7.0.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + es6-promise-pool@2.5.0: {} esbuild@0.27.3: @@ -4040,22 +6190,32 @@ snapshots: escalade@3.2.0: {} + escape-string-regexp@2.0.0: {} + escape-string-regexp@4.0.0: {} - eslint-plugin-react-hooks@7.0.1(eslint@9.39.3): + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + + eslint-plugin-react-hooks@7.0.1(eslint@9.39.3(jiti@2.6.1)): dependencies: '@babel/core': 7.29.0 '@babel/parser': 7.29.0 - eslint: 9.39.3 + eslint: 9.39.3(jiti@2.6.1) hermes-parser: 0.25.1 zod: 3.25.76 zod-validation-error: 4.0.2(zod@3.25.76) transitivePeerDependencies: - supports-color - eslint-plugin-react-refresh@0.5.2(eslint@9.39.3): + eslint-plugin-react-refresh@0.5.2(eslint@9.39.3(jiti@2.6.1)): dependencies: - eslint: 9.39.3 + eslint: 9.39.3(jiti@2.6.1) eslint-scope@8.4.0: dependencies: @@ -4068,9 +6228,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@9.39.3: + eslint@9.39.3(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.1 '@eslint/config-helpers': 0.4.2 @@ -4085,7 +6245,7 @@ snapshots: ajv: 6.14.0 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -4104,6 +6264,8 @@ snapshots: minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 transitivePeerDependencies: - supports-color @@ -4113,6 +6275,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 4.2.1 + esprima@4.0.1: {} + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -4127,20 +6291,94 @@ snapshots: event-target-shim@5.0.1: {} + events-universal@1.0.1: + dependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + events@3.3.0: {} + execa@9.6.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + exif-parser@0.1.12: {} + exit-hook@4.0.0: {} + + expect-webdriverio@5.6.5(@wdio/globals@9.23.0)(@wdio/logger@9.18.0)(webdriverio@9.25.0): + dependencies: + '@vitest/snapshot': 4.1.0 + '@wdio/globals': 9.23.0(expect-webdriverio@5.6.5)(webdriverio@9.25.0) + '@wdio/logger': 9.18.0 + deep-eql: 5.0.2 + expect: 30.3.0 + jest-matcher-utils: 30.3.0 + webdriverio: 9.25.0 + + expect@30.3.0: + dependencies: + '@jest/expect-utils': 30.3.0 + '@jest/get-type': 30.1.0 + jest-matcher-utils: 30.3.0 + jest-message-util: 30.3.0 + jest-mock: 30.3.0 + jest-util: 30.3.0 + + extract-zip@2.0.1: + dependencies: + debug: 4.4.3(supports-color@8.1.1) + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@2.0.1: {} + fast-deep-equal@3.1.3: {} + fast-fifo@1.3.2: {} + fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} + fast-xml-builder@1.1.3: + dependencies: + path-expression-matcher: 1.1.3 + + fast-xml-parser@5.5.5: + dependencies: + fast-xml-builder: 1.1.3 + path-expression-matcher: 1.1.3 + strnum: 2.2.0 + + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -4151,6 +6389,10 @@ snapshots: strtok3: 6.3.0 token-types: 4.2.1 + filelist@1.0.6: + dependencies: + minimatch: 5.1.9 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -4160,24 +6402,74 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + flat-cache@4.0.1: dependencies: flatted: 3.3.4 keyv: 4.5.4 + flat@5.0.2: {} + flatted@3.3.4: {} + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + fractional-indexing@3.2.0: {} + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true fuzzy@0.1.3: {} + geckodriver@6.1.0: + dependencies: + '@wdio/logger': 9.18.0 + '@zip.js/zip.js': 2.8.23 + decamelize: 6.0.1 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + modern-tar: 0.7.5 + transitivePeerDependencies: + - supports-color + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + get-nonce@1.0.1: {} + get-port@7.1.0: {} + + get-stream@5.2.0: + dependencies: + pump: 3.0.4 + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + get-tsconfig@4.13.6: + dependencies: + resolve-pkg-maps: 1.0.0 + + get-uri@6.0.5: + dependencies: + basic-ftp: 5.2.0 + data-uri-to-buffer: 6.0.2 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + gifwrap@0.10.1: dependencies: image-q: 4.0.0 @@ -4191,32 +6483,92 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + glob@13.0.6: dependencies: minimatch: 10.2.4 minipass: 7.1.3 path-scurry: 2.0.2 + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.9 + once: 1.4.0 + globals@14.0.0: {} globals@17.4.0: {} glur@1.1.2: {} + graceful-fs@4.2.11: {} + + grapheme-splitter@1.0.4: {} + hachure-fill@0.5.2: {} has-flag@4.0.0: {} + he@1.2.0: {} + hermes-estree@0.25.1: {} hermes-parser@0.25.1: dependencies: hermes-estree: 0.25.1 + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + + hosted-git-info@8.1.0: + dependencies: + lru-cache: 10.4.3 + + htmlfy@0.8.1: {} + + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + human-signals@8.0.1: {} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -4231,6 +6583,8 @@ snapshots: dependencies: '@types/node': 16.9.1 + immediate@3.0.6: {} + immutable@4.3.7: {} import-fresh@3.3.1: @@ -4238,28 +6592,124 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 + import-meta-resolve@4.2.0: {} + imurmurhash@0.1.4: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + inherits@2.0.4: {} + inquirer@12.11.1(@types/node@20.19.37): + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@20.19.37) + '@inquirer/prompts': 7.10.1(@types/node@20.19.37) + '@inquirer/type': 3.0.10(@types/node@20.19.37) + mute-stream: 2.0.0 + run-async: 4.0.6 + rxjs: 7.8.2 + optionalDependencies: + '@types/node': 20.19.37 + internmap@1.0.1: {} internmap@2.0.3: {} + ip-address@10.1.0: {} + + is-arrayish@0.2.1: {} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 is-number@7.0.0: {} + is-plain-obj@2.1.0: {} + + is-plain-obj@4.1.0: {} + + is-stream@2.0.1: {} + + is-stream@4.0.1: {} + + is-unicode-supported@0.1.0: {} + + is-unicode-supported@2.1.0: {} + + isarray@1.0.0: {} + isexe@2.0.0: {} + isexe@4.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jake@10.9.4: + dependencies: + async: 3.2.6 + filelist: 1.0.6 + picocolors: 1.1.1 + + jest-diff@30.3.0: + dependencies: + '@jest/diff-sequences': 30.3.0 + '@jest/get-type': 30.1.0 + chalk: 4.1.2 + pretty-format: 30.3.0 + + jest-matcher-utils@30.3.0: + dependencies: + '@jest/get-type': 30.1.0 + chalk: 4.1.2 + jest-diff: 30.3.0 + pretty-format: 30.3.0 + + jest-message-util@30.3.0: + dependencies: + '@babel/code-frame': 7.29.0 + '@jest/types': 30.3.0 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + picomatch: 4.0.3 + pretty-format: 30.3.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@30.3.0: + dependencies: + '@jest/types': 30.3.0 + '@types/node': 16.9.1 + jest-util: 30.3.0 + + jest-regex-util@30.0.1: {} + + jest-util@30.3.0: + dependencies: + '@jest/types': 30.3.0 + '@types/node': 16.9.1 + chalk: 4.1.2 + ci-info: 4.4.0 + graceful-fs: 4.2.11 + picomatch: 4.0.3 + jimp@1.6.0: dependencies: '@jimp/core': 1.6.0 @@ -4290,6 +6740,8 @@ snapshots: '@jimp/types': 1.6.0 '@jimp/utils': 1.6.0 + jiti@2.6.1: {} + jotai-scope@0.7.2(jotai@2.11.0(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): dependencies: jotai: 2.11.0(@types/react@19.2.14)(react@19.2.4) @@ -4312,12 +6764,21 @@ snapshots: json-buffer@3.0.1: {} + json-parse-even-better-errors@3.0.2: {} + json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} json5@2.2.3: {} + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + katex@0.16.33: dependencies: commander: 8.3.0 @@ -4332,29 +6793,78 @@ snapshots: layout-base@1.0.2: {} + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 + lie@3.3.0: + dependencies: + immediate: 3.0.6 + + lines-and-columns@2.0.4: {} + + locate-app@2.5.0: + dependencies: + '@promptbook/utils': 0.69.5 + type-fest: 4.26.0 + userhome: 1.0.1 + locate-path@6.0.0: dependencies: p-locate: 5.0.0 + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + lodash-es@4.17.23: {} + lodash.clonedeep@4.5.0: {} + lodash.debounce@4.0.8: {} + lodash.flattendeep@4.4.0: {} + lodash.merge@4.6.2: {} + lodash.pickby@4.6.0: {} + lodash.throttle@4.1.1: {} + lodash.union@4.6.0: {} + + lodash.zip@4.2.0: {} + + lodash@4.17.23: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + loglevel-plugin-prefix@0.8.4: {} + + loglevel@1.9.2: {} + + lru-cache@10.4.3: {} + lru-cache@11.2.6: {} lru-cache@5.1.1: dependencies: yallist: 3.1.1 + lru-cache@7.18.3: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + mdast-util-from-markdown@1.3.1: dependencies: '@types/mdast': 3.0.15 @@ -4515,7 +7025,7 @@ snapshots: micromark@3.2.0: dependencies: '@types/debug': 4.1.12 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) decode-named-character-reference: 1.3.0 micromark-core-commonmark: 1.1.0 micromark-factory-space: 1.1.0 @@ -4544,8 +7054,43 @@ snapshots: dependencies: brace-expansion: 1.1.12 + minimatch@5.1.9: + dependencies: + brace-expansion: 2.0.2 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.0.2 + minipass@7.1.3: {} + mitt@3.0.1: {} + + mocha@10.8.2: + dependencies: + ansi-colors: 4.1.3 + browser-stdout: 1.3.1 + chokidar: 3.6.0 + debug: 4.4.3(supports-color@8.1.1) + diff: 5.2.2 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 8.1.0 + he: 1.2.0 + js-yaml: 4.1.1 + log-symbols: 4.1.0 + minimatch: 5.1.9 + ms: 2.1.3 + serialize-javascript: 6.0.2 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.5.1 + yargs: 16.2.0 + yargs-parser: 20.2.9 + yargs-unparser: 2.0.0 + + modern-tar@0.7.5: {} + mri@1.2.0: {} ms@2.1.3: {} @@ -4555,6 +7100,8 @@ snapshots: glur: 1.1.2 object-assign: 4.1.1 + mute-stream@2.0.0: {} + nanoid@3.3.11: {} nanoid@3.3.3: {} @@ -4563,16 +7110,45 @@ snapshots: natural-compare@1.4.0: {} + netmask@2.0.2: {} + node-releases@2.0.27: {} non-layered-tidy-tree-layout@2.0.2: {} + normalize-package-data@6.0.2: + dependencies: + hosted-git-info: 7.0.2 + semver: 7.7.4 + validate-npm-package-license: 3.0.4 + + normalize-package-data@7.0.1: + dependencies: + hosted-git-info: 8.1.0 + semver: 7.7.4 + validate-npm-package-license: 3.0.4 + normalize-path@3.0.0: {} + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + object-assign@4.1.1: {} + object-inspect@1.13.4: {} + omggif@1.0.10: {} + once@1.4.0: + dependencies: + wrappy: 1.0.2 + open-color@1.9.1: {} optionator@0.9.4: @@ -4588,10 +7164,38 @@ snapshots: dependencies: yocto-queue: 0.1.0 + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + pac-proxy-agent@7.2.0: + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + get-uri: 6.0.5 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + pac-resolver: 7.0.1 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + pac-resolver@7.0.1: + dependencies: + degenerator: 5.0.1 + netmask: 2.0.2 + + package-json-from-dist@1.0.1: {} + pako@1.0.11: {} pako@2.0.3: {} @@ -4609,19 +7213,59 @@ snapshots: xml-parse-from-string: 1.0.1 xml2js: 0.5.0 + parse-json@7.1.1: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 3.0.2 + lines-and-columns: 2.0.4 + type-fest: 3.13.1 + + parse-ms@4.0.0: {} + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.3.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + path-data-parser@0.1.0: {} path-exists@4.0.0: {} + path-exists@5.0.0: {} + + path-expression-matcher@1.1.3: {} + path-key@3.1.1: {} + path-key@4.0.0: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + path-scurry@2.0.2: dependencies: lru-cache: 11.2.6 minipass: 7.1.3 + pathe@1.1.2: {} + + pathe@2.0.3: {} + peek-readable@4.1.0: {} + pend@1.2.0: {} + perfect-freehand@1.2.0: {} pica@7.1.1: @@ -4676,17 +7320,59 @@ snapshots: prettier@3.8.1: {} + pretty-format@30.3.0: + dependencies: + '@jest/schemas': 30.0.5 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + pretty-ms@9.3.0: + dependencies: + parse-ms: 4.0.0 + + process-nextick-args@2.0.1: {} + process@0.11.10: {} + progress@2.0.3: {} + + proxy-agent@6.5.0: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 7.18.3 + pac-proxy-agent: 7.2.0 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + proxy-from-env@1.1.0: {} + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + punycode@2.3.1: {} pwacompat@2.0.17: {} + query-selector-shadow-dom@1.0.1: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + react-dom@19.2.4(react@19.2.4): dependencies: react: 19.2.4 scheduler: 0.27.0 + react-is@18.3.1: {} + react-refresh@0.18.0: {} react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.4): @@ -4718,6 +7404,29 @@ snapshots: react@19.2.4: {} + read-pkg-up@10.1.0: + dependencies: + find-up: 6.3.0 + read-pkg: 8.1.0 + type-fest: 4.41.0 + + read-pkg@8.1.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 6.0.2 + parse-json: 7.1.1 + type-fest: 4.41.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@4.7.0: dependencies: abort-controller: 3.0.0 @@ -4730,12 +7439,34 @@ snapshots: dependencies: readable-stream: 4.7.0 + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.9 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 + readdirp@4.1.2: {} + + recursive-readdir@2.2.3: + dependencies: + minimatch: 3.1.5 + + require-directory@2.1.1: {} + resolve-from@4.0.0: {} + resolve-pkg-maps@1.0.0: {} + + resq@1.11.0: + dependencies: + fast-deep-equal: 2.0.1 + + ret@0.5.0: {} + + rgb2hex@0.2.5: {} + robust-predicates@3.0.2: {} rollup@4.59.0: @@ -4776,14 +7507,28 @@ snapshots: points-on-curve: 0.2.0 points-on-path: 0.2.1 + run-async@4.0.6: {} + rw@1.3.3: {} + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + sade@1.8.1: dependencies: mri: 1.2.0 + safaridriver@1.0.1: {} + + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} + safe-regex2@5.1.0: + dependencies: + ret: 0.5.0 + safer-buffer@2.1.2: {} sass@1.51.0: @@ -4800,24 +7545,117 @@ snapshots: semver@7.7.4: {} + serialize-error@12.0.0: + dependencies: + type-fest: 4.41.0 + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + setimmediate@1.0.5: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + signal-exit@4.1.0: {} + simple-xml-to-json@1.2.3: {} + slash@3.0.0: {} + sliced@1.0.1: {} + smart-buffer@4.2.0: {} + + socks-proxy-agent@8.0.5: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + socks: 2.8.7 + transitivePeerDependencies: + - supports-color + + socks@2.8.7: + dependencies: + ip-address: 10.1.0 + smart-buffer: 4.2.0 + source-map-js@1.2.1: {} + source-map@0.6.1: + optional: true + + spacetrim@0.11.59: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.23 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 + + spdx-license-ids@3.0.23: {} + + split2@4.2.0: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + stream-buffers@3.0.3: {} + + streamx@2.23.0: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.7 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-final-newline@4.0.0: {} + strip-json-comments@3.1.1: {} + strnum@2.2.0: {} + strtok3@6.3.0: dependencies: '@tokenizer/token': 0.3.0 @@ -4829,6 +7667,46 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + tar-fs@3.1.2: + dependencies: + pump: 3.0.4 + tar-stream: 3.1.8 + optionalDependencies: + bare-fs: 4.5.5 + bare-path: 3.0.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + tar-stream@3.1.8: + dependencies: + b4a: 1.8.0 + bare-fs: 4.5.5 + fast-fifo: 1.3.2 + streamx: 2.23.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + teex@1.0.1: + dependencies: + streamx: 2.23.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + text-decoder@1.2.7: + dependencies: + b4a: 1.8.0 + transitivePeerDependencies: + - react-native-b4a + tinycolor2@1.6.0: {} tinyglobby@0.2.15: @@ -4836,6 +7714,10 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyrainbow@1.2.0: {} + + tinyrainbow@3.1.0: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -4853,6 +7735,13 @@ snapshots: tslib@2.8.1: {} + tsx@4.21.0: + dependencies: + esbuild: 0.27.3 + get-tsconfig: 4.13.6 + optionalDependencies: + fsevents: 2.3.3 + tunnel-rat@0.1.2(@types/react@19.2.14)(react@19.2.4): dependencies: zustand: 4.5.7(@types/react@19.2.14)(react@19.2.4) @@ -4865,19 +7754,33 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.56.1(eslint@9.39.3)(typescript@5.9.3): + type-fest@3.13.1: {} + + type-fest@4.26.0: {} + + type-fest@4.41.0: {} + + typescript-eslint@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@5.9.3))(eslint@9.39.3)(typescript@5.9.3) - '@typescript-eslint/parser': 8.56.1(eslint@9.39.3)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@9.39.3)(typescript@5.9.3) - eslint: 9.39.3 + '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color typescript@5.9.3: {} + undici-types@6.21.0: {} + + undici@6.24.0: {} + + undici@7.24.1: {} + + unicorn-magic@0.3.0: {} + unist-util-stringify-position@3.0.3: dependencies: '@types/unist': 2.0.11 @@ -4892,6 +7795,8 @@ snapshots: dependencies: punycode: 2.3.1 + urlpattern-polyfill@10.1.0: {} + use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.4): dependencies: react: 19.2.4 @@ -4911,10 +7816,14 @@ snapshots: dependencies: react: 19.2.4 + userhome@1.0.1: {} + utif2@4.1.0: dependencies: pako: 1.0.11 + util-deprecate@1.0.2: {} + uuid@9.0.1: {} uvu@0.5.6: @@ -4924,7 +7833,12 @@ snapshots: kleur: 4.1.5 sade: 1.8.1 - vite@7.3.1: + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + vite@7.3.1(@types/node@20.19.37)(jiti@2.6.1)(tsx@4.21.0): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -4933,18 +7847,124 @@ snapshots: rollup: 4.59.0 tinyglobby: 0.2.15 optionalDependencies: + '@types/node': 20.19.37 fsevents: 2.3.3 + jiti: 2.6.1 + tsx: 4.21.0 + + wait-port@1.1.0: + dependencies: + chalk: 4.1.2 + commander: 9.5.0 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + optional: true web-worker@1.5.0: {} + webdriver@9.25.0: + dependencies: + '@types/node': 20.19.37 + '@types/ws': 8.18.1 + '@wdio/config': 9.25.0 + '@wdio/logger': 9.18.0 + '@wdio/protocols': 9.25.0 + '@wdio/types': 9.25.0 + '@wdio/utils': 9.25.0 + deepmerge-ts: 7.1.5 + https-proxy-agent: 7.0.6 + undici: 6.24.0 + ws: 8.19.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - bufferutil + - react-native-b4a + - supports-color + - utf-8-validate + + webdriverio@9.25.0: + dependencies: + '@types/node': 20.19.37 + '@types/sinonjs__fake-timers': 8.1.5 + '@wdio/config': 9.25.0 + '@wdio/logger': 9.18.0 + '@wdio/protocols': 9.25.0 + '@wdio/repl': 9.16.2 + '@wdio/types': 9.25.0 + '@wdio/utils': 9.25.0 + archiver: 7.0.1 + aria-query: 5.3.2 + cheerio: 1.2.0 + css-shorthand-properties: 1.1.2 + css-value: 0.0.1 + grapheme-splitter: 1.0.4 + htmlfy: 0.8.1 + is-plain-obj: 4.1.0 + jszip: 3.10.1 + lodash.clonedeep: 4.5.0 + lodash.zip: 4.2.0 + query-selector-shadow-dom: 1.0.1 + resq: 1.11.0 + rgb2hex: 0.2.5 + serialize-error: 12.0.0 + urlpattern-polyfill: 10.1.0 + webdriver: 9.25.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - bufferutil + - react-native-b4a + - supports-color + - utf-8-validate + webworkify@1.5.0: {} + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + which@2.0.2: dependencies: isexe: 2.0.0 + which@6.0.1: + dependencies: + isexe: 4.0.0 + word-wrap@1.2.5: {} + workerpool@6.5.1: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} + + ws@8.19.0: {} + xml-parse-from-string@1.0.1: {} xml2js@0.5.0: @@ -4954,10 +7974,60 @@ snapshots: xmlbuilder@11.0.1: {} + y18n@5.0.8: {} + yallist@3.1.1: {} + yargs-parser@20.2.9: {} + + yargs-parser@21.1.1: {} + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + yocto-queue@0.1.0: {} + yocto-queue@1.2.2: {} + + yoctocolors-cjs@2.1.3: {} + + yoctocolors@2.1.2: {} + + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.7.0 + zod-validation-error@4.0.2(zod@3.25.76): dependencies: zod: 3.25.76 diff --git a/src-tauri/src/commands/board_content.rs b/src-tauri/src/commands/board_content.rs new file mode 100644 index 0000000..0c0baf4 --- /dev/null +++ b/src-tauri/src/commands/board_content.rs @@ -0,0 +1,84 @@ +use chrono::Utc; +use rusqlite::params; +use tauri::AppHandle; + +use crate::db::{board_id_exists, default_board_data, load_board_data_value, open_db}; + +#[tauri::command] +pub(crate) fn save_board_data( + app: AppHandle, + board_id: String, + data: String, +) -> Result<(), String> { + let mut conn = open_db(&app)?; + let tx = conn.transaction().map_err(|error| error.to_string())?; + + let updated = tx + .execute( + "UPDATE boards SET updated_at = ?1 WHERE id = ?2", + params![Utc::now().timestamp_millis(), board_id], + ) + .map_err(|error| error.to_string())?; + if updated == 0 { + return Err("Board not found".to_string()); + } + + tx.execute( + "INSERT OR REPLACE INTO board_data (board_id, data) VALUES (?1, ?2)", + params![board_id, data], + ) + .map_err(|error| error.to_string())?; + + tx.commit().map_err(|error| error.to_string())?; + Ok(()) +} + +#[tauri::command] +pub(crate) fn load_board_data(app: AppHandle, board_id: String) -> Result { + let conn = open_db(&app)?; + if let Some(data) = load_board_data_value(&conn, &board_id)? { + return Ok(data); + } + if !board_id_exists(&conn, &board_id)? { + return Err("Board not found".to_string()); + } + Ok(default_board_data()) +} + +#[tauri::command] +pub(crate) fn set_collaboration_link( + app: AppHandle, + board_id: String, + link: Option, +) -> Result<(), String> { + let conn = open_db(&app)?; + let updated = conn + .execute( + "UPDATE boards SET collaboration_link = ?1, updated_at = ?2 WHERE id = ?3", + params![link, Utc::now().timestamp_millis(), board_id], + ) + .map_err(|error| error.to_string())?; + if updated == 0 { + return Err("Board not found".to_string()); + } + Ok(()) +} + +#[tauri::command] +pub(crate) fn save_board_thumbnail( + app: AppHandle, + board_id: String, + thumbnail: Option, +) -> Result<(), String> { + let conn = open_db(&app)?; + let updated = conn + .execute( + "UPDATE boards SET thumbnail = ?1 WHERE id = ?2", + params![thumbnail, board_id], + ) + .map_err(|error| error.to_string())?; + if updated == 0 { + return Err("Board not found".to_string()); + } + Ok(()) +} diff --git a/src-tauri/src/commands/board_transfer.rs b/src-tauri/src/commands/board_transfer.rs new file mode 100644 index 0000000..6a4cfe6 --- /dev/null +++ b/src-tauri/src/commands/board_transfer.rs @@ -0,0 +1,240 @@ +use chrono::Utc; +use serde_json::Value as JsonValue; +use std::collections::HashSet; +use std::fs; +use tauri::AppHandle; + +use crate::commands::board_content::save_board_data; +use crate::commands::boards::create_board; +use crate::db::{ + default_board_data, get_setting, load_board_data_value, load_boards_index_from_db, open_db, + set_setting, +}; +use crate::models::{ + Board, BoardListItem, BoardsExportEntry, BoardsExportFile, BoardsImportResult, +}; + +const ACTIVE_BOARD_SETTING_KEY: &str = "active_board_id"; + +#[tauri::command] +pub(crate) fn export_boards(app: AppHandle, file_path: String) -> Result<(), String> { + let conn = open_db(&app)?; + let index = load_boards_index_from_db(&conn)?; + + let mut boards = Vec::new(); + let mut seen = HashSet::new(); + + for item in &index.items { + export_item_boards(&conn, item, &mut seen, &mut boards)?; + } + + let export_file = BoardsExportFile { + version: 1, + exported_at: Utc::now(), + boards, + }; + + let payload = serde_json::to_string_pretty(&export_file).map_err(|error| error.to_string())?; + fs::write(file_path, payload).map_err(|error| error.to_string())?; + Ok(()) +} + +#[tauri::command] +pub(crate) fn import_boards( + app: AppHandle, + file_path: String, + selected_indices: Vec, +) -> Result { + let payload = fs::read_to_string(file_path).map_err(|error| error.to_string())?; + let export_file: BoardsExportFile = + serde_json::from_str(&payload).map_err(|error| error.to_string())?; + + let conn = open_db(&app)?; + let active_before = get_setting(&conn, ACTIVE_BOARD_SETTING_KEY)?; + + let (existing_ids, mut used_names) = load_existing_board_ids_and_names(&conn)?; + let selected: HashSet = selected_indices.into_iter().collect(); + let mut seen_ids = existing_ids; + let mut imported = 0; + let mut skipped = 0; + + for (index, entry) in export_file.boards.iter().enumerate() { + if !selected.contains(&index) { + continue; + } + + let did_import = import_selected_entry(&app, entry, &mut seen_ids, &mut used_names)?; + if did_import { + imported += 1; + } else { + skipped += 1; + } + } + + restore_active_board(&conn, active_before)?; + + Ok(BoardsImportResult { imported, skipped }) +} + +fn export_item_boards( + conn: &rusqlite::Connection, + item: &BoardListItem, + seen: &mut HashSet, + export_entries: &mut Vec, +) -> Result<(), String> { + match item { + BoardListItem::Board(board) => export_board_if_new(conn, board, seen, export_entries), + BoardListItem::Folder(folder) => { + for board in &folder.items { + export_board_if_new(conn, board, seen, export_entries)?; + } + Ok(()) + } + } +} + +fn export_board_if_new( + conn: &rusqlite::Connection, + board: &Board, + seen: &mut HashSet, + export_entries: &mut Vec, +) -> Result<(), String> { + if !seen.insert(board.id.clone()) { + return Ok(()); + } + + export_entries.push(build_export_entry(conn, board)?); + Ok(()) +} + +fn import_selected_entry( + app: &AppHandle, + entry: &BoardsExportEntry, + seen_ids: &mut HashSet, + used_names: &mut HashSet, +) -> Result { + let final_name = resolve_import_name(entry, seen_ids, used_names); + let created = match create_board(app.clone(), final_name.clone()) { + Ok(board) => board, + Err(_) => return Ok(false), + }; + + persist_imported_board_data(app.clone(), &created.id, entry)?; + register_imported_identity(entry, &final_name, seen_ids, used_names); + Ok(true) +} + +fn persist_imported_board_data( + app: AppHandle, + created_board_id: &str, + entry: &BoardsExportEntry, +) -> Result<(), String> { + let Some(data_value) = entry.data.as_ref() else { + return Ok(()); + }; + + if data_value.is_null() { + return Ok(()); + } + + let data_str = data_value.to_string(); + save_board_data(app, created_board_id.to_string(), data_str) +} + +fn load_existing_board_ids_and_names( + conn: &rusqlite::Connection, +) -> Result<(HashSet, HashSet), String> { + let mut stmt = conn + .prepare("SELECT id, name FROM boards") + .map_err(|error| error.to_string())?; + let mut rows = stmt.query([]).map_err(|error| error.to_string())?; + let mut ids = HashSet::new(); + let mut used_names = HashSet::new(); + + while let Some(row) = rows.next().map_err(|error| error.to_string())? { + let id: String = row.get(0).map_err(|error| error.to_string())?; + let name: String = row.get(1).map_err(|error| error.to_string())?; + + ids.insert(id); + let name_key = name.trim().to_lowercase(); + if !name_key.is_empty() { + used_names.insert(name_key); + } + } + + Ok((ids, used_names)) +} + +fn normalize_import_name(name: &str) -> String { + if name.trim().is_empty() { + "Imported board".to_string() + } else { + name.trim().to_string() + } +} + +fn make_copy_name(base: &str, used_names: &HashSet) -> String { + let mut candidate = format!("{} (Copy)", base); + let mut counter = 2; + while used_names.contains(&candidate.to_lowercase()) { + candidate = format!("{} (Copy {})", base, counter); + counter += 1; + } + candidate +} + +fn resolve_import_name( + entry: &BoardsExportEntry, + seen_ids: &HashSet, + used_names: &HashSet, +) -> String { + let base_name = normalize_import_name(&entry.name); + let has_id = !entry.id.trim().is_empty(); + let is_duplicate = has_id && seen_ids.contains(&entry.id); + if is_duplicate { + make_copy_name(&base_name, used_names) + } else { + base_name + } +} + +fn register_imported_identity( + entry: &BoardsExportEntry, + final_name: &str, + seen_ids: &mut HashSet, + used_names: &mut HashSet, +) { + let has_id = !entry.id.trim().is_empty(); + used_names.insert(final_name.to_lowercase()); + if has_id { + seen_ids.insert(entry.id.clone()); + } +} + +fn restore_active_board( + conn: &rusqlite::Connection, + active_before: Option, +) -> Result<(), String> { + if let Some(active_id) = active_before { + set_setting(conn, ACTIVE_BOARD_SETTING_KEY, Some(&active_id))?; + } + Ok(()) +} + +fn build_export_entry( + conn: &rusqlite::Connection, + board: &Board, +) -> Result { + let data_str = load_board_data_value(conn, &board.id)?.unwrap_or_else(default_board_data); + let data_json: JsonValue = serde_json::from_str(&data_str).unwrap_or(JsonValue::Null); + + Ok(BoardsExportEntry { + id: board.id.clone(), + name: board.name.clone(), + created_at: board.created_at, + updated_at: board.updated_at, + collaboration_link: board.collaboration_link.clone(), + thumbnail: board.thumbnail.clone(), + data: Some(data_json), + }) +} diff --git a/src-tauri/src/commands/boards.rs b/src-tauri/src/commands/boards.rs index bbe23f0..62c4d9f 100644 --- a/src-tauri/src/commands/boards.rs +++ b/src-tauri/src/commands/boards.rs @@ -1,8 +1,5 @@ use chrono::Utc; use rusqlite::params; -use serde_json::Value as JsonValue; -use std::collections::HashSet; -use std::fs; use tauri::AppHandle; use uuid::Uuid; @@ -11,9 +8,11 @@ use crate::db::{ get_board_by_id, get_setting, load_board_data_value, load_boards_index_from_db, normalize_active_board_id, open_db, set_setting, }; -use crate::models::{ - Board, BoardListItem, BoardsExportEntry, BoardsExportFile, BoardsImportResult, BoardsIndex, -}; +use crate::models::{Board, BoardListItem, BoardsIndex}; + +const ACTIVE_BOARD_SETTING_KEY: &str = "active_board_id"; + +struct BoardDataPayload(String); #[tauri::command] pub(crate) fn get_boards(app: AppHandle) -> Result { @@ -35,17 +34,17 @@ pub(crate) fn create_board(app: AppHandle, name: String) -> Result Result<(), String> { let mut conn = open_db(&app)?; - let tx = conn.transaction().map_err(|e| e.to_string())?; + let tx = conn.transaction().map_err(|error| error.to_string())?; tx.execute( "DELETE FROM board_data WHERE board_id = ?1", params![board_id], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; let deleted = tx .execute("DELETE FROM boards WHERE id = ?1", params![board_id]) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; if deleted == 0 { return Err("Board not found".to_string()); } @@ -90,30 +89,30 @@ pub(crate) fn delete_board(app: AppHandle, board_id: String) -> Result<(), Strin "DELETE FROM index_items WHERE item_type = 'board' AND item_id = ?1", params![board_id], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; tx.execute( "DELETE FROM folder_items WHERE board_id = ?1", params![board_id], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; tx.execute( "DELETE FROM folders WHERE id NOT IN (SELECT DISTINCT folder_id FROM folder_items)", [], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; tx.execute( "DELETE FROM index_items WHERE item_type = 'folder' AND item_id NOT IN (SELECT id FROM folders)", [], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; - let active_id = get_setting(&tx, "active_board_id")?; + let active_id = get_setting(&tx, ACTIVE_BOARD_SETTING_KEY)?; if active_id.as_deref() == Some(&board_id) { let next_id = first_board_id_from_db(&tx)?; - set_setting(&tx, "active_board_id", next_id.as_deref())?; + set_setting(&tx, ACTIVE_BOARD_SETTING_KEY, next_id.as_deref())?; } - tx.commit().map_err(|e| e.to_string())?; + tx.commit().map_err(|error| error.to_string())?; Ok(()) } @@ -123,67 +122,7 @@ pub(crate) fn set_active_board(app: AppHandle, board_id: String) -> Result<(), S if !board_id_exists(&conn, &board_id)? { return Err("Board not found".to_string()); } - set_setting(&conn, "active_board_id", Some(&board_id))?; - Ok(()) -} - -#[tauri::command] -pub(crate) fn save_board_data( - app: AppHandle, - board_id: String, - data: String, -) -> Result<(), String> { - let mut conn = open_db(&app)?; - let tx = conn.transaction().map_err(|e| e.to_string())?; - - let updated = tx - .execute( - "UPDATE boards SET updated_at = ?1 WHERE id = ?2", - params![Utc::now().timestamp_millis(), board_id], - ) - .map_err(|e| e.to_string())?; - if updated == 0 { - return Err("Board not found".to_string()); - } - - tx.execute( - "INSERT OR REPLACE INTO board_data (board_id, data) VALUES (?1, ?2)", - params![board_id, data], - ) - .map_err(|e| e.to_string())?; - - tx.commit().map_err(|e| e.to_string())?; - Ok(()) -} - -#[tauri::command] -pub(crate) fn load_board_data(app: AppHandle, board_id: String) -> Result { - let conn = open_db(&app)?; - if let Some(data) = load_board_data_value(&conn, &board_id)? { - return Ok(data); - } - if !board_id_exists(&conn, &board_id)? { - return Err("Board not found".to_string()); - } - Ok(default_board_data()) -} - -#[tauri::command] -pub(crate) fn set_collaboration_link( - app: AppHandle, - board_id: String, - link: Option, -) -> Result<(), String> { - let conn = open_db(&app)?; - let updated = conn - .execute( - "UPDATE boards SET collaboration_link = ?1, updated_at = ?2 WHERE id = ?3", - params![link, Utc::now().timestamp_millis(), board_id], - ) - .map_err(|e| e.to_string())?; - if updated == 0 { - return Err("Board not found".to_string()); - } + set_setting(&conn, ACTIVE_BOARD_SETTING_KEY, Some(&board_id))?; Ok(()) } @@ -195,7 +134,9 @@ pub(crate) fn duplicate_board( ) -> Result { let mut conn = open_db(&app)?; let original = get_board_by_id(&conn, &board_id)?; - let original_data = load_board_data_value(&conn, &board_id)?.unwrap_or_else(default_board_data); + let original_data = BoardDataPayload( + load_board_data_value(&conn, &board_id)?.unwrap_or_else(default_board_data), + ); let now = Utc::now(); let new_board = Board { @@ -207,10 +148,10 @@ pub(crate) fn duplicate_board( thumbnail: original.thumbnail.clone(), }; - let tx = conn.transaction().map_err(|e| e.to_string())?; + let tx = conn.transaction().map_err(|error| error.to_string())?; insert_board_with_data(&tx, &new_board, &original_data)?; - tx.commit().map_err(|e| e.to_string())?; + tx.commit().map_err(|error| error.to_string())?; Ok(new_board) } @@ -220,14 +161,14 @@ pub(crate) fn set_boards_index( items: Vec, ) -> Result { let mut conn = open_db(&app)?; - let tx = conn.transaction().map_err(|e| e.to_string())?; + let tx = conn.transaction().map_err(|error| error.to_string())?; tx.execute("DELETE FROM index_items", []) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; tx.execute("DELETE FROM folder_items", []) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; tx.execute("DELETE FROM folders", []) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; for (position, item) in items.iter().enumerate() { match item { @@ -236,25 +177,25 @@ pub(crate) fn set_boards_index( "INSERT INTO index_items (position, item_type, item_id) VALUES (?1, 'board', ?2)", params![position as i64, board.id], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; } BoardListItem::Folder(folder) => { tx.execute( "INSERT OR REPLACE INTO folders (id, name) VALUES (?1, ?2)", params![folder.id, folder.name], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; tx.execute( "INSERT INTO index_items (position, item_type, item_id) VALUES (?1, 'folder', ?2)", params![position as i64, folder.id], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; for (folder_pos, board) in folder.items.iter().enumerate() { tx.execute( "INSERT INTO folder_items (folder_id, board_id, position) VALUES (?1, ?2, ?3)", params![folder.id, board.id, folder_pos as i64], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; } } } @@ -262,7 +203,7 @@ pub(crate) fn set_boards_index( let mut index = BoardsIndex { items, - active_board_id: get_setting(&tx, "active_board_id")?, + active_board_id: get_setting(&tx, ACTIVE_BOARD_SETTING_KEY)?, }; if let Some(active_id) = index.active_board_id.clone() { @@ -273,120 +214,19 @@ pub(crate) fn set_boards_index( index.active_board_id = first_board_id(&index.items); } - set_setting(&tx, "active_board_id", index.active_board_id.as_deref())?; - tx.commit().map_err(|e| e.to_string())?; + set_setting( + &tx, + ACTIVE_BOARD_SETTING_KEY, + index.active_board_id.as_deref(), + )?; + tx.commit().map_err(|error| error.to_string())?; Ok(index) } -#[tauri::command] -pub(crate) fn export_boards(app: AppHandle, file_path: String) -> Result<(), String> { - let conn = open_db(&app)?; - let index = load_boards_index_from_db(&conn)?; - - let mut boards = Vec::new(); - let mut seen = HashSet::new(); - - for item in index.items.iter() { - match item { - BoardListItem::Board(board) => { - if seen.insert(board.id.clone()) { - boards.push(build_export_entry(&conn, board)?); - } - } - BoardListItem::Folder(folder) => { - for board in folder.items.iter() { - if seen.insert(board.id.clone()) { - boards.push(build_export_entry(&conn, board)?); - } - } - } - } - } - - let export_file = BoardsExportFile { - version: 1, - exported_at: Utc::now(), - boards, - }; - - let payload = serde_json::to_string_pretty(&export_file).map_err(|e| e.to_string())?; - fs::write(file_path, payload).map_err(|e| e.to_string())?; - Ok(()) -} - -#[tauri::command] -pub(crate) fn import_boards( - app: AppHandle, - file_path: String, - selected_indices: Vec, -) -> Result { - let payload = fs::read_to_string(file_path).map_err(|e| e.to_string())?; - let export_file: BoardsExportFile = - serde_json::from_str(&payload).map_err(|e| e.to_string())?; - - let conn = open_db(&app)?; - let active_before = get_setting(&conn, "active_board_id")?; - - let (existing_ids, mut used_names) = load_existing_board_ids_and_names(&conn)?; - let selected: HashSet = selected_indices.into_iter().collect(); - let mut seen_ids = existing_ids; - let mut imported = 0; - let mut skipped = 0; - - for (index, entry) in export_file.boards.iter().enumerate() { - if !selected.contains(&index) { - continue; - } - - let final_name = resolve_import_name(entry, &seen_ids, &used_names); - - let created = match create_board(app.clone(), final_name.clone()) { - Ok(board) => board, - Err(_) => { - skipped += 1; - continue; - } - }; - - if let Some(data_value) = entry.data.clone() { - if !data_value.is_null() { - let data_str = data_value.to_string(); - save_board_data(app.clone(), created.id.clone(), data_str)?; - } - } - - register_imported_identity(entry, &final_name, &mut seen_ids, &mut used_names); - imported += 1; - } - - restore_active_board(&conn, active_before)?; - - Ok(BoardsImportResult { imported, skipped }) -} - -#[tauri::command] -pub(crate) fn save_board_thumbnail( - app: AppHandle, - board_id: String, - thumbnail: Option, -) -> Result<(), String> { - let conn = open_db(&app)?; - let updated = conn - .execute( - "UPDATE boards SET thumbnail = ?1 WHERE id = ?2", - params![thumbnail, board_id], - ) - .map_err(|e| e.to_string())?; - if updated == 0 { - return Err("Board not found".to_string()); - } - Ok(()) -} - fn insert_board_with_data( tx: &rusqlite::Transaction<'_>, board: &Board, - data: &str, + data: &BoardDataPayload, ) -> Result<(), String> { tx.execute( "INSERT INTO boards (id, name, created_at, updated_at, collaboration_link, thumbnail) @@ -400,20 +240,20 @@ fn insert_board_with_data( &board.thumbnail ], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; tx.execute( "INSERT INTO board_data (board_id, data) VALUES (?1, ?2)", - params![&board.id, data], + params![&board.id, &data.0], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; let position = next_index_position(tx)?; tx.execute( "INSERT INTO index_items (position, item_type, item_id) VALUES (?1, 'board', ?2)", params![position, &board.id], ) - .map_err(|e| e.to_string())?; + .map_err(|error| error.to_string())?; Ok(()) } @@ -424,103 +264,5 @@ fn next_index_position(tx: &rusqlite::Transaction<'_>) -> Result { [], |row| row.get(0), ) - .map_err(|e| e.to_string()) -} - -fn load_existing_board_ids_and_names( - conn: &rusqlite::Connection, -) -> Result<(HashSet, HashSet), String> { - let mut stmt = conn - .prepare("SELECT id, name FROM boards") - .map_err(|e| e.to_string())?; - let mut rows = stmt.query([]).map_err(|e| e.to_string())?; - let mut ids = HashSet::new(); - let mut used_names = HashSet::new(); - - while let Some(row) = rows.next().map_err(|e| e.to_string())? { - let id: String = row.get(0).map_err(|e| e.to_string())?; - let name: String = row.get(1).map_err(|e| e.to_string())?; - - ids.insert(id); - let name_key = name.trim().to_lowercase(); - if !name_key.is_empty() { - used_names.insert(name_key); - } - } - - Ok((ids, used_names)) -} - -fn normalize_import_name(name: &str) -> String { - if name.trim().is_empty() { - "Imported board".to_string() - } else { - name.trim().to_string() - } -} - -fn make_copy_name(base: &str, used_names: &HashSet) -> String { - let mut candidate = format!("{} (Copy)", base); - let mut counter = 2; - while used_names.contains(&candidate.to_lowercase()) { - candidate = format!("{} (Copy {})", base, counter); - counter += 1; - } - candidate -} - -fn resolve_import_name( - entry: &BoardsExportEntry, - seen_ids: &HashSet, - used_names: &HashSet, -) -> String { - let base_name = normalize_import_name(&entry.name); - let has_id = !entry.id.trim().is_empty(); - let is_duplicate = has_id && seen_ids.contains(&entry.id); - if is_duplicate { - make_copy_name(&base_name, used_names) - } else { - base_name - } -} - -fn register_imported_identity( - entry: &BoardsExportEntry, - final_name: &str, - seen_ids: &mut HashSet, - used_names: &mut HashSet, -) { - let has_id = !entry.id.trim().is_empty(); - used_names.insert(final_name.to_lowercase()); - if has_id { - seen_ids.insert(entry.id.clone()); - } -} - -fn restore_active_board( - conn: &rusqlite::Connection, - active_before: Option, -) -> Result<(), String> { - if let Some(active_id) = active_before { - set_setting(conn, "active_board_id", Some(&active_id))?; - } - Ok(()) -} - -fn build_export_entry( - conn: &rusqlite::Connection, - board: &Board, -) -> Result { - let data_str = load_board_data_value(conn, &board.id)?.unwrap_or_else(default_board_data); - let data_json: JsonValue = serde_json::from_str(&data_str).unwrap_or(JsonValue::Null); - - Ok(BoardsExportEntry { - id: board.id.clone(), - name: board.name.clone(), - created_at: board.created_at, - updated_at: board.updated_at, - collaboration_link: board.collaboration_link.clone(), - thumbnail: board.thumbnail.clone(), - data: Some(data_json), - }) + .map_err(|error| error.to_string()) } diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs index c4eb221..2000ca0 100644 --- a/src-tauri/src/commands/mod.rs +++ b/src-tauri/src/commands/mod.rs @@ -1 +1,5 @@ +pub(crate) mod board_content; +pub(crate) mod board_transfer; pub(crate) mod boards; +pub(crate) mod system_tests; +pub(crate) mod ui_preferences; diff --git a/src-tauri/src/commands/system_tests.rs b/src-tauri/src/commands/system_tests.rs new file mode 100644 index 0000000..7a01d2d --- /dev/null +++ b/src-tauri/src/commands/system_tests.rs @@ -0,0 +1,46 @@ +use std::fs; +use tauri::AppHandle; + +use crate::db::get_boards_dir; + +#[tauri::command] +pub(crate) fn get_system_test_export_path(app: AppHandle) -> Result, String> { + resolve_system_test_transfer_path(&app, "TAURI_TEST_EXPORT_PATH") +} + +#[tauri::command] +pub(crate) fn get_system_test_import_path(app: AppHandle) -> Result, String> { + resolve_system_test_transfer_path(&app, "TAURI_TEST_IMPORT_PATH") +} + +fn resolve_system_test_transfer_path( + app: &AppHandle, + env_key: &str, +) -> Result, String> { + if !is_system_test_mode() { + return Ok(None); + } + + if let Some(path) = env_path_override(env_key) { + return Ok(Some(path)); + } + + let directory = get_boards_dir(app)?.join("system-tests"); + fs::create_dir_all(&directory).map_err(|error| error.to_string())?; + let path = directory.join("boards-transfer.json"); + Ok(Some(path.to_string_lossy().into_owned())) +} + +fn is_system_test_mode() -> bool { + matches!( + std::env::var("TAURI_TEST_MODE").ok().as_deref(), + Some("1" | "true" | "TRUE" | "True") + ) +} + +fn env_path_override(env_key: &str) -> Option { + std::env::var(env_key) + .ok() + .map(|value| value.trim().to_string()) + .filter(|value| !value.is_empty()) +} diff --git a/src-tauri/src/commands/ui_preferences.rs b/src-tauri/src/commands/ui_preferences.rs new file mode 100644 index 0000000..896865c --- /dev/null +++ b/src-tauri/src/commands/ui_preferences.rs @@ -0,0 +1,58 @@ +use serde::Serialize; +use tauri::AppHandle; + +use crate::db::{get_setting, open_db, set_setting}; + +const HIDE_EXPORT_ROW_SETTING_KEY: &str = "ui.hide_export_row"; +const SHOW_TIMESTAMPS_SETTING_KEY: &str = "ui.show_timestamps"; + +#[derive(Serialize)] +pub(crate) struct UiPreferences { + hide_export_row: bool, + show_timestamps: bool, +} + +#[tauri::command] +pub(crate) fn get_ui_preferences(app: AppHandle) -> Result { + let conn = open_db(&app)?; + let hide_export_row = parse_boolean_setting( + get_setting(&conn, HIDE_EXPORT_ROW_SETTING_KEY)?, + false, + HIDE_EXPORT_ROW_SETTING_KEY, + )?; + let show_timestamps = parse_boolean_setting( + get_setting(&conn, SHOW_TIMESTAMPS_SETTING_KEY)?, + true, + SHOW_TIMESTAMPS_SETTING_KEY, + )?; + + Ok(UiPreferences { + hide_export_row, + show_timestamps, + }) +} + +#[tauri::command] +pub(crate) fn set_ui_preference(app: AppHandle, key: String, value: bool) -> Result<(), String> { + let setting_key = match key.as_str() { + "hide_export_row" => HIDE_EXPORT_ROW_SETTING_KEY, + "show_timestamps" => SHOW_TIMESTAMPS_SETTING_KEY, + _ => return Err("Invalid UI preference key".to_string()), + }; + + let conn = open_db(&app)?; + let setting_value = if value { "1" } else { "0" }; + set_setting(&conn, setting_key, Some(setting_value)) +} + +fn parse_boolean_setting(value: Option, default: bool, key: &str) -> Result { + let Some(raw) = value else { + return Ok(default); + }; + + match raw.trim().to_ascii_lowercase().as_str() { + "1" | "true" => Ok(true), + "0" | "false" => Ok(false), + _ => Err(format!("Invalid boolean setting value for key '{key}'")), + } +} diff --git a/src-tauri/src/db.rs b/src-tauri/src/db.rs index fd70062..5d69035 100644 --- a/src-tauri/src/db.rs +++ b/src-tauri/src/db.rs @@ -9,11 +9,51 @@ use crate::models::{Board, BoardFolder, BoardListItem, BoardsIndex}; pub(crate) fn get_boards_dir(app: &AppHandle) -> Result { let app_data = app.path().app_data_dir().map_err(|e| e.to_string())?; - let boards_dir = app_data.join("boards"); + let mut boards_dir = app_data.join("boards"); + + if is_system_test_mode() { + boards_dir = + system_test_data_root().unwrap_or_else(|| app_data.join("boards-system-tests")); + if let Some(run_id) = system_test_run_id() { + boards_dir = boards_dir.join(run_id); + } + } + fs::create_dir_all(&boards_dir).map_err(|e| e.to_string())?; Ok(boards_dir) } +fn is_system_test_mode() -> bool { + matches!( + std::env::var("TAURI_TEST_MODE").ok().as_deref(), + Some("1" | "true" | "TRUE" | "True") + ) +} + +fn system_test_run_id() -> Option { + std::env::var("TAURI_TEST_RUN_ID") + .ok() + .map(|value| value.trim().to_string()) + .filter(|value| !value.is_empty()) + .map(|value| value.chars().map(normalize_run_id_char).collect::()) +} + +fn normalize_run_id_char(character: char) -> char { + if character.is_ascii_alphanumeric() || matches!(character, '-' | '_') { + character + } else { + '_' + } +} + +fn system_test_data_root() -> Option { + std::env::var("TAURI_TEST_DATA_ROOT") + .ok() + .map(|value| value.trim().to_string()) + .filter(|value| !value.is_empty()) + .map(PathBuf::from) +} + pub(crate) fn default_board_data() -> String { serde_json::json!({ "excalidraw": null, diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index d0d821a..bb57a83 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -2,11 +2,16 @@ mod commands; mod db; mod models; +use crate::commands::board_content::{ + load_board_data, save_board_data, save_board_thumbnail, set_collaboration_link, +}; +use crate::commands::board_transfer::{export_boards, import_boards}; use crate::commands::boards::{ - create_board, delete_board, duplicate_board, export_boards, get_boards, import_boards, - load_board_data, rename_board, save_board_data, save_board_thumbnail, set_active_board, - set_boards_index, set_collaboration_link, + create_board, delete_board, duplicate_board, get_boards, rename_board, set_active_board, + set_boards_index, }; +use crate::commands::system_tests::{get_system_test_export_path, get_system_test_import_path}; +use crate::commands::ui_preferences::{get_ui_preferences, set_ui_preference}; use tauri::{Emitter, Listener, Manager}; #[cfg_attr(mobile, tauri::mobile_entry_point)] @@ -41,6 +46,7 @@ pub fn run() { }) .invoke_handler(tauri::generate_handler![ get_boards, + get_ui_preferences, create_board, rename_board, delete_board, @@ -52,7 +58,10 @@ pub fn run() { set_boards_index, export_boards, import_boards, - save_board_thumbnail + save_board_thumbnail, + set_ui_preference, + get_system_test_export_path, + get_system_test_import_path ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src/components/BoardList.tsx b/src/components/BoardList.tsx index 2d1d5a5..387b5f2 100644 --- a/src/components/BoardList.tsx +++ b/src/components/BoardList.tsx @@ -1,5 +1,6 @@ import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; +import { invoke } from '@tauri-apps/api/core'; import { getVersion } from '@tauri-apps/api/app'; import { confirm, open as openDialog } from '@tauri-apps/plugin-dialog'; import { readTextFile } from '@tauri-apps/plugin-fs'; @@ -100,6 +101,11 @@ interface ImportBoardEntry extends BoardsExportEntry { index: number; } +interface UiPreferences { + hide_export_row: boolean; + show_timestamps: boolean; +} + // ============================================================================= // Utility Functions // ============================================================================= @@ -230,6 +236,7 @@ function DraggableBoardItem({
!isEditing && onSelect()} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} @@ -272,6 +279,7 @@ function DraggableBoardItem({
- - @@ -1181,7 +1245,12 @@ export function BoardList({

Boards

- @@ -1360,7 +1435,11 @@ export function BoardList({ {settingsOpen ? createPortal(
-
event.stopPropagation()}> +
event.stopPropagation()} + >

Settings

Boards
@@ -1390,6 +1469,7 @@ export function BoardList({
-
diff --git a/src/hooks/useAppController.ts b/src/hooks/useAppController.ts index 8f3868c..faf206b 100644 --- a/src/hooks/useAppController.ts +++ b/src/hooks/useAppController.ts @@ -185,10 +185,13 @@ const useBoardsTransferActions = ( setSettingsError(null); try { - const filePath = await save({ - defaultPath: buildBoardsExportName(), - filters: [{ name: 'Boards export', extensions: ['json'] }], - }); + const testExportPath = await invoke('get_system_test_export_path'); + const filePath = testExportPath + ? testExportPath + : await save({ + defaultPath: buildBoardsExportName(), + filters: [{ name: 'Boards export', extensions: ['json'] }], + }); if (!filePath) { return;